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

不羁岁月 提交于 2019-12-31 02:54:10

问题


OK, this might sound a bit confusing and complicated, so bear with me.

We've written a framework that allows us to define friendly URLs. If you surf to any arbitrary URL, IIS tries to display a 404 error (or, in some cases, 403;14 or 405). However, IIS is set up so that anything directed to those specific errors is sent to an .aspx file. This allows us to implement an HttpHandler to handle the request and do stuff, which involves finding the an associated template and then executing whatever's associated with it.

Now, this all works in IIS 5 and 6 and, to an extent, on IIS7 - but for one catch, which happens when you post a form.

See, when you post a form to a non-existent URL, IIS says "ah, but that url doesn't exist" and throws a 405 "method not allowed" error. Since we're telling IIS to redirect those errors to our .aspx page and therefore handling it with our HttpHandler, this normally isn't a problem. But as of IIS7, all POST information has gone missing after being redirected to the 405. And so you can no longer do the most trivial of things involving forms.

To solve this we've tried using a HttpModule, which preserves POST data but appears to not have an initialized Session at the right time (when it's needed). We also tried using a HttpModule for all requests, not just the missing requests that hit 404/403;14/405, but that means stuff like images, css, js etc are being handled by .NET code, which is terribly inefficient.

Which brings me to the actual question: has anyone ever encountered this, and does anyone have any advice or know what to do to get things working again? So far someone has suggested using Microsoft's own URL Rewriting module. Would this help solve our problem?

Thanks.


回答1:


Microsoft released a hotfix for this :

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




回答2:


Since IIS7 uses .net from the top down there would not be any performance overhead of using an HttpModule, In fact there are several Managed HttpModules that are always used on every request. When the BeginRequest event is fired, the SessionStateModule may not have been added to the Modules collection, so if you try to handle the request during this event no session state info will be available. Setting the HttpContext.Handler property will initialize the session state if the requested handler needs it, so you can just set the handler to your fancy 404 page that implements IRequiresSessionState. The code below should do the trick, though you may need to write a different implementation for the IsMissing() method:

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;
    }
}

Edit: I added an implementation of IsMissing()

Note: On IIS7, The session state module does not run globally by default. There are two options: Enable the session state module for all requests (see my comment above regarding running managed modules for all request types), or you could use reflection to access internal members inside System.Web.dll.




回答3:


The problem in IIS 7 of post variables not being passed through to custom error handlers is fixed in service pack 2 for Vista. Haven't tried it on Windows Server but I'm sure it will be fixed there too.




回答4:


Just a guess: the handler specified in IIS7's %windir%\system32\inetsrv\config\applicationhost.config which is handling your request is not allowing the POST verb to get through at all, and it is evaluating that rule before determining whether the URL doesn't exist.




回答5:


Yes, I would definitely recommend URL rewriting (using Microsoft's IIS7 one or one of the many alternatives). This is specifically designed for providing friendly URLs, whereas error documents are a last-ditch backstop for failures, which tends to munge the incoming data so it may not be what you expect.



来源:https://stackoverflow.com/questions/102846/posting-forms-to-a-404-httphandler-in-iis7-why-has-all-post-data-gone-missing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!