我正在我的Web应用程序中动态创建一个文件。我想将此文件发送给用户,就像许多网站在下载文件时一样。
我首先在Download/Stream file from URL - asp.net尝试了这种方法。但这不起作用,因为我在一个从ASPX网页中删除的一个类;我的结果是文件覆盖了自己,与我交替,我无法创建正确的请求/响应对象。
然后我尝试了这种方法:
try
{
WebClient myClient = new WebClient();
string basefile = Path.GetFileName( file_name );
myClient.DownloadFile( file_name, basefile );
}
catch (WebException we)
{
string message = we.Message;
}
这引发了一个例外:拒绝访问路径'C:\ Program Files(x86)\ IIS Express \ file-being-sent.ext'。
那么,我该如何传输文件?
ETA我以前的尝试:
//Create a WebRequest to get the file
HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create( url ); //Send request to this URL
//Create a response for this request
HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();
//if (fileReq.ContentLength > 0)
// fileResp.ContentLength = fileReq.ContentLength;
//Get the Stream returned from the response
//stream = new Stream();
writer = new StreamWriter( file_name );
//stream = writer.BaseStream.Length
// prepare the response to the client. resp is the client Response
var resp = HttpContext.Current.Response;
//Indicate the type of data being sent
//resp.ContentType = "application/octet-stream";
resp.ContentType = "application/zip";
//Name the file
resp.AddHeader( "Content-Disposition", "attachment; filename=\"" + Path.GetFileName( file_name ) + "\"" );
resp.AddHeader( "Content-Length", writer.BaseStream.Length.ToString() );
// Verify that the client is connected.
if (resp.IsClientConnected)
{
resp.Write( writer );
resp.Flush();
}
我还没想出要传递给HttpCreateRequest()
的电话的内容。
ETA2:这是我目前正在使用的内容。各种SOF帖子说这应该提示用户打开或保存对话框,但它仍然不会对我这样做。
StreamReader reader = new StreamReader( file_name );
var resp = HttpContext.Current.Response;
//Indicate the type of data being sent
resp.ContentType = "application/zip";
resp.AppendHeader( "Content-Disposition", "attachment; filename=\"" + Path.GetFileName( file_name ) + "\"" );
resp.AppendHeader( "Content-Length", reader.BaseStream.Length.ToString() );
// Verify that the client is connected.
if (resp.IsClientConnected)
{
resp.Clear();
resp.TransmitFile( file_name ); //does not buffer into memory, therefore scales better for large files and heavy usage
resp.Flush();
}
ETA3:IIS跟踪日志报告异常,System.Web.HttpException: Server cannot set content type after HTTP headers have been sent.
这对我没有意义,因为我在添加标题之前设置了内容类型。
堆栈跟踪是:
[HttpException (0x80004005): Server cannot set content type after HTTP headers have been sent.]
System.Web.HttpResponse.set_ContentType(String value) +9681570
System.Web.HttpResponseInternalWrapper.set_ContentType(String value) +41
System.Web.UI.PageRequestManager.RenderPageCallback(HtmlTextWriter writer, Control pageControl) +139
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +268
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Page.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +57
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1386
ETA4:我将流式传输到ASPX页面的代码隐藏文件,该文件可以直接访问Response
对象。我仍然得到同样的例外。我无法解释为什么普遍接受的方法向我抱怨已经发送了响应,或者为什么我的代码不会提示用户下载文件。
答案 0 :(得分:0)
在resp.Clear()
using (StreamReader reader = new StreamReader( file_name ))
{
var resp = HttpContext.Current.Response;
resp.BufferOutput = true; //this is from the SO article
//resp.Buffer = True; //this is from msdn comments
// Verify that the client is connected.
if (resp.IsClientConnected)
{
resp.Clear();
resp.ClearHeaders();
//Indicate the type of data being sent
resp.ContentType = "application/zip";
resp.AppendHeader( "Content-Disposition", "attachment; filename=\"" + Path.GetFileName( file_name ) + "\"" );
resp.AppendHeader( "Content-Length", reader.BaseStream.Length.ToString() );
resp.TransmitFile( file_name ); //does not buffer into memory, therefore scales better for large files and heavy usage
resp.End();
}
}
答案 1 :(得分:0)
在ASPX <%@ Page...%>
指令中设置ContentType属性:
<%@ Page ContentType="application/zip" %>