另存为-适用于任何文件类型

When developing different types of ASP.NET applications I often face a requirement to let user download different types of files. They vary from logs in *.txt files or manuals/instructions in *.pdf files to charts in *.jpg files or reports in *.xls files. In most cases these files are generated at run-time or stored in a folder not directly accessible to user through URL.

在开发不同类型的ASP.NET应用程序时,我经常面临让用户下载不同类型文件的要求。 它们从* .txt文件中的日志或* .pdf文件中的手册/说明到* .jpg文件中的图表或* .xls文件中的报告不等。 在大多数情况下,这些文件是在运行时生成的,或存储在用户无法通过URL直接访问的文件夹中。

As you know clicking on a link referencing e.g. *.txt file opens this file in browser window. Sometimes this behavior is not very comfortable for user when he/she desires to save file for later use.

如您所知,单击引用的链接,例如* .txt文件会在浏览器窗口中打开该文件。 有时,当用户希望保存文件以备后用时,此行为对于用户来说不是很舒服。

This article will show you how to set up your application and links in your pages so user would be provided with Save As& dialog when clicking on such link.

本文将向您展示如何在页面中设置应用程序和链接,以便在单击此类链接时向用户提供“另存为&”对话框。

Note: I use Visual Studio 2008 and C# language in this article and in a demo application available to download at the end of the article.

注意:我在本文和演示软件中使用Visual Studio 2008和C#语言,该应用程序可在本文结尾处下载。

1.为您的文件创建文件夹 (1. Create folder for you files)

Create a folder where you will put files user could download. If files should not be accessible directly by URL to user App_Data folder (or subfolder in App_Data folder) would be a good choice because content from App_Data folder is not served to user.

创建一个文件夹,您可以在其中放置用户可以下载的文件。 如果不应通过URL直接访问文件到用户App_Data文件夹(或App_Data文件夹中的子文件夹),则将是一个不错的选择,因为不会将App_Data文件夹中的内容提供给用户。

To create a folder:

创建文件夹:

  1. In Visual Studio right-click on project name in solution explorer

1.在Visual Studio中,在解决方案资源管理器中右键单击项目名称

  2. Choose New Folder

2.选择新文件夹

  3. Type a desired name of a folder. (I will use Files in this article.)

3.键入所需的文件夹名称。 (我将在本文中使用“文件”。)

Create new folder

By default App_Data folder is automatically created when you create a new Web Site. If not (or you deleted one):

默认情况下,创建新网站时会自动创建App_Data文件夹。 如果不是(或您删除了一个):

  1. In Visual Studio right-click on project name in solution explorer

1.在Visual Studio中,在解决方案资源管理器中右键单击项目名称

  2. Choose Add ASP.NET Folder > App_Data.

2.选择添加ASP.NET文件夹> App_Data。

Create App_Data folder

2.将文件放在创建的文件夹中 (2. Put files in created folder)

Put any files you want to server to user in a newly created folder.

将您要服务器处理的所有文件放在新创建的文件夹中。

3.创建一个HTTP处理程序来提供文件。 (3. Create a HTTP handler to serve files.)

From MSDN:

从MSDN:

An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. You can create your own HTTP handlers that render custom output to the browser.

ASP.NET HTTP处理程序是响应对ASP.NET Web应用程序的请求而运行的过程(通常称为“端点”)。 最常见的处理程序是处理.aspx文件的ASP.NET页处理程序。 当用户请求.aspx文件时,页面将通过页面处理程序处理请求。 您可以创建自己的HTTP处理程序,以将自定义输出呈现给浏览器。



To create HTTP handler:

要创建HTTP处理程序:

  1. In Visual Studio right-click on project name in solution explorer

1.在Visual Studio中,在解决方案资源管理器中右键单击项目名称

  2. Choose Add New Item&

2.选择添加新项并

  3. In open dialog choose Generic Handler from templates list

