ApiController 无法处理 404 异常

Posted

技术标签:

【中文标题】ApiController 无法处理 404 异常【英文标题】:ApiController not working with 404 expection 【发布时间】:2019-05-02 09:14:57 【问题描述】:

我有一个从 System.Web.Http.ApiController 派生的控制器(使用 Nuget 包 Microsoft.AspNet.WebApi.Core.5.2.3)。

我在控制器类上使用了RoutePrefix,在Action上使用了Route Attribute。

我配置了两条路线。一个在 WebAPiConfig(HttpRouteCollection) 中,另一个在 RouteConfig(System.Web.Routing.RouteCollection)

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/controller/id",
            defaults: new  id = RouteParameter.Optional );

routes.MapRoute(
            name: "Default",
            url: "controller/action/id",
            defaults: new  controller = "Home", action = "Index", id = UrlParameter.Optional 
        );

当我收到邮递员的请求时。我得到 404 错误代码。奇怪的是堆栈跟踪是:

[HttpException]: The controller for path '/api/Account/IsAuthorized' was not found or does not implement IController.
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

以下是控制器代码:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Description;
[RoutePrefix("api/Account")]
public class AccountController : ApiController

    /// <summary>
    /// Determines whether this instance is authorized.
    /// </summary>
    /// <returns>send whether the user is authorized or not</returns>
    [AllowAnonymous]
    [Route("IsAuthorized")]
    [HttpGet]
    public HttpResponseMessage IsAuthorized()
    
        return Request.CreateResponse(User.Identity.IsAuthenticated);
        ////return true;
    

Global.asax 注册顺序

protected void Application_Start()
    
        AreaRegistration.RegisterAllAreas();
        UnityConfig.RegisterComponents(HttpConfiguration.Config);
        WebApiConfig.Register(HttpConfiguration.Config);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    

为什么框架试图通过 System.Web.Mvc.DefaultControllerFactory.GetControllerInstance 初始化控制器

在同一个 API 项目中,我有另一个由 System.Web.Mvc.Controller 开发的控制器,并且运行良好。

任何指示都会对我有很大帮助。

【问题讨论】:

你也可以分享你的控制器代码吗? @AlenGenzić 我已经编辑了原始帖子以及命名空间 您是从 Postman 发送 GET(不是 POST 或其他任何内容)吗? @JLe 发送 Get 请求,因为 action(IsAuthorized) 支持 Get 你能分享Application_Start()Global.asax.cs 的代码吗? 【参考方案1】:

在定义你的路线之前添加这个:

config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/controller/id",
            defaults: new  id = RouteParameter.Optional );

更多信息here

【讨论】:

这已经在WebApiConfig的Register方法中定义了。 @user2861226 并且你添加了config.MapMvcAttributeRoutes()? 不,我添加了 config.MapHttpAttributeRoutes();尽管。也打算试试 MapMvcAttributeRoutes【参考方案2】:

添加

GlobalConfiguration.Configure(WebApiConfig.Register);

而不是

WebApiConfig.Register(Orbit.WebApi.Extensions.Startup.Config);

为我工作。当谈到 WebAPI 控制器时,我必须弄清楚这两行之间的真正区别是什么。

我记得我在某个地方读到这只是一种改进。但它可以产生如此大的不同,这是我不知道的。

如果有人能对此有所了解,将不胜感激。

【讨论】:

以上是关于ApiController 无法处理 404 异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中使用 CachedNetworkImage 处理 404 异常

如何通过在 Spring MVC 中返回自定义错误页面来全局处理 404 异常?

Spring Boot制作个人博客-框架搭建(异常处理)

返回 NotFound() 或带有 404 页面的未处理异常

404 状态和 url 模式的 Spring 控制器异常处理

zbb20180921 springboot 全局异常处理 404 500