不存在的目录/文件 Web API(非控制器)的自定义错误页面

2024-02-23

我知道我可以为不存在的控制器或错误的路由设置自定义错误页面,但是如果用户尝试下载某个目录中不存在的文件,如何显示自定义错误页面?我根本无法让它发挥作用。它仍然显示默认错误页面。


这篇博文将引导您处理 ASP.Net Web API 中的 404 错误:http://weblogs.asp.net/imranbaloch/handling-http-404-error-in-asp-net-web-api http://weblogs.asp.net/imranbaloch/handling-http-404-error-in-asp-net-web-api

假设您正在使用 ASP.NET Web API 框架开发 HTTP RESTful 应用程序。在此应用程序中,您需要在集中位置处理 HTTP 404 错误。从 ASP.NET Web API 的角度来看,您需要处理这些情况,

  • 没有匹配的路线。
  • 路由已匹配,但在路由上未找到 {controller}。
  • 未找到名称为 {controller} 的类型。
  • 由于没有以请求 HTTP 方法动词开头的操作方法,或者没有找到具有 IActionHttpMethodProviderRoute 实现属性的操作方法,或者没有找到具有 {action} 名称的方法,或者没有找到具有匹配的 {action} 名称的方法,因此在所选控制器中找不到匹配的操作方法。

现在,让我们使用 Handle404 操作方法创建一个 ErrorController。此操作方法将在上述所有情况下用于向客户端发送 HTTP 404 响应消息。

public class ErrorController : ApiController
{
    [HttpGet, HttpPost, HttpPut, HttpDelete, HttpHead, HttpOptions, AcceptVerbs("PATCH")]
    public HttpResponseMessage Handle404()
    {
        var responseMessage = new HttpResponseMessage(HttpStatusCode.NotFound);
        responseMessage.ReasonPhrase = "The requested resource is not found";
        return responseMessage;
    }
}

您可以轻松更改上述操作方法以发送一些其他特定的 HTTP 404 错误响应。如果 HTTP 服务的客户端向资源(uri)发送请求,并且服务器上没有与此 uri 匹配的路由,那么您可以使用自定义路由将请求路由到上述 Handle404 方法。将此路由放在路由配置的最底部,

routes.MapHttpRoute(
    name: "Error404",
    routeTemplate: "{*url}",
    defaults: new { controller = "Error", action = "Handle404" }
);

现在,您需要处理匹配路由中没有 {controller} 或找不到具有 {controller} 名称的类型时的情况。您可以轻松处理这种情况,并使用自定义 IHttpControllerSelector 将请求路由到上述 Handle404 方法。这是自定义 IHttpControllerSelector 的定义,

public class HttpNotFoundAwareDefaultHttpControllerSelector : DefaultHttpControllerSelector
{
    public HttpNotFoundAwareDefaultHttpControllerSelector(HttpConfiguration configuration)
    : base(configuration)
    {
    }
    public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
    {
        HttpControllerDescriptor decriptor = null;
        try
        {
            decriptor = base.SelectController(request);
        }
        catch (HttpResponseException ex)
        {
            var code = ex.Response.StatusCode;
            if (code != HttpStatusCode.NotFound) throw;
            var routeValues = request.GetRouteData().Values;
            routeValues["controller"] = "Error";
            routeValues["action"] = "Handle404";
            decriptor = base.SelectController(request);
        }
        return decriptor;
    }
}

接下来,如果由于上述原因在所选控制器中没有找到匹配的action方法,还需要将请求传递给上述Handle404方法。这种情况也可以通过自定义 IHttpActionSelector 轻松处理。这里是自定义IHttpActionSelector的源码,

public class HttpNotFoundAwareControllerActionSelector : ApiControllerActionSelector
{
    public HttpNotFoundAwareControllerActionSelector()
    {
    }

    public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
    {
        HttpActionDescriptor decriptor = null;
        try
        {
            decriptor = base.SelectAction(controllerContext);
        }
        catch (HttpResponseException ex)
        {
            var code = ex.Response.StatusCode;
            if (code != HttpStatusCode.NotFound && code != HttpStatusCode.MethodNotAllowed) throw;
            var routeData = controllerContext.RouteData;
            routeData.Values["action"] = "Handle404";
            IHttpController httpController = new ErrorController();
            controllerContext.Controller = httpController;
            controllerContext.ControllerDescriptor = new HttpControllerDescriptor(controllerContext.Configuration, "Error", httpController.GetType());
            decriptor = base.SelectAction(controllerContext);
        }
        return decriptor;
    }
}

最后,我们需要注册自定义的IHttpControllerSelector和IHttpActionSelector。打开 global.asax.cs 文件并添加这些行,

configuration.Services.Replace(typeof(IHttpControllerSelector), new HttpNotFoundAwareDefaultHttpControllerSelector(configuration));
configuration.Services.Replace(typeof(IHttpActionSelector), new HttpNotFoundAwareControllerActionSelector());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不存在的目录/文件 Web API(非控制器)的自定义错误页面 的相关文章

随机推荐

  • express.Router() 返回未定义

    我正在尝试设置一个在我的 node js HTTP 服务器上运行的 REST API 对于常规调用 我希望路径是 对于 API 调用 我想使用 API 根据我从各个网页收集到的信息 包括http expressjs com guide ro
  • 将图像添加到表格单元格 (iOS)

    我正在尝试做一些类似于 Twitter 或 Facebook 的事情 UITableViewCell tableView UITableView tableView cellForRowAtIndexPath NSIndexPath ind
  • 如何使用 Java (J2SE) 创建 QRCode

    如何使用普通j2se创建QRcode图像 有任何 API 或类可以用来执行此操作吗 为此 您需要下载以下 jar zxing core 1 7 jar zxing javase 1 7 jar from http code google c
  • 有没有办法在for循环中添加多个条件?

    n int raw input enter the number of mcnuggets you want to buy total number of mcnuggets you want yo buy for a in range 1
  • JS 字符串:替换为正则表达式中的索引

    我对正则表达式几乎没有经验 我想知道如何替换由正则表达式标识的字符串中的部分 其中索引是标识部分的一部分 这是我的示例字符串 let exampleStr How do I 0 the n with the 1 in my array 这是
  • 启用 nginx 分块传输编码

    看起来像nginx 0 8 35 可能支持分块传输编码 http nginx org en CHANGES 2010 年 4 月 1 日 nginx 0 8 35 的变化 Change now the charset filter runs
  • 项目参考与文件参考?

    可以通过两种方式在项目中添加引用 项目参考 文件参考 但是 什么时候使用 Project 什么时候使用 File 引用 您没有指定 但我猜您指的是 Visual Studio 项目引用和文件引用之间的主要区别在于是否提供实时更新 在项目参考
  • SASS中有多行吗? [复制]

    这个问题在这里已经有答案了 我无法从 SASS 文档中弄清楚这一点 例如我想使用带有 5 个参数的 Compass mixin link colors normal hover false active false visited fals
  • 如何在Meteor服务器中获取用户IP地址?

    我想在我的流星应用程序中的服务器端获取用户IP地址 以便我可以用一堆东西记录IP地址 例如 订阅邮件列表的非注册用户 或者只是做任何事情 重要的 我知道 当涉及反向代理时 服务器 看到 的 IP 地址可能与真实源地址不同 在这种情况下 X
  • MYSQL 中的规范化

    MySQL 中的规范化是什么 在什么情况下以及如何使用它 我尝试在这里用外行术语来解释标准化 首先 它适用于关系数据库 Oracle Access MySQL 因此它不仅仅适用于 MySQL 规范化是为了确保每个表具有唯一的最小字段并消除依
  • uint32_t 与 int 作为日常编程的约定

    什么时候应该使用 stdint h 中的数据类型 总是使用它们作为惯例是正确的吗 像 int 和 Short 这样的非特定大小类型的设计目的是什么 什么时候应该使用 stdint h 中的数据类型 当编程任务指定整数宽度时 特别是为了适应某
  • 在 Facebook 等 iOS 应用程序中预览嵌入链接

    我正在尝试以与 Facebook 相同的方式在 iOS 应用程序中嵌入链接预览 我正在尝试找到一种方法来获取最合适的图像 并返回其 url 页面标题 甚至可能是元描述并将其传递回应用程序 但我不确定最好的方法 有一些 API 可以做到这一点
  • 在 Tkinter 中拖放?

    在 tkinter 中完成拖放的正确 官方 正确 推荐的方法是什么 我的文档第 24 1 1 节包括 Tkdnd 对 Tkinter 的拖放支持 这是实验性的并且 当它被 Tk DND 取代时 它应该被弃用 但我找不到其他的official
  • 正则表达式仅允许数字或空字符串

    有人可以帮我创建这个正则表达式吗 我需要它来检查字符串是否完全是空白 空 或者是否只包含正整数 如果还有其他事情 那就失败了 这是我到目前为止所拥有的 s 0 9 0 9 您正在寻找 s d 如果您想要一个不带前导零的正数 请使用 1 9
  • 如何使用 Expo EAS 为 React Native 中的 组件启用动画 webp?

    使用 Expo EAS 构建时 动画 gif 在 Android 中可以工作 但动画 webp awebp 则不能 Why 如何让 awebp 工作 为什么 gif 动画可以用 但它却不起作用 React Native 有动画图像支持多种格
  • IntelliJ IDEA 和 Gradle:为什么每个子模块有 3 个模块?

    我对 IntelliJ IDEA 的 gradle 集成以及 gradle 子项目到 IDEA 模块的映射感到相当困惑 为什么每个 gradle 子项目都有 3 个模块 client client main 和 client test 有没
  • 停止异步 ISearchJob 的正确方法

    我要使用WUA API https msdn microsoft com en us library windows desktop aa387099 v vs 85 aspx并以这种方式开始执行异步搜索更新 CComPtr
  • python中比较两个列表的最佳算法

    我在 python 中有两个列表 list1 和 list2 其中填充了自己的数据类型 我想将它们与列表进行比较 并将这些列表的所有元素提供给标准输出 或其他地方 但以特定的顺序 不以任何方式对列表进行排序 List1 和 List2 可以
  • 通过 go-mssqldb 进行 golang SQL Server 查询

    我正在尝试查询SQL Server 2008 R2使用去 https github com denisenkom go mssqldb https github com denisenkom go mssqldb SQL Server 20
  • 不存在的目录/文件 Web API(非控制器)的自定义错误页面

    我知道我可以为不存在的控制器或错误的路由设置自定义错误页面 但是如果用户尝试下载某个目录中不存在的文件 如何显示自定义错误页面 我根本无法让它发挥作用 它仍然显示默认错误页面 这篇博文将引导您处理 ASP Net Web API 中的 40