3.在打开的对话框中,从模板列表中选择通用处理程序。

  4. Type desired handler's name in Name textbox (I will use "FileDownload.ashx" in this article)

4.在“名称”文本框中键入所需处理程序的名称(我将在本文中使用“ FileDownload.ashx”)

  5. Click Add button

5.单击添加按钮

Create HTTP handler

Note: handler name will be used in links on pages so make sure you give your handler a meaningful name

注意:处理程序名称将在页面上的链接中使用,因此请确保为处理程序命名

4.使您的处理程序为您和您的应用程序用户服务 (4. Make your handler work for you and users of your application)

To do this you will have to implement two members of IHttpHandler interface. Let's start from easy one.

为此,您将必须实现IHttpHandler接口的两个成员。 让我们从简单的一个开始。

::: IsReusable property :::

::: IsReusable属性:::

From MSDN:

从MSDN:

The IsReusable property specifies whether the IHttpHandlerFactory object (the object that actually calls the appropriate handler) can put the handler in a pool and reuse it to increase performance. If the handler cannot be pooled, the factory must create a new instance of the handler every time that the handler is needed.

IsReusable属性指定IHttpHandlerFactory对象(实际上调用适当处理程序的对象)是否可以将处理程序放入池中并重用它以提高性能。 如果无法合并处理程序,则工厂每次需要处理程序时都必须创建一个新的处理程序实例。



public bool IsReusable
{
	get
	{
		return false;
	}
}

By default when you create a HTTP handler this property returns false. As handler we are creating is not resource intensive we could leave it as is. I've read forums where people complain that returning true has a negative impact on handler performance. I've tried returning true in my handlers but did not notice any effect so I always do return false;.

默认情况下,创建HTTP处理程序时,此属性返回false。 由于我们正在创建的处理程序并不占用资源,因此我们可以保持原样。 我读过一些论坛,人们抱怨说返回true对处理程序性能有负面影响。 我尝试在处理程序中返回true,但是没有注意到任何影响,因此我总是返回false;。

::: ProcessRequest method :::

::: ProcessRequest方法:::

From MSDN:

从MSDN:

The ProcessRequest method is responsible for processing individual HTTP requests. In this method, you write the code that produces the output for the handler.

ProcessRequest方法负责处理单个HTTP请求。 在此方法中,您编写了生成处理程序输出的代码。

HTTP handlers have access to the application context. This includes the requesting user's identity (if known), application state, and session information. When an HTTP handler is requested, ASP.NET calls the ProcessRequest method of the appropriate handler. The code that you write in the handler's ProcessRequest method creates a response, which is sent back to the requesting browser.

HTTP处理程序可以访问应用程序上下文。 这包括发出请求的用户的身份(如果知道),应用程序状态和会话信息。 当请求HTTP处理程序时,ASP.NET调用适当处理程序的ProcessRequest方法。 您在处理程序的ProcessRequest方法中编写的代码将创建一个响应,该响应将被发送回请求浏览器。



As everything said is quite clear let's proceed further. HTTP handlers (I mean *.ashx files) are requested by browsers and support query strings as well. We are going to use query string to know witch file to serve.

一切都说得很清楚,让我们继续。 浏览器请求HTTP处理程序(我的意思是* .ashx文件),并且也支持查询字符串。 我们将使用查询字符串来了解服务的文件。

//...
// Add necessary namespace to the top
// as we are working with file system
using System.IO;
public void ProcessRequest(HttpContext context)
{
	// You should validate query string here to make sure
	// it contains necessary information

	if (context.Request.QueryString.Count <= 0)
	{
		// could redirect to error page here
	}

	string file = context.Request.QueryString["FileName"];

	if (string.IsNullOrEmpty(file))
	{
		// could redirect to error page here
	}


	// Combine file name with folder name
	string filePath = context.Server.MapPath(string.Concat("~/Files/" + file));

	// Check if requested file exists
	if (!File.Exists(filePath))
	{
		// could redirect to error page here
	}

	// Always nice to know you're working with clear response object
	// just in case
	context.Response.Clear();

	// This is the heart of your functionality. Browser read response's content type
	// and decide whether they should show Save As.. dialog or show response in
	// in it's window. Special value application/save forces browser to show Save As... dialog
	context.Response.ContentType = "application/save";

	// Browser use this to detect name of a file to be downloaded
	context.Response.AddHeader("Content-Disposition", "attachment; filename=" + file);

	// Add file itself to response
	context.Response.WriteFile(filePath);

	// Flush our rendered response to browser
	context.Response.Flush();

	// We are done
	context.Response.End();

}

