httphandlers_使用HttpHandlers有条件地静态或动态地服务文件

httphandlers

httphandlers

I have some static files - RSS XML in fact - that have been served by IIS as static files for a while. I consider them permalinks, and I don't want to change that for now, but I wanted to do some testing with FeedBurner (similar do what I did before with FeedBurner in DasBlog) letting them serve the RSS for a while, gathering statistics. If it went well, I'd go with FeedBurner full time for those files - but not all.

我有一些静态文件-实际上是RSS XML-由IIS用作静态文件已有一段时间了。 我认为它们是永久链接,暂时不希望更改,但是我想对FeedBurner进行一些测试(与我之前在DasBlog中对FeedBurner所做的类似),让它们暂时使用RSS,收集统计信息。 如果一切顺利,我会全天候与FeedBurner一起处理那些文件-但不是全部。

So, given a directory with: foo.xml, bar.xml, bat.xml and others all served statically by IIS, I wanted a quick and dirty way to maintain the permalinks while handling a few of the files dynamically, and a few as redirects to FeedBurner.

因此,给定一个目录: foo.xml,bar.xml,bat.xml和其他所有目录均由IIS静态提供,我想要一种快速而又肮脏的方法来维护永久链接,同时动态处理一些文件,另外一些则重定向到FeedBurner。

There's a number of ways to solved this depending on your version of IIS and ASP.NET; here's an easy way, and the way I'm doing it now.

有多种方法可以解决此问题,具体取决于您的IIS和ASP.NET版本。 这是一种简单的方法,也是我现在正在做的方法。

By default IIS will serve XML files as static files with the text/xml mime type and ASP.NET will never hear about it. As XML files aren't handled by ASP.NET, first I need to configure IIS to pass all requests for XML files for this VDIR to ASP.NET. Do this from the Configuration button under Home Directory in the Properties pages of the app/vdir. I've pointed ".xml" to aspnet_isapi.dll as seen in the figure at right.

默认情况下,IIS将XML文件作为具有text / xml mime类型的静态文件提供,而ASP.NET将永远不会听到它。 由于XML文件不是由ASP.NET处理的,因此首先我需要配置IIS,以将对此VDIR的所有XML文件请求传递给ASP.NET。 从app / vdir的“属性”页面中主目录下的“配置”按钮执行此操作。 我已将“ .xml”指向aspnet_isapi.dll,如右图所示。

Note that you need to be explicit if you want IIS to check if the file exists. For example, if foo.xml is a real static file on disk, but bar.xml is going to be dynamically created, don't select "Verify that file exists." Setting this checkbox wrong is the #1 developer-error that you'll hit when creating HttpHandlers to handle custom extensions.

请注意,如果要让IIS检查文件是否存在,则需要明确。 例如,如果foo.xml是磁盘上的实际静态文件,但是bar.xml将动态创建,则不要选择“验证该文件是否存在”。 将此复选框设置为错误是创建HttpHandlers处理自定义扩展时遇到的#1开发人员错误

Next I'll add a handler in web.config for *.xml (or just foo.xml, etc, if I want to be more restrictive).

接下来,我将在web.config中为* .xml添加一个处理程序(或者,如果我想更严格一些,只需添加foo.xml等)。

   1:  <httpHandlers>
   2:  <add verb="GET" 
   3:  path="*.xml"
   4:  type="Foo.Redirector,FooAssembly"
   5:  />
   6:  </httpHandlers>

Now I'll create a VERY simple HttpHandler that will fire for all .xml files (or just the ones you want, if you only associated a few files in your web.config.

现在,我将创建一个非常简单的HttpHandler,它将对所有.xml文件(或仅在您要在web.config中关联几个文件的情况下)触发。

This is your chance to:

这是您的机会:

  • Redirect elsewhere

    重定向到其他地方
  • Dynamically generate the file they asked for

    动态生成他们要求的文件
  • Pick up the file off disk and serve it statically

    从磁盘上拾取文件并静态提供

The example below checks to see if the UserAgent requesting the files foo.xml or bar.xml is FeedBurner. (You could check other things of course, like IP subnet, etc.) If it isn't FeedBurner's bot, we currently redirect them temporarily with an HTTP 302. There's commented code for a permanent redirect, which RSS Readers respect, that would cause the client to update their bookmarks and never return. For now, I'll do a temporary one.

