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

本文关键字:路由 webapi 处理 设置 程序 属性 | 更新日期: 2023-09-27 18:20:43

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

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",然后从这里使用路由属性,并使所有控制器都具有自定义处理程序?

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

我试图为开发人员提供一种非常清晰的方式,让他们看到这个控制器或方法使用的是自定义的routehandler,如果新的开发人员应该添加另一个控制器,他们可以使用一个特殊的路由,比如"/custom"或使用一个属性。

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

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

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

小心!由于与Web API WebHost框架的集成问题,以下功能将不起作用:

匹配路由时的性能增强、自定义路由处理程序,querystring参数约束,子域路由,本地化应用于入站/出站url,并降低前缀的大小写、附加前缀,等等到生成的路由。这些功能都必须等待的vNextWeb 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) }
    );
}

请注意,必须显式指定YourCustomMessageHandlerInnerHandler,才能将请求向下传递到管道中的其他处理程序和控制器。有关详细信息,请参阅Microsoft说明。