在控制器 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());
希望对您有所帮助
对于我的 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());
希望对您有所帮助