1

I have a form which will return a csv file whenever user click a button. In order to return file I have created a StringBuilder named sb and concatenate all responses to sb(a point to mention is that my strings are Arabic characters so I need to encode them as UTF8 chars). Then I try to return my csv file like this:

DataTable dt = auc.GetTradesByDate().Tables[0];
/**************************************************************/
StringBuilder sb = new StringBuilder();
sb.Append("date, symbol, symbolName, buyerId,buyerName\n");
foreach (DataRow dr in dt.Rows)
{
    sb.Append(dr["date"]);
    sb.Append("," + dr["symbol"]);
    sb.Append("," + dr["symbolName"]);
    sb.Append("," + dr["buyerId"]);
    sb.Append("," + dr["buyerName"]);

    sb.Append("\n");
}

Response.Clear();
Response.ClearHeaders();
Response.ContentType = "text/csv";
Response.Charset = "";
Response.ContentEncoding = Encoding.UTF8;
Response.Buffer = true;

Response.AddHeader("content-disposition", string.Format("attachment;filename=trades_{0:yyyy-MM-dd}.csv", DateTime.Now));


byte[] BOM = new byte[] { 0xef, 0xbb, 0xbf };
Response.BinaryWrite(BOM);
Response.BinaryWrite(Encoding.UTF8.GetBytes(sb.ToString()));
Response.Flush();
Response.End();

The sb has filled correctly but the output file is still empty. I will appreciate your helps. can anybody help me with that?

I have used all the methods proposed(1 and 2) but it's still empty. and The point is that when I write string to XML file everything works fine but when it comes to CSV it doesn't work. That's really making me crazy. I don't know what's the problem. am I forgetting to write anything??

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
Nahid Bandi
  • 428
  • 1
  • 4
  • 23
  • About half of your code is irrelevant, one way or the other - is the problem when it goes into the `if` body, or the `else` body? Presumably the `if` body, which means we don't need to see the rest. Always try to reduce the code to a [mcve]. – Jon Skeet Nov 06 '17 at 07:14
  • @JonSkeet sorry for that. I have edit the code – Nahid Bandi Nov 06 '17 at 07:18
  • Right, that's definitely better. So, what's happening on the client side? Are you looking at this through a browser, or downloading it programmatically? Have you looked at what's coming over the wire with Wireshark or Fiddler? Any reason you're setting `Charset` to an empty string instead of "utf-8"? – Jon Skeet Nov 06 '17 at 07:28
  • The client will download the file from a browser. No,I have not checked the connection.The file downloaded successfully but it's just blank. you thinks the code is OK and something is going wrong on network layer? if it's that why it doesn't have any problem with XML files? – Nahid Bandi Nov 06 '17 at 07:34
  • I doubt that anything is wrong with the network, but you need to know what's actually happening in the response. – Jon Skeet Nov 06 '17 at 07:39
  • @JonSkeet thanks for your help. I solved it. – Nahid Bandi Nov 08 '17 at 04:45

2 Answers2

0

try commenting below two lines if that helps

Response.Charset = "";
Response.ContentEncoding = Encoding.UTF8;
ChiragMM
  • 347
  • 4
  • 12
-1

I have tried a lot to solve this problem. As I have spent a lot of time on that to find the problem I will post the answer maybe it can save time for others. The problem was the way I build the sb. I have to build it for CSV file with adding format. The following worked for me:

DataTable dt = auc.GetTradesByDate().Tables[0];
/**************************************************************/
StringBuilder sb = new StringBuilder();

sb.AppendFormat("{0},{1},{2},{3},{4}"
                , "date", "symbol", "symbolName", "buyerId","buyerName\n");
foreach (DataRow dr in dt.Rows)
{
    sb.AppendFormat("{0},", dr["date"]);
    sb.AppendFormat("{0},", dr["symbol"]);
    sb.AppendFormat("{0},", dr["symbolName"]);
    sb.AppendFormat("{0},", dr["buyerId"]);
    sb.AppendFormat("{0}", dr["buyerName"]);
    sb.AppendFormat("\n");
}

string CsvHeader = "";
Response.Clear();
Response.ContentType = "text/csv";
Response.Buffer = true;
Response.AddHeader("content-disposition", string.Format("attachment;filename=trades_{0:yyyy-MM-dd}.csv", DateTime.Now));
Response.Write(CsvHeader + sb.ToString());
Response.End();
Nahid Bandi
  • 428
  • 1
  • 4
  • 23
  • That shouldn't make any difference - it certainly shouldn't make the difference between getting content and not getting anything. (And please don't format dates that way...) I think you need to dig deeper to see exactly where the problem is. (You may well want to still use AppendFormat, but do it in a single call per row - but there's really no point in using AppendFormat for the headings like that.) – Jon Skeet Nov 08 '17 at 07:33
  • @JonSkeet I have edited the date. I really don't know what's the problem. everything looks fine and just after adding format it worked. can you tell me more? and if my answer is not good can you provide me with a better one? – Nahid Bandi Nov 08 '17 at 09:55
  • Basically you need to do more diagnostic work yourself. Firstly, make sure you can still reproduce the problem - if you go back to the old builder code, can you reproduce the issue? If so, then you must be generating different strings - so you should be able to provide a minimal example which *just* produces those strings, without using HttpResponse at all. You could write them to separate files and diff them, for example. – Jon Skeet Nov 08 '17 at 09:57