2

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

http://techbrij.com/separate-web-api-action-mobile-asp-net-mvc

在本文中,它展示了来自桌面 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 授予您对 Headers 和 UserAgent 字符串的访问权限。我找到了一种分析 UserAgent 以确定设备类型的方法(http://techbrij.com/display-mode-mobile-tablet-tv-aspnet-mvc)。我正在使用命名约定,将 DeviceType 放在控制器名称之后:

值[设备类型]控制器

例子:

  • 值控制器
  • 价值观移动控制器
  • 值平板控制器

我从 UserAgent 确定设备类型,然后在 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);
    }
}

通过根据设备类型指示哪个控制器处理响应,我可以通过定制对设备类型的正确响应来更好地控制用户体验。

您对这种方法有何看法?你能看出这种方法有什么问题吗?

4

1 回答 1

0

有一个名为 IHttpControllerSelector 的服务可以满足您的目的。您可以从 DefaultHttpControllerSelector 派生并覆盖 GetControllerName。

于 2013-02-18T21:02:08.277 回答