下面的示例检查以查看请求文件foo.xml或bar.xml的UserAgent是否为FeedBurner。 (当然,您可以检查其他内容,例如IP子网等。)如果它不是FeedBurner的机器人,我们当前会使用HTTP 302暂时将其重定向。RSSReaders尊重永久性重定向的注释代码,这将导致客户端更新其书签,并且永不返回。 现在,我将做一个临时的。

   1:  using System;
   2:   
   3:  namespace Foo
   4:  {
   5:      public class  Redirector : System.Web.IHttpHandler
   6:      {
   7:          void System.Web.IHttpHandler.ProcessRequest(System.Web.HttpContext context)
   8:          {
   9:              string userAgent = context.Request.UserAgent;
  10:              if (userAgent != null && userAgent.Length > 0)
  11:              {
  12:                  // If they aren't FeedBurner (optional example check)
  13:                  if (userAgent.StartsWith("FeedBurner") == false)
  14:                  {
  15:                      string redirect = String.Empty;
  16:                      string physicalpath = System.IO.Path.GetFileName( 
context.Request.PhysicalPath).ToUpperInvariant();
  17:                      switch (physicalpath)
  18:                      {
  19:                          case "BAR.XML":
  20:                              redirect = "http://feeds.feedburner.com/Bar";
  21:                              break;
  22:                          case "FOO.XML":
  23:                              redirect = "http://feeds.feedburner.com/Foo";
  24:                              break;
  25:                      }
  26:                      if (redirect != String.Empty)
  27:                      {
  28:                          context.Response.Redirect(redirect); //temporary redirect
  29:   
  30:                          //context.Response.StatusCode = 
(int) System.Net.HttpStatusCode.MovedPermanently; //permanent HTTP 301
  31:                          //context.Response.Status = "301 Moved Permanently";
  32:                          //context.Response.RedirectLocation = redirect;
  33:                          return;
  34:                      }
  35:                  }
  36:              }
  37:              context.Response.ContentType = "application/xml";
  38:              context.Response.TransmitFile(context.Request.PhysicalPath);
  39:          }
  40:   
  41:          bool System.Web.IHttpHandler.IsReusable
  42:          {
  43:              get { return true; }
  44:          }
  45:      }
  46:  }

If they ARE FeedBurner, that means their bot is returning to get fresh data from the foo.xml or bar.xml files. If so, we call the new ASP.NET 2.0 TransmitFile API, that supplements/improves on the earlier WriteFile. Transmit file doesn't buffer to memory and solved a number of problems seen when writing out files and buffering.

如果他们是FeedBurner,则意味着他们的机器人正在返回以从foo.xml或bar.xml文件中获取新数据。 如果是这样,我们将调用新的ASP.NET 2.0 TransmitFile API,该API在早期的WriteFile上进行了补充/改进。 传输文件不会缓冲到内存中,并解决了写文件和缓冲时出现的许多问题。

We also fall to this default code path if any other XML file has been requested, if that file is hooked into ASP.NET via the web.config. In my example, *.xml is hooked up, so all other requests end up in the TransmitFile API.

如果已请求任何其他XML文件(如果该文件已通过web.config挂接到ASP.NET),则我们也将使用该默认代码路径。 在我的示例中,*。xml已连接,因此所有其他请求最终都在TransmitFile API中结束。

TransmitFile doesn't pass the request back to IIS, as some folks believe, nor does it handle caching for you. If you need that support you'll need to write it by following the HTTP spec and handling the headers yourself.

正如某些人认为的那样,TransmitFile不会将请求传递回IIS,也不会为您处理缓存。 如果需要该支持,则需要遵循HTTP规范并自己处理标头来编写它。

To recap:

回顾一下:

  • Tell IIS to pass handling of your extension to ASPNET_ISAPI

    告诉IIS将扩展的处理传递给ASPNET_ISAPI
  • Map files or extensions to Assembly Qualified Names in the web.config httpHandlers section - i.e. What class handles what files dynamically?

    将文件或扩展名映射到web.config httpHandlers部分中的程序集合格名称-即,哪个类动态处理哪些文件?
  • Create, redirect or serve your files

    创建,重定向或提供文件

I'll try to writeup some other ways to solve the same problem, depending on what version of ASP.NET and IIS you're using. If you've got clever ways (there are many) leave them in the comments.

我将尝试编写一些其他方法来解决相同的问题,具体取决于您所使用的ASP.NET和IIS版本。 如果您有聪明的方法(有很多方法),请在评论中留下。

翻译自: https://www.hanselman.com/blog/conditionally-serve-files-statically-or-dynamically-with-httphandlers

httphandlers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,ASHX文件是一种用于处理HTTP请求的处理程序,因此我们需要定义一个实现IHttpHandler接口的类来处理客户端请求。 下面是一个简单的示例。假设我们的ASHX文件名为MyHandler.ashx: ```csharp using System; using System.Web; public class MyHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { // 获取客户端请求的方法 string method = context.Request.HttpMethod; if (method == "GET") { // 处理GET请求 string name = context.Request.QueryString["name"]; context.Response.Write("Hello, " + name + "!"); } else if (method == "POST") { // 处理POST请求 string data = new System.IO.StreamReader(context.Request.InputStream).ReadToEnd(); context.Response.Write("Received data: " + data); } else { // 不支持的请求方法 context.Response.StatusCode = 405; // Method Not Allowed } } public bool IsReusable { get { return false; } } } ``` 在上面的代码中,我们实现了IHttpHandler接口,并覆盖了它的ProcessRequest方法,用于处理客户端请求。我们首先获取请求的方法(GET或POST),然后根据不同的方法执行不同的操作。 对于GET请求,我们从查询字符串中获取“name”参数,并向客户端返回一个简单的问候消息。 对于POST请求,我们从请求正文中读取数据,并向客户端返回一个简单的响应消息。 最后,我们还需要将这个处理程序注册到Web.config文件中,以便IIS能够找到它: ```xml <configuration> <system.web> <httpHandlers> <add verb="*" path="MyHandler.ashx" type="MyHandler"/> </httpHandlers> </system.web> </configuration> ``` 在上面的示例中,我们将MyHandler类注册为能够处理所有HTTP请求方法(verb="*"),并将它的路径设置为MyHandler.ashx。 这样,我们就可以通过发送GET或POST请求到MyHandler.ashx来测试我们的处理程序了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值