代码之家  ›  专栏  ›  技术社区  ›  Rahul

将表单发布到iis7中的404+httphandler:为什么所有发布数据都丢失了?

  •  2
  • Rahul  · 技术社区  · 16 年前

    好吧,这听起来可能有点混乱和复杂,所以请原谅我。

    我们已经编写了一个框架,允许我们定义友好的URL。如果您浏览任意的URL,IIS会尝试显示404错误(在某些情况下,会显示403、14或405)。但是,IIS的设置是为了将指向这些特定错误的任何内容发送到.aspx文件。这允许我们实现一个httphandler来处理请求和做一些事情,这包括找到一个关联的模板,然后执行与之相关的任何事情。

    现在,所有这些都在IIs5和6中工作,并且在某种程度上,在IIs7中工作——但是对于一个捕获,当您发布表单时会发生这种情况。

    请看,当您将表单发布到不存在的URL时,IIS会说“啊,但是该URL不存在”,并抛出405“方法不允许”错误。因为我们告诉IIS将这些错误重定向到.aspx页面,因此使用httphandler处理这些错误,所以这通常不是问题。但是,从IIS7开始,所有的帖子信息在被重定向到405之后都丢失了。所以你不能再做那些涉及形式的最琐碎的事情了。

    为了解决这个问题,我们尝试使用一个httpmodule,它保留post数据,但似乎没有在正确的时间(当需要时)初始化会话。我们还尝试对所有请求使用httpmodule,不仅仅是达到404/403;14/405的丢失请求,这意味着诸如图像、CSS、JS等内容正在由.NET代码处理,这非常低效。

    这让我想到了一个实际的问题:有人曾经遇到过这样的情况吗?有人有什么建议或者知道该怎么做才能让事情重新开始?到目前为止,有人建议使用微软自己的 URL Rewriting module . 这有助于解决我们的问题吗?

    谢谢。

    5 回复  |  直到 16 年前
        1
  •  2
  •   Çağdaş Tekin    16 年前

    微软为此发布了一个修补程序:

    http://support.microsoft.com/default.aspx/kb/956578

        2
  •  2
  •   Stefan Rusek    16 年前

    由于iis7从上到下使用.NET,因此使用httpmodule不会产生任何性能开销,事实上,有几个托管httpmodules始终用于每个请求。当触发BeginRequest事件时,会话状态模块可能尚未添加到模块集合中,因此如果在此事件期间尝试处理请求,则会话状态信息将不可用。如果请求的处理程序需要,设置httpContext.handler属性将初始化会话状态,因此您只需将处理程序设置为实现IRequiresSessionState的奇特404页。下面的代码应该可以做到这一点,尽管您可能需要为isMissing()方法编写不同的实现:

    using System.Web;
    using System.Web.UI;
    
    class Smart404Module : IHttpModule
    {
        public void Dispose() {}
    
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new System.EventHandler(DoMapping);
        }
    
        void DoMapping(object sender, System.EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
    
            if (IsMissing(app.Context))
                app.Context.Handler = PageParser.GetCompiledPageInstance(
                    "~/404.aspx", app.Request.MapPath("~/404.aspx"), app.Context);
        }
    
        bool IsMissing(HttpContext context)
        {
            string path = context.Request.MapPath(context.Request.Url.AbsolutePath);
    
            if (System.IO.File.Exists(path) || (System.IO.Directory.Exists(path)
                && System.IO.File.Exists(System.IO.Path.Combine(path, "default.aspx"))))
                return true;
            return false;
        }
    }
    

    编辑:我添加了isMissing()的实现

    注意:在iis7上,会话状态模块默认不全局运行。有两个选项:为所有请求启用会话状态模块(请参阅上面关于为所有请求类型运行托管模块的注释),或者可以使用反射访问system.web.dll中的内部成员。

        3
  •  2
  •   bartonlee    15 年前

    在Vista的ServicePack2中修复了无法传递给自定义错误处理程序的POST变量的IIS7中的问题。还没有在Windows服务器上尝试过,但我确信它也将在那里修复。

        4
  •  0
  •   jlew    16 年前

    猜测一下:iis7的%windir%\system32\inetsrv\config\applicationhost.config中指定的处理程序根本不允许post动词通过,它正在评估该规则,然后确定URL是否不存在。

        5
  •  0
  •   bobince    16 年前

    是的,我绝对推荐URL重写(使用微软的iis7一种或多种备选方案之一)。这是专门为提供友好的URL而设计的,而错误文档是失败的最后一道障碍,它往往会吞噬传入的数据,因此它可能不是您所期望的。

    推荐文章