Asp.net mvc 4 用于http配置的路由处理器

Asp.net mvc 4 用于http配置的路由处理器,asp.net-mvc-4,asp.net-web-api,asp.net-mvc-routing,asp.net-web-api-routing,Asp.net Mvc 4,Asp.net Web Api,Asp.net Mvc Routing,Asp.net Web Api Routing,我偶然发现了一篇关于ASP.Net MVC的WebAPI的RouteHandler的有趣文章: 在本文中,它展示了如何将来自桌面web浏览器和移动设备的相同WebAPI请求路由到不同的控制器。该示例使用如下所示的RouteHandler: routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", def

我偶然发现了一篇关于ASP.Net MVC的WebAPI的RouteHandler的有趣文章:

在本文中,它展示了如何将来自桌面web浏览器和移动设备的相同WebAPI请求路由到不同的控制器。该示例使用如下所示的RouteHandler:

routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional }
           ).RouteHandler = new MyRouteHandler();
此代码在Global.asax中使用

但是,我正在通过App_Start中的WebApiConfig注册我的WebAPI路由,其中HttpConfiguration被传递到config方法:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: null,
            handler: new CustomHttpControllerDispatcher(config)
        );

    }
}
config.Routes.MapHttpRoute无法处理RouteHandler。如何将RouteHandler与config.Routes.MapHttpRoute一起使用

谢谢你的帮助

更新

在进一步的研究之后,我想我找到了我想要的,但不确定这种方法是好是坏

我的目标是拦截传入的请求并确定请求的设备类型,以便我可以根据正确的设备(台式机、平板电脑、手机等)定制响应。HttpRequestMessage授予您对标头和UserAgent字符串的访问权。我找到了一种分析UserAgent以确定设备类型()的方法。我使用的命名约定是,在控制器名称后放置DeviceType:

值[DeviceType]控制器

示例:

  • 值控制器
  • 值BILECONTROLER
  • 值稳定控制器
我从UserAgent确定devicetype,然后在RouteData集合中交换控制器名称

**注意:下面的DisplayModeConfig.GetDeviceType(userAgent)使用上面链接中概述的方法

public class CustomHttpControllerDispatcher : HttpControllerDispatcher
{
    public CustomHttpControllerDispatcher(HttpConfiguration configuration): base(configuration)
    {

    }
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // My stuff here
        var userAgent = request.Headers.UserAgent.ToString();
        var deviceType = DisplayModeConfig.GetDeviceType(userAgent);
        IHttpRouteData routeData = request.GetRouteData();

        switch(deviceType)
        {
            case "mobile":
                {
                    var controller = routeData.Values["controller"].ToString();
                    routeData.Values["controller"] = controller + "Mobile";

                    break;
                }
            case "tablet":
                {
                    var controller = routeData.Values["controller"].ToString();
                    routeData.Values["controller"] = controller + "Tablet";

                    break;
                }
            case "desktop":
                {

                    break;
                }
        }

        return base.SendAsync(request, cancellationToken);
    }
}
公共类CustomHttpControllerDispatcher:HttpControllerDispatcher
{
公共CustomHttpControllerDispatcher(HttpConfiguration配置):基本(配置)
{
}
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
//我的东西在这里
var userAgent=request.Headers.userAgent.ToString();
var deviceType=DisplayModeConfig.GetDeviceType(userAgent);
IHttpRouteData routeData=request.GetRouteData();
开关(设备类型)
{
“手机”案例:
{
var controller=routeData.Values[“controller”].ToString();
路由数据值[“控制器”]=控制器+移动设备;
打破
}
案例“平板”:
{
var controller=routeData.Values[“controller”].ToString();
路由数据值[“控制器”]=控制器+平板电脑;
打破
}
案例“桌面”:
{
打破
}
}
返回base.sendaync(请求、取消令牌);
}
}
通过按设备类型指示哪个控制器处理响应,我可以根据设备类型定制正确的响应,从而更好地控制用户体验


你对这种方法有什么想法?您看到这种方法有什么问题吗?

有一种叫做IHttpControllerSelector的服务可以满足您的需要。您可以从DefaultHttpControllerSelector派生并替代GetControllerName