2

我有一个实现IHttpHandler和的类IRouteHandler

  public class CustomHandler : IHttpHandler,IRouteHandler
  {
    public bool IsReusable
    {
      get { return false; }
    }

    public void ProcessRequest(HttpContext context)
    {
      context.Response.AddHeader("Content-Type", "text/plain");
      context.Response.Write("Hello World");
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
      return this;
    }
  }

在 Application_Start 方法中,我尝试使用路由注册我的处理程序:

Route route = new Route("dav/{*Pathinfo}", new CustomHandler());
RouteTable.Routes.Add(route);

一切都很酷,直到我用这种 URL 调用:
- http://localhost:63428/dav/asdadsa
- http://localhost:63428/dav/asdadsa/asdasd
- http://localhost:63428/dav/asdadsa/a%20%20sdasd (在 url 中有空格)
但是如果我尝试使用 theese:
- http://localhost:63428/dav/asdadsa.docx
-http://localhost:63428/dav/asdads/a.docx
我的处理程序没有被调用并且服务器返回 404。我认为通配符将匹配每个 url以 .开头dav/
知道如何使带有扩展名的网址也与我的路线匹配吗?

更新:
我找到了这个页面
它是从配置中设置的,而不是从后面的代码中设置的,但不必设置 runAllManagedModulesForAllRequests 设置,不幸的是,在我的原始示例中,路由值没有那么干净。
如果来这个问题寻求答案,也许有人会感兴趣。

4

1 回答 1

1

如果您将以下配置添加到您的 web.config 文件,那么您的路由也将包含文件。

<configuration>
  <system.webServer>
    <modules>
      <remove name="UrlRoutingModule-4.0" />
      <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
      <!-- more -->
    </modules>
  </system.webServer>
</configuration>

一种不同的解决方案是添加<modules runAllManagedModulesForAllRequests="true">,但这会产生开销,因为所有注册的 HTTP 模块都在每个请求上运行,而不仅仅是托管请求(例如 .aspx)。这意味着模块将在每个 .jpg .gif .css .html .pdf 等上运行。

您可以在此处阅读有关不同路由设置的更多信息。

请记住,如果您要将特殊路由添加到现有路由,则必须先添加您的路由,否则它将不会被处理,如本例所示。

Route route = new Route("dav/{*Pathinfo}", new CustomHandler());
routes.Add(route);

routes.MapRoute(
  name: "Default",
  url: "{controller}/{action}/{id}",
  defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

这种方法的一个问题是,第一个路由定义会混淆系统中的 Html 助手,因此您不会再获得像localhost/home/indexbut 那样的好路由localhost/dav?action=index&controller=home。对此的解决方案是将第一条路由限制为仅对传入的路由请求有效。这可以通过创建 aRouteConstraint并将其添加到 a 中的路由定义来完成RouteValueDictionary

public class OnlyIncomingRequestConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.IncomingRequest)
            return true;
        return false;
    }
}

然后,您可以通过这种方式重新定义您的路由定义:

Route route = new Route("dav/{*Pathinfo}", new RouteValueDictionary(new { controller = new OnlyIncomingRequestConstraint() }), new CustomHandler());
routes.Add(route);

在此之后,您的默认路由应该会再次恢复正常。

于 2013-08-29T10:40:45.110 回答