使用路由属性时设置web api路由处理程序

时间:2015-11-05 11:06:53

标签: c# asp.net-web-api

我有一个自定义路由处理程序,我想在不同的控制器上使用。现在,我让我的控制器使用这个路由处理程序的唯一方法就是像这样设置它

RouteTable.Routes.MapHttpRoute(
    name: "CustomRouteHandler",
    routeTemplate: "/custom/{controller}/{action}",
    defaults: new { id = RouteParameter.Optional, action = RouteParameter.Optional }
    ).RouteHandler = new CustomRouteHandler();

我真的想使用像这样的路线属性

[HttpGet]
[Route(Name = "GetCart")]
public Cart Get()
{
    return _repository.Get();
}

但是,当我使用路线属性时,似乎无法弄清楚如何确保我使用自定义路线处理程序。优选我只会使用路由属性,所以如果我可以使用像" RouteHandler"这里指向我的" CustomRouteHandler"这将是完美的。

我是否可以使用这样的属性,或者我可以在某种程度上将MapHttpRoute中的所有内容指向" / Custom"然后使用此处的路由属性并使所有控制器都具有自定义处理程序?

另一种选择是否可以制作我自己的属性,使控制器或方法使用我的自定义路由处理程序?

我试图为开发人员制作一个非常清晰的方法,让他们看到这个控制器或方法正在使用自定义路由处理程序,如果新开发人员应该添加另一个控制器,他们可以使用像#34这样的特殊路由; /定制"或使用属性。

非常欢迎任何想法。 感谢。

1 个答案:

答案 0 :(得分:5)

不幸的是,由于某些限制,这在纯AttributeRouting中是不可能的:

  

小心!由于Web API WebHost框架的集成问题,   以下功能无效:

     

匹配路线,自定义路线处理程序时的性能增强,   查询字符串参数约束,子域路由,本地化   应用于入站/出站网址,小写,附加前缀,   等生成的路线。这些功能都必须等待vNext   Web API。

所以你只有三个选择。

1)以经典方式在WebApiConfig.cs中进行路由:

config.Routes.MapHttpRoute(
    name: "GetData",
    routeTemplate: "api/yourawesomecontroller/data",
    defaults: new { controller = "YourAwesomeController", action = nameof(YourAwesomeController.GetData) },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) },
    handler: new YourCustomMessageHandler() { InnerHandler = new HttpControllerDispatcher(config) }
);

2)你也可以为所有请求注册YourCustomMessageHandler并在处理程序本身内实现路由过滤:

class YourCustomMessageHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Method == HttpMethod.Get &&
            request.RequestUri.PathAndQuery.StartsWith("/api/yourawesomecontroller/data"))

        // ... custom handling for request ...

        var response = await base.SendAsync(request, cancellationToken);

        // ... custom handling for response ...

        return response;
    }
}

3)最后一个选项是自定义路由属性:

public class MyRouteAttribute : Attribute
{
    public string Url { get; private set; }

    public MyRouteAttribute (string url)
    {
        Url = url;
    }
}

你需要用它来装饰动作方法。但在这种情况下,您需要在自定义引导程序中注册类似于选项1)的路由,如下所示:

foreach (var controllerType in allControllerTypes)
{
    var attributes = System.ComponentModel.TypeDescriptor.GetAttributes(controllerType);
    var urlAttribute = (MyRouteAttribute) attributes[typeof(MyRouteAttribute)];
    var controllerName = controllerType.Name.Replace("Controller", "");

    config.Routes.MapHttpRoute(
        name: controllerName,
        routeTemplate: urlAttribute.Url,
        handler: new YourCustomMessageHandler() { InnerHandler = new HttpControllerDispatcher(config) }
    );
}

请注意,您必须明确指定InnerHandler YourCustomMessageHandler才能将请求传递给管道到其他处理程序和控制器。有关详细信息,请参阅Microsoft explanation