控制器ApiController上未找到任何操作

时间:2016-03-10 02:49:13

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

对于我的API,我希望能够处理使用不正确的URL(即与任何控制器或操作不匹配的URL)进行调用的情况。

为此我已经实现了路由,以便它匹配任何路由:

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

我已经实现了控制器 - 操作如下:

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

当我提供错误的网址时,我会收到消息:

  

未找到与名称“处理程序”

匹配的控制器“错误”的操作

不确定错误在哪里。

1 个答案:

答案 0 :(得分:2)

简单方法

您需要匹配操作名称。因此,要么Get中的Handler重命名为ErrorController,要删除属性,因为它们会与您映射的约定冲突。

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

或在Catch all Handler中将行动从Get更改为MapHttpRoute

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

不是那么简单的方法

以下是我使用属性路由和继承在web 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);
    }
}

我的Api控制器都继承自这个基本控制器。

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

鉴于您的问题包含RouteAttribute,您应该已在网络API配置中使用MapHttpAttributeRoutes

但还有更多。要让框架识别继承的属性,您需要覆盖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);
    }
}

并将其应用于web api配置。

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

希望这有帮助