Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

c# - Return multiple files to download from asp.net

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:	est.zip", FileMode.Create))
            {
                zipToOpen.Seek(0, SeekOrigin.Begin);
                zipToOpen.CopyTo(fileStream);
            }
        }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...