Reputation: 1113
Who know how to do this? I have a loop and in that loop a List is build up. I want each List to be saved as a different file with a different filename (duh). I am using HttpContext.Current.Response for this. A single file works fine, however, I cannot loop it. The error I receive upon the second iteration is "Server cannot clear headers after HTTP headers have been sent." My code is somewhat like below. What matters of course is the part commented by // response to user. Any comments highly appreciated!
Cheerz, Ronald
foreach (GridViewRow dr in GridView1.Rows)
{
// find the check box in the row
System.Web.UI.WebControls.CheckBox cb = (System.Web.UI.WebControls.CheckBox)dr.FindControl("chkbx_selected");
// see if it's checked
if (cb != null && cb.Checked)
{
// get the cell
DataControlFieldCell Cell = GetCellByName(dr, "GUID");
string guid = new Guid(Cell.Text);
// get the record filtered on the GUID
var result_json = call_WEBAPI(guid);
// result_json contains serialized List<string>
List<string> result = JsonConvert.DeserializeObject<List<string>>(result_json);
// response to user
string filename = result[0] + ".txt";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.AppendHeader("content-disposition", string.Format("attachment; filename={0}", filename));
HttpContext.Current.Response.ContentType = "application/octet-stream";
foreach (string line in result)
{
HttpContext.Current.Response.Write(line + Environment.NewLine);
}
HttpContext.Current.Response.Flush();
}
}
HttpContext.Current.Response.End();
Update: I now create a zip archive in memory, create an entry and fill this with a writer. But how do I create the second entry in the .zip?? The code below does not work, error is "Entries in create mode may only be written to once, and only one entry may be held open at a time."
using (MemoryStream zipToOpen = new MemoryStream())
{
using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create, true))
{
ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
{
writer.WriteLine("Information about this package.");
writer.WriteLine("========================");
}
List<string> result = new List<string>();
result.Add("line1");
result.Add("line2");
ZipArchiveEntry readmeEntry2 = archive.CreateEntry("Readme2.txt");
using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
{
writer.Write(result);
}
}
using (var fileStream = new FileStream(@"C:\test.zip", FileMode.Create))
{
zipToOpen.Seek(0, SeekOrigin.Begin);
zipToOpen.CopyTo(fileStream);
}
}
Upvotes: 1
Views: 14202
Reputation: 4539
while zip file opening it is anoying which is always open.! But if you try to close there is just one manner dispose but this time it is anoying disposed object. That is the solution Dispose and reopen all files right below one opening example
string MappingpathZip = Path.Combine(HttpRuntime.AppDomainAppPath, @"XmlDocs\Invs\" + firmName + fileName + ".zip");
ZipArchive zip = ZipFile.Open(MappingpathZip, ZipArchiveMode.Create);
ZipArchiveEntry zae = zip.CreateEntryFromFile(MappingpathSignedXML, Path.GetFileName(MappingpathZip), CompressionLevel.Optimal);
var stream = zae.Open();
byte[] bytes;
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
bytes = ms.ToArray();
}
Upvotes: 0
Reputation: 382
You can zip all files on the server and then send one .zip file. As Google does :) It'll solve you problem
Upvotes: 0
Reputation: 218808
A single response can contain only a single "file". (Technically HTTP has no concept of "files", which is kind of why this is the case. HTTP has "headers" and "content". As the error tells you, once the headers are sent you can't change them. Because they've already been sent to the client.)
You're either going to have to return the files from multiple requests/responses or compress them into a single file and return that.
(Also, why use "application/octet-stream"
for a text file? Use that for the zipped file perhaps, but a text file should probably be "text/plain"
or something similar.)
Upvotes: 5