ASP.Net C# 路由; HttpHandler;并且 HttpModule 不工作

发布于 2024-12-17 12:11:33 字数 4275 浏览 1 评论 0 原文

我在自定义扩展和拦截现有处理程序方面遇到了很多问题。

我想做什么

基于持久选项,我希望所有“虚拟”扩展都由设置处理程序处理。所有页面都是动态构建的,站点上不存在实际文件。该站点填充内容、形成 html 输出并将其作为 Web 结果返回。 这是必需的,因为我正在两台服务器之间建立胖/瘦关系。瘦服务器将简单地将请求传递给胖服务器,在胖服务器上处理请求并发出响应。 该项目是一个动态的多域内容管理系统。瘦服务器可能不兼容 .net(因此需要外部请求),但将针对 .net 进行优化(因此需要处理程序)。

问题

我想要的是重新路由现有的扩展 - aspx; php; html。 我已经在本地环境中使用自定义 HttpModule 实现了这一点,该模块设置了适当的处理程序。我已经探索过在配置中设置标签,但是扩展是使用持久的动态规则重新路由的。

如前所述,该解决方案适用于本地主机。 上传后,模块会正确处理 .Net 扩展,但任何自定义扩展或非 .net 扩展都会返回 404 错误。

为了寻求替代方案,我尝试了全局内的路由,但这也不起作用。

我还尝试使用注册自定义扩展...但每个扩展都遇到相同的结果 - 404 未找到。


全局路由尝试:

public class Global : System.Web.HttpApplication
{

    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes(RouteTable.Routes);
    }

    public static void RegisterRoutes(RouteCollection routes)
    {

        routes.Add(new Route("{action}.sqs", new SqlRequestHandler()));
    }

.Config(用于处理程序和模块尝试)

    <system.web>
      <compilation debug="true" targetFramework="4.0" />
      <httpRuntime requestValidationMode="2.0" />
      <customErrors mode="Off"/>

      <httpHandlers>
        <add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
        <add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
      </httpHandlers>

      <httpModules>
        <add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
      </httpModules>
  </system.web>

  <system.webServer>   
      <modules runAllManagedModulesForAllRequests="true" />
      <modules>
        <add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
      </modules>

      <handlers>
        <add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqsHandler" />
        <add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqlHandler" />
      </handlers>
  </system.webServer>

自定义模块(CmsMapper.VirtualModule)

    if (extentionMap != null)
    {
        // note that extentionMap.ExtentionType is a predetermined enum
        switch (extentionMap.ExtentionType)
        {
            // If the extention is banned then pass back a generic message
            case ExtentionType.Banned:
                this.WriteTextResponce("Invalid extention detected:" + extentionMap.Extention);
                break;

            // Remap .Ajax requests to the ajax handler
            case ExtentionType.Ajax:
                this._app.Context.RemapHandler(new AjaxHandler());
                break;

            // Remap session query or sql requests to the sql handler
            case ExtentionType.SessionQuery:
                this._app.Context.RemapHandler(new SqlRequestHandler());
                break;

            // if the extention is not ignored, re map to the virtual page handler
            default:

                bool isManagementServer = this._app.Context.Request.Url.Authority != VirtualModule.RESPONSE_SERVER;
                bool isPostRequest = !String.IsNullOrEmpty(this._app.Context.Request.Form[HtmlRequest.RequestOrigin]);
                bool isGetRequest = !String.IsNullOrEmpty(this._app.Context.Request.QueryString[HtmlRequest.RequestOrigin]);
                bool isIgnored = extentionMap.ExtentionType == ExtentionType.Ignore;

                if ((isPostRequest || isGetRequest) && !isIgnored)
                {
                    this._app.Context.RemapHandler(new VirtualHandler());
                }
                else
                {
                    this._app.Context.RemapHandler(new ExternalRequestHandler());
                }

                break;
        }
    }

所有处理程序都非常标准地实现以下功能:

public class SqlRequestHandler : IHttpHandler, IRequiresSessionState, IRouteHandler

同样,首选方法 - HttpModule - 在我的本地主机上工作。这可能是服务器配置问题(在这种情况下,我正在寻找解决方法),但处理 .net 扩展的事实很奇怪 - 因为这意味着中等信任的问题不应该适用,但是问题关于服务器上的扩展处理可能优先于 .net 应用程序。

服务器是共享托管(因此我无法更改 machine.config 文件),是使用 4.0 的 IIS6。

感谢您提供有关如何解决此问题的任何建议。 麦克风

I am having quite a few problems with custom extensions and intercepting existing handlers.

What am I trying to do

Based upon persisted options, I would like all 'virtual' extensions to be handled by set handlers. All pages are dynamically built, and no actual files exist on the site. The site populates the content, forms the html output and returns it as the web result.
This is required as I am setting up a fat/thin relationship between 2 servers. The thin server will simply pass on the request to the fat server - where the request is processed and response issued back down the line.
The project is for a dynamic multi-domain content management system. The thin server may not be .net compatible (hence the external request), but will be .net optimised (hence the need for handlers).