5.链接到文件 (5. Links to files)

As we have finished setting up our handler let's proceed to links.

完成设置处理程序后,我们继续进行链接。

Suppose we have a file named template.txt in our Files folder and we want to provide user with link so he/she could download that file by clicking on this link.

假设我们在“文件”文件夹中有一个名为template.txt的文件,我们想为用户提供链接,以便他/她可以通过单击此链接来下载该文件。

You can use either ASP.NET Hyperlink control or standard HTML <a> element to create link. The only difference is that ASP.NET Hyperlink control accepts application relative URLs (e.g."~/Files/template.txt") and standard HTML <a> elements do not.

您可以使用ASP.NET Hyperlink控件或标准HTML <a>元素来创建链接。 唯一的区别是ASP.NET Hyperlink控件接受应用程序相对URL(例如“〜/ Files / template.txt” “)和标准HTML <a>元素没有。

<asp:HyperLink runat="server" NavigateUrl="~/FileDownload.ashx?FileName=template.txt" Text="Download template" />
<br />
<a href="FileDownload.ashx?FileName=template.txt">Download template</a>

Clicking on link like this user will be provided with "Save As&" dialog to save file instead of showing in browser window.

单击该用户这样的链接将显示“另存为&”对话框,以保存文件,而不是在浏览器窗口中显示。

This is it. Our goal achieved.

就是这个。 我们的目标得以实现。

This is just a simple sample. You can develop a more advances handlers where you pass some ID of database record to handler and it outputs some report in *.pdf file or chart in *.jpg file or& depends on requirements and needs.

这只是一个简单的示例。 您可以开发一个更高级的处理程序,在该处理程序中,您将一些数据库记录的ID传递给处理程序,并在* .pdf文件中输出一些报告,或者在* .jpg文件中输出图表,或者根据需要和需求而输出。

In a demo application I attached to article you will find more extensive scenarios of FileDownload HTTP handler. EE does not allow uploading most of ASP.NET files (even if they are compressed in zip file) so I added a .txt extension to every file.

在本文所附的演示应用程序中,您将找到FileDownload HTTP处理程序的更广泛的场景。 EE不允许上传大多数ASP.NET文件(即使它们已压缩为zip文件),因此我向每个文件添加了.txt扩展名。

Download here:Demo.zip

在这里下载: Demo.zip

This is my first article ever so please forgive me if did not like something about style of writing.

这是我的第一篇文章,所以如果不喜欢写作风格,请原谅。

Your comments and criticism are very welcome.

非常欢迎您的评论和批评。

Resources:

资源:

  HTTP Handlers and HTTP Modules Overview

HTTP处理程序和HTTP模块概述

http://msdn.microsoft.com/en-us/library/bb398986.aspx http://msdn.microsoft.com/en-us/library/bb398986.aspx

  Walkthrough: Creating a Synchronous HTTP Handler

演练:创建同步HTTP处理程序

http://msdn.microsoft.com/en-us/library/ms228090.aspx http://msdn.microsoft.com/en-us/library/ms228090.aspx

  IHttpHandler Interface

IHttpHandler接口

http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.aspx http://msdn.microsoft.com/zh-CN/library/system.web.ihttphandler.aspx

翻译自: https://www.experts-exchange.com/articles/282/Save-as-for-any-file-type.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值