简体   繁体   English

强制下载文件对话框不起作用 - ASP.NET C#

[英]Force the Download File dialog Not Working - ASP.NET C#

I am trying to implement force download file dialog in my ASP.NET C# application.我正在尝试在我的 ASP.NET C# 应用程序中实现强制下载文件对话框。 The files I'd like to force download are media files not locally available available on the web server but are being served from a different location.我想强制下载的文件是 web 服务器上本地不可用但从不同位置提供的媒体文件。

I am getting an error 'http://remote-site-to-webserver/somefile.asf' is not a valid virtual path.我收到错误“http://remote-site-to-webserver/somefile.asf”不是有效的虚拟路径。

I have searched the web for solutions but all examples point to relative path on the server using Server.MapPath我已经在 web 中搜索了解决方案,但所有示例都指向使用 Server.MapPath 的服务器上的相对路径

In the example below I created a webhandler.ashx page and send the download request to this page.在下面的示例中,我创建了一个 webhandler.ashx 页面并将下载请求发送到该页面。

<%@ WebHandler Language="C#" Class="DownloadHandler" %>

using System;
using System.Web;

public class DownloadHandler : IHttpHandler {
public void ProcessRequest(HttpContext context) {
var fileName = "http://remote-site-to-webserver/somefile.asf";
var r = context.Response;
r.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
r.WriteFile(context.Server.MapPath(fileName));
}
public bool IsReusable { get { return false; } }
}

The Content-Disposition header looks wrong to me. Content-Disposition header 在我看来是错误的。 I think it should be:我认为应该是:

r.AddHeader("Content-Disposition", 
    "attachment; filename=DefaultNewFilename.ext");

the filename is the default name given to the downloaded file... Or in otherwords it's what is shown in the browsers save dialog.文件名是下载文件的默认名称......或者换句话说,它是浏览器保存对话框中显示的内容。

You may also want:您可能还想要:

r.AddHeader("Content-Type", "application/octetstream");

I'm not sure that's required.... But I've always included it for video files and so on.我不确定这是必需的......但我一直将它包含在视频文件等中。

Server.MapPath() 

is not used for remote http files.不用于远程 http 文件。 it is just a tool for converting virtual addresses to physical addresses, ie you can retrieve "C:\inetpub\wwwroot\MyWebSite\Files\blah.txt" by giving "~/Files/blah.txt" to Server.MapPath method.它只是一个将虚拟地址转换为物理地址的工具,即您可以通过将“~/Files/blah.txt”赋予Server.MapPath 方法来检索“C:\inetpub\wwwroot\MyWebSite\Files\blah.txt”。

if you are interested in downloading a file from another web server you will have to use HttpWebRequest class.如果您有兴趣从另一个 web 服务器下载文件,则必须使用 HttpWebRequest class。

this is a sample code:这是一个示例代码:

                HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create("http://remote-site-to-webserver/somefile.asf");
                httpRequest.Credentials = CredentialCache.DefaultCredentials; //or a NetworkCredential if needed

                HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();

                Stream dataStream = httpResponse.GetResponseStream();

now you can output the dataStream into your response.现在您可以将数据流 output 放入您的响应中。

In order for the download to start from a different server, you need to send a redirect answer to the client ( Response.Redirect(mediaURL) ).为了从不同的服务器开始下载,您需要向客户端发送重定向应答( Response.Redirect(mediaURL) )。

As a consequence, you cannot force the download dialog from your web server because the browser will send a separate request to the other server.因此,您无法从 web 服务器强制下载对话框,因为浏览器会向其他服务器发送单独的请求。 This must be solved on the server where the media is served from.这必须在提供媒体的服务器上解决。

The only alternative is that you act as an intermediate, ie you download the media file to your server and send it as the response to the client.唯一的选择是您充当中间人,即将媒体文件下载到服务器并将其作为响应发送给客户端。 This shouldn't be too difficult if it's a small file that easily fits into memory.如果它是一个很容易放入 memory 的小文件,这应该不会太难。 However, if it's a large file it might involve some tricky coding so you can receive and send it piecewise.但是,如果它是一个大文件,它可能会涉及一些棘手的编码,因此您可以分段接收和发送它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM