2016-03-10 6 views
3

Для моего API, я хочу, чтобы иметь возможность обрабатывать сценарии, где вызов выполняется с использованием неверного URL (то есть URL-адрес, который не соответствует ни одному контроллеру или действие.)никаких действий не было найдено на ApiController контроллера

Для это я реализовал маршрут так, чтобы он соответствовал любому маршруту:

config.Routes.MapHttpRoute(
       name: "CatchAll", 
       routeTemplate: "{*any}", 
       defaults: new { controller = "Error", action = "Handler" } 
       ); 

И я реализовал контроллер - действие следующим образом:

[Route("api/v1/Handler")] 
[ActionName("Handler")] 
public HttpResponseMessage Get() {...} 

Когда я даю неверный URL, я получаю сообщение: никаких действий не было найдено на контроллер «Error», совпадающий с именем «Обработчик»

Не уверен, где ошибка. Любая помощь приветствуется.

ответ

2

Простой подход:

Вы должны совпадать с именем действия. Поэтому либо переименуйте Get в Handler в ErrorController и удалите атрибуты, поскольку они будут конфликтовать с соглашениями, которые вы сопоставили.

public HttpResponseMessage Handler(string any) {...} 

или изменить действие от Handler к Get в улове все MapHttpRoute

config.Routes.MapHttpRoute(
      name: "CatchAll", 
      routeTemplate: "{*any}", 
      defaults: new { controller = "Error", action = "Get" } 
      ); 

Не так просто подход:

Вот как я обработал то же самое в моем веб-API, используя маршрутизация атрибутов и наследование.

Сначала я создал базовый контроллер api, который будет обрабатывать неизвестные действия.

public abstract class WebApiControllerBase : ApiController { 

    [Route("{*actionName}")] 
    [AcceptVerbs("GET", "POST", "PUT", "DELETE")] 
    [AllowAnonymous] 
    [ApiExplorerSettings(IgnoreApi = true)] 
    public virtual HttpResponseMessage HandleUnknownAction(string actionName) { 
     var status = HttpStatusCode.NotFound; 
     var message = "[Message placeholder]"; 
     var content = new { message = message, status = status}; 
     return Request.CreateResponse(status, content); 
    } 
} 

Контроллеры My Api все наследуются от этого базового контроллера.

[RoutePrefix("api/customers")] 
public class CustomersApiController : WebApiControllerBase {...} 

Учитывая, что ваш вопрос включен RouteAttribute вы уже должны использовать MapHttpAttributeRoutes в вашем Web API конфигурации.

Но есть еще. Для того, чтобы получить основу для распознавания наследуемые атрибуты, которые необходимо переопределить DefaultDirectRouteProvider как указано here

и используется в качестве ответа здесь

WebAPI controller inheritance and attribute routing

public class WebApiCustomDirectRouteProvider : DefaultDirectRouteProvider { 
    protected override System.Collections.Generic.IReadOnlyList<IDirectRouteFactory> 
     GetActionRouteFactories(System.Web.Http.Controllers.HttpActionDescriptor actionDescriptor) { 
     // inherit route attributes decorated on base class controller's actions 
     return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true); 
    } 
} 

и применить это к конфигурации веб-API.

// Attribute routing. (with inheritance) 
config.MapHttpAttributeRoutes(new WebApiCustomDirectRouteProvider()); 

Надеется, что это помогает

+0

Wow! Thx @ Nkosi. Простой подход работал. В чем преимущество комплексного решения над простым?Я также хотел бы попробовать это –

+0

@RashmiPandit. Комплекс позволяет наследовать маршруты, если вы идете по пути использования маршрутизации атрибутов без каких-либо соглашений. Использование точки расширения DirectRouteProvider дает полный контроль над тем, как маршруты атрибутов обнаруживаются и настраиваются. – Nkosi

Смежные вопросы