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

No action was found on the controller ApiController

对于我的 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() {...}

当我给出错误的 URL 时,我收到消息:

No action was found on the controller 'Error' that matches the name 'Handler'

不知道哪里错了。

简单方法:

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

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

或在捕获所有 MapHttpRoute

中将操作从 Handler 更改为 Get
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);
    }
}

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

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

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

但还有更多。要让框架识别继承的属性,您需要按照 here

所述覆盖 DefaultDirectRouteProvider

并在此处用于回答

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());

希望对您有所帮助