The Problem

What I want is to re-route existing extensions - aspx; php; html.
I have achieved this in my local environment using a custom HttpModule which sets the appropriate handler. I have explored setting the tag in config, but the the extensions are re-routed using dynamic rules that are persisted.

As mentioned, this solution works on localhost.
When uploaded, the .Net extensions are handled by the module correctly but any custom extensions or non-.net extensions return a 404 error.

Seeking an alternative, I have experimented with routing within Global, but this dis not work either.

I have also attempted to use to register the custom extensions... but each are met with the same result - 404 not found.


Global Routing attempt:

public class Global : System.Web.HttpApplication
{

    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes(RouteTable.Routes);
    }

    public static void RegisterRoutes(RouteCollection routes)
    {

        routes.Add(new Route("{action}.sqs", new SqlRequestHandler()));
    }

.Config (for handler and module attempt)

    <system.web>
      <compilation debug="true" targetFramework="4.0" />
      <httpRuntime requestValidationMode="2.0" />
      <customErrors mode="Off"/>

      <httpHandlers>
        <add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
        <add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
      </httpHandlers>

      <httpModules>
        <add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
      </httpModules>
  </system.web>

  <system.webServer>   
      <modules runAllManagedModulesForAllRequests="true" />
      <modules>
        <add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
      </modules>

      <handlers>
        <add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqsHandler" />
        <add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqlHandler" />
      </handlers>
  </system.webServer>

Custom Module (CmsMapper.VirtualModule)

    if (extentionMap != null)
    {
        // note that extentionMap.ExtentionType is a predetermined enum
        switch (extentionMap.ExtentionType)
        {
            // If the extention is banned then pass back a generic message
            case ExtentionType.Banned:
                this.WriteTextResponce("Invalid extention detected:" + extentionMap.Extention);
                break;

            // Remap .Ajax requests to the ajax handler
            case ExtentionType.Ajax:
                this._app.Context.RemapHandler(new AjaxHandler());
                break;

            // Remap session query or sql requests to the sql handler
            case ExtentionType.SessionQuery:
                this._app.Context.RemapHandler(new SqlRequestHandler());
                break;

            // if the extention is not ignored, re map to the virtual page handler
            default:

                bool isManagementServer = this._app.Context.Request.Url.Authority != VirtualModule.RESPONSE_SERVER;
                bool isPostRequest = !String.IsNullOrEmpty(this._app.Context.Request.Form[HtmlRequest.RequestOrigin]);
                bool isGetRequest = !String.IsNullOrEmpty(this._app.Context.Request.QueryString[HtmlRequest.RequestOrigin]);
                bool isIgnored = extentionMap.ExtentionType == ExtentionType.Ignore;

                if ((isPostRequest || isGetRequest) && !isIgnored)
                {
                    this._app.Context.RemapHandler(new VirtualHandler());
                }
                else
                {
                    this._app.Context.RemapHandler(new ExternalRequestHandler());
                }

                break;
        }
    }

All the handlers are pretty standard implementing the following:

public class SqlRequestHandler : IHttpHandler, IRequiresSessionState, IRouteHandler

Again, the preferred method - HttpModule - works on my localhost machine. This could be a server config issue (in which case I'm looking for a work around), but the fact that the .net extensions are being handled is strange - as this would imply that issues with medium trust should not apply, however issues regarding extension handling on the server may take priority over the .net application.

The server is shared hosting (therefore I am unable to alter the machine.config files), is IIS6 using 4.0.

Thank you for any suggestions on how to resolve this issue.
Mike

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

虫児飞 2024-12-24 12:11:33

您需要在 IIS 6.0 中配置网站以路由所有扩展(包括称为 通配符扩展映射)到 ASP.NET ISAPI dll(并禁用文件存在检查)。

当然,您可以有选择地仅对那些想要通过 ASP.NET 代码路由的扩展进行此映射。但如果您没有预定义的扩展集,通配符映射会更有用。

如果没有这样的映射,IIS 不会将未知扩展名的请求转发到 ASP.NET(并且路由代码甚至不会出现) - 相反,IIS 会将扩展名传递给默认(静态文件)处理程序,该处理程序将发出 404 if file不存在。

请参阅描述这些步骤的这篇文章(适用于 ASP.NET MVC,但这同样适用于您的情况):http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx
在文章接近尾声时,作者给出了如何添加通配符脚本映射

You need to configure web site in IIS 6.0 to route all extensions (including extensionless paths known as wildcard extension mapping) to ASP.NET ISAPI dll (and disable the check for file exists).

You can of course do this mapping selectively only for those extensions that you want to route via ASP.NET code. But wildcard mapping will be more useful in case you don't have predefined set of extensions.

In the absence of such mappings, IIS will not forward requests for unknown extensions to ASP.NET (and routing code will not even come into picture) - rather IIS will pass the extension to default (static file) handler that will issue 404 if file is not present.

See this article that describes these steps (for ASP.NET MVC but the same applies to your case): http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx
Near the end of article, author has given how to add wildcard script map

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文