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

问题描述 投票:3回答:1

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

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

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

不确定错误在哪里。

c# asp.net-web-api asp.net-web-api2 asp.net-web-api-routing
1个回答
2
投票

简单方法:

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

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

或改变行动从HandlerGet在Catch all 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,您应该已经在您的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());

希望这可以帮助

© www.soinside.com 2019 - 2024. All rights reserved.