的ASP.NET Web API定制IHttpControllerSelector为单一路线 [英] ASP.NET Web API custom IHttpControllerSelector for a single route

查看:745
本文介绍了的ASP.NET Web API定制IHttpControllerSelector为单一路线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个自定义的 IHttpControllerSelector 应该只应用于特定的路线。所有其他网页API路线应该使用的默认实现 IHttpControllerSelector

I need a custom IHttpControllerSelector which should be applied to a specific route only. All other web api routes should use the default implementation of IHttpControllerSelector.

虽然研究我发现下面的code,是为了取代IHttpControllerSelector在应用程序启动,但它完全替代默认的控制器选择,这会导致应用程序中的所有路由都使用我的自定义控制器选择:

While researching I found the following code that is meant to replace the IHttpControllerSelector at application start, but it replaces the default controller selector completely, which causes that all routes in the application use my custom controller selector:

config.Services.Replace(typeof(IHttpControllerSelector), 
                                                    new CustomControllerSelector(config));

有没有配置的方式 IHttpControllerSelector 为单一路线?

推荐答案

您可以指定每个路由消息处理程序需要使用不同的控制器选择逻辑的路线。这种处理器将与这一请求需要区别对待的标志标记的Htt prequestMessage

You can assign a per-route message handler to the route that needs to use a different controller selection logic. This handler would mark the HttpRequestMessage with a flag that this request needs to be treated differently.

然后,只需让 CustomControllerSelector DefaultHttpControllerSelector 继承并检查该标志:

Then simply make the CustomControllerSelector inherit from DefaultHttpControllerSelector and inspect that flag:


  • 如果它的设置,继续与您的定制逻辑

  • 如果它没有设置,返回基地( DefaultHttpControllerSelector

  • if it's set, continue with your custom logic
  • if it's not set, return to base (DefaultHttpControllerSelector)

下面是code:

1)消息处理程序,设置标志

1) message handler, setting the flag

public class RouteSpecificHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Properties["UseCustomSelector"] = true;
        return base.SendAsync(request, cancellationToken);
    }
}

2)每路线消息处理程序分配给特定的路线只有(不用于其他路线上)

2) assigning per route message handler to the specific route only (do not run for other routes)

        config.Routes.MapHttpRoute(
            name: "MyRoute",
            routeTemplate: "api/dummy/{id}",
            defaults: new {controller = "Dummy", id = RouteParameter.Optional},
            constraints: null,
            handler: new RouteSpecificHandler { InnerHandler = new HttpControllerDispatcher(config) }
            );

3)自定义选择尊重国旗:

3) custom selector respecting the flag:

public class CustomSelector : DefaultHttpControllerSelector
{
    public CustomSelector(HttpConfiguration configuration) : base(configuration)
    {
    }

    public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
    {
        if (request.Properties.ContainsKey("UseCustomSelector") &&
            request.Properties["UseCustomSelector"] as bool? == true)
        {
            //your logic goes here
        }

        return base.SelectController(request);
    }
}

4)注册​​选择:

4) registering the selector:

config.Services.Replace(typeof(IHttpControllerSelector), new CustomSelector(config));

修改

如果您不希望为从 DefaultHttpControllerSelector 继承 - 然后实现 IHttpControllerSelector 直接的,而不是调用 base.SelectController(要求)保存旧的选择作为一个字段/属性在你的类

edit

If you wish to not inherit from DefaultHttpControllerSelector - then implement IHttpControllerSelector directly, and instead of calling the base.SelectController(request) save the old selector as a field/property in your class

public class CustomSelector : IHttpControllerSelector
{
    private HttpConfiguration _config;

    public IHttpControllerSelector PreviousSelector {get; set;}

    public CustomSelector(HttpConfiguration configuration)
    {
         _config = configuration;
    }

    public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
    {
        if (request.Properties.ContainsKey("UseCustomSelector") &&
            request.Properties["UseCustomSelector"] as bool? == true)
        {
            //your logic goes here
        }

        return PreviousSelector.SelectController(request);
    }
}

然后,只需变更登记:

Then just change the registration:

  var previousSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as IHttpControllerSelector;
 config.Services.Replace(typeof(IHttpControllerSelector), new CustomSelector(config) { PreviousSelector = previousSelector});  

这篇关于的ASP.NET Web API定制IHttpControllerSelector为单一路线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