繁体   English   中英

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

[英]Posting forms to a 404 + HttpHandler in IIS7: why has all POST data gone missing?

好吧,这听起来可能有点混乱和复杂,请耐心等待。

我们编写了一个框架,使我们可以定义友好的URL。 如果您浏览任何任意URL,IIS会尝试显示404错误(或在某些情况下为403; 14或405)。 但是,已设置IIS,以便将针对那些特定错误的所有内容发送到.aspx文件。 这使我们可以实现HttpHandler来处理请求和处理工作,这涉及找到相关的模板,然后执行与之相关的任何内容。

现在,这一切都可以在IIS 5和IIS 6中使用,并且在某种程度上也可以在IIS7上使用-但要注意的一点是,发布表单时会发生这种情况。

请参见,将表单发布到不存在的URL时,IIS会显示“啊,但该URL不存在”,并抛出405“不允许的方法”错误。 由于我们要告诉IIS将这些错误重定向到.aspx页,并因此使用HttpHandler进行处理,因此这通常不是问题。 但是从IIS7开始,所有POST信息在重定向到405后都丢失了。因此,您不能再做涉及表单的最琐碎的事情。

为了解决这个问题,我们尝试使用HttpModule,它保留POST数据,但似乎在正确的时间(需要时)没有初始化的Session。 我们还尝试对所有请求使用HttpModule,不仅是命中404/403; 14/405的丢失请求,而且这意味着图像,css,js等内容正在由.NET代码处理,这效率极低。

这使我想到了一个实际的问题:是否有人遇到过这个问题?是否有人提出任何建议或知道该怎么做才能使事情再次起作用? 到目前为止,有人建议使用Microsoft自己的URL重写模块 这会解决我们的问题吗?

谢谢。

由于IIS7自上而下使用.net,因此使用HttpModule不会带来任何性能开销,因此实际上有多个托管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上尝试过它,但是我敢肯定它也将在此修复。

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

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

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

是的,我绝对建议您重写URL(使用Microsoft的IIS7或许多替代方法之一)。 这是专门为提供友好的URL而设计的,而错误文档是失败的最后支持,这往往会破坏传入的数据,因此可能不是您所期望的。

暂无
暂无

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

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