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

StackOverflow https://stackoverflow.com/questions/102846

  •  01-07-2019
  •  | 
  •  

好吧,这听起来有点令人困惑和复杂,所以请耐心等待。

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

现在,这一切都可以在IIS 5和6中运行,并且在某种程度上可以在IIS7上运行 - 但是对于一次捕获,当您发布表单时会发生这种情况。

请注意,当您将表单发布到不存在的URL时,IIS会说“啊,但该网址不存在”并且抛出405“不允许的方法”。错误。由于我们告诉IIS将这些错误重定向到我们的.aspx页面,因此使用我们的HttpHandler处理它,这通常不是问题。但是从IIS7开始,所有POST信息在被重定向到405后都丢失了。所以你不能再做涉及表单的最简单的事情了。

为了解决这个问题,我们尝试使用HttpModule,它保留了POST数据但似乎没有在正确的时间(当需要时)初始化Session。我们还尝试对所有请求使用HttpModule,而不仅仅是遇到404/403; 14/405的缺失请求,但这意味着像.NET,css,js等东西正在由.NET代码处理,这非常低效。 / p>

这让我想到了一个实际的问题:有没有人遇到过这个问题,有没有人有任何建议或知道如何让事情再次发挥作用?到目前为止,有人建议使用微软自己的网址重写模块。这有助于解决我们的问题吗?

感谢。

其他提示

由于IIS7自上而下使用.net,因此使用HttpModule不会产生任何性能开销。实际上,每个请求都会使用几个Managed HttpModule。触发BeginRequest事件时,SessionStateModule可能尚未添加到Modules集合中,因此如果您尝试在此事件期间处理请求,则不会有会话状态信息。如果请求的处理程序需要,则设置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内部的内部成员。

IIS 7中的邮件变量没有传递给自定义错误处理程序的问题在Vista的Service Pack 2中得到修复。没有在Windows Server上尝试过,但我确信它也会在那里修复。

只是猜测:处理您的请求的IIS7的%windir%\ system32 \ inetsrv \ config \ applicationhost.config中指定的处理程序根本不允许POST动词通过,并且在确定之前正在评估该规则URL是否不存在。

是的,我肯定会推荐URL重写(使用Microsoft的IIS7中的一个或多个替代方案之一)。这是专门为提供友好的URL而设计的,而错误文档是失败的最后一步支持,它往往会破坏传入的数据,因此它可能不是您所期望的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top