2

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

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

现在,这一切都适用于 IIS 5 和 6,在某种程度上,也适用于 IIS7 - 但有一个问题,当您发布表单时会发生这种情况。

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

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

这让我想到了一个实际的问题:有没有人遇到过这种情况,有没有人有任何建议或知道该怎么做才能让事情恢复正常?到目前为止,有人建议使用微软自己的URL 重写模块。这会帮助解决我们的问题吗?

谢谢。

4

5 回答 5

2

由于 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 中的内部成员。

于 2008-09-20T20:02:09.947 回答
2

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

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

于 2009-01-08T19:02:28.527 回答
2

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

于 2009-10-19T20:37:25.350 回答
0

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

于 2008-09-19T15:50:54.333 回答
0

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

于 2008-10-20T10:56:45.003 回答