【问题标题】:No action was found on the controller ApiController在控制器 ApiController 上未找到任何操作
【发布时间】:2016-03-10 02:49:12
【问题描述】:

对于我的 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 不正确时,我会收到以下消息:

在控制器“错误”上找不到与名称“处理程序”匹配的操作

不知道错在哪里。

【问题讨论】:

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


    【解决方案1】:

    简单方法

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

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

    或在 Catch all MapHttpRoute 中将操作从 Handler 更改为 Get

    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,您应该已经在您的 Web 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());
    

    希望对你有帮助

    【讨论】:

    • 哇!谢谢@Nkosi。简单的方法奏效了。复杂的解决方案比简单的解决方案有什么优势?我也想试试
    • @RashmiPandit 如果您在没有任何约定的情况下使用属性路由的路径,复杂的允许继承路由。使用 DirectRouteProvider 扩展点可以完全控制如何发现和配置属性路由。
    猜你喜欢
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2013-04-24
    • 2019-02-16
    • 1970-01-01
    相关资源
    最近更新 更多