Introduction:

Building modern HTTP/RESTful/RPC
services has become very easy with the new ASP.NET Web API framework.
Using ASP.NET Web API framework, you can create HTTP services which can
be accessed from browsers, machines, mobile devices and other
clients. Developing HTTP services is now become more easy for ASP.NET
MVC developer becasue ASP.NET Web API is now included in ASP.NET MVC. In
addition to developing HTTP services, it is also important to return
meaningful response to client if a resource(uri) not found(HTTP 404) for
a reason(for example, mistyped resource uri). It is also important to
make this response centralized so you can configure all of 'HTTP 404 Not
Found' resource at one place. In this article, I will show you how
to handle 'HTTP 404 Not Found' at one place.

        Description:

Let's say that you are developing
a HTTP RESTful application using ASP.NET Web API framework. In this
application you need to handle HTTP 404 errors in a centralized
location. From ASP.NET Web API point of you, you need to handle these
situations,

  • No route matched.
  • Route is matched but no {controller} has been found on route.
  • No type with {controller} name has been found.
  • No matching action method found in the selected controller due to no
    action method start with the request HTTP method verb or no action
    method with IActionHttpMethodProviderRoute implemented attribute found
    or no method with {action} name found or no method with the matching
    {action} name found.

Now, let create a ErrorController with Handle404
action method. This action method will be used in all of the above
cases for sending HTTP 404 response message to the client.

01 public class ErrorController : ApiController
02 {
03     [HttpGet, HttpPost, HttpPut, HttpDelete, HttpHead, HttpOptions, AcceptVerbs("PATCH")]
04     public HttpResponseMessage Handle404()
05     {
06         var responseMessage = new HttpResponseMessage(HttpStatusCode.NotFound);
07         responseMessage.ReasonPhrase = "The requested resource is not found";
08         return responseMessage;
09     }
10 }

You can easily change the above
action method to send some other specific HTTP 404 error response. If a
client of your HTTP service send a request to a resource(uri) and no
route matched with this uri on server then you can route the request to
the above Handle404 method using a custom route. Put this route at the
very bottom of route configuration,

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

Now you need handle the case when there is no
{controller} in the matching route or when there is no type with
{controller} name found. You can easily handle this case and route the
request to the above Handle404 method using a custom
IHttpControllerSelector. Here is the definition of a custom
IHttpControllerSelector,

01 public class HttpNotFoundAwareDefaultHttpControllerSelector : DefaultHttpControllerSelector
02 {
03     public HttpNotFoundAwareDefaultHttpControllerSelector(HttpConfiguration configuration)
04         : base(configuration)
05     {
06     }
07     public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
08     {
09         HttpControllerDescriptor decriptor = null;
10         try
11         {
12             decriptor = base.SelectController(request);
13         }
14         catch (HttpResponseException ex)
15         {
16             var code = ex.Response.StatusCode;
17             if (code != HttpStatusCode.NotFound)
18                 throw;
19             var routeValues = request.GetRouteData().Values;
20             routeValues["controller"] = "Error";
21             routeValues["action"] = "Handle404";
22             decriptor = base.SelectController(request);
23         }
24         return decriptor;
25     }
26 }

Next, it is also required to pass the request to
the above Handle404 method if no matching action method found in the
selected controller due to the reason discussed above. This situation
can also be easily handled through a custom IHttpActionSelector. Here is
the source of custom IHttpActionSelector,

01 public class HttpNotFoundAwareControllerActionSelector : ApiControllerActionSelector
02 {
03     public HttpNotFoundAwareControllerActionSelector()
04     {
05     }
06  
07     public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
08     {
09         HttpActionDescriptor decriptor = null;
10         try
11         {
12             decriptor = base.SelectAction(controllerContext);
13         }
14         catch (HttpResponseException ex)
15         {
16             var code = ex.Response.StatusCode;
17             if (code != HttpStatusCode.NotFound && code != HttpStatusCode.MethodNotAllowed)
18                 throw;
19             var routeData = controllerContext.RouteData;
20             routeData.Values["action"] = "Handle404";
21             IHttpController httpController = new ErrorController();
22             controllerContext.Controller = httpController;
23             controllerContext.ControllerDescriptor = new HttpControllerDescriptor(controllerContext.Configuration, "Error", httpController.GetType());
24             decriptor = base.SelectAction(controllerContext);
25         }
26         return decriptor;
27     }
28 }

Finally, we need to register the custom
IHttpControllerSelector and IHttpActionSelector. Open global.asax.cs
file and add these lines,

1 configuration.Services.Replace(typeof(IHttpControllerSelector), new HttpNotFoundAwareDefaultHttpControllerSelector(configuration));
2 configuration.Services.Replace(typeof(IHttpActionSelector), new HttpNotFoundAwareControllerActionSelector());

        Summary:

In addition to building an
application for HTTP services, it is also important to send
meaningful centralized information in response when something goes
wrong, for example 'HTTP 404 Not Found' error.  In this article, I
showed you how to handle 'HTTP 404 Not Found' error in a centralized
location. Hopefully you will enjoy this article too.

Handling HTTP 404 Error in ASP.NET Web API的更多相关文章

  1. Global Error Handling in ASP.NET Web API 2(webapi2 中的全局异常处理)

    目前,在Web API中没有简单的方法来记录或处理全局异常(webapi1中).一些未处理的异常可以通过exception filters进行处理,但是有许多情况exception filters无法 ...

  2. Exception Handling in ASP.NET Web API webapi异常处理

    原文:http://www.asp.net/web-api/overview/error-handling/exception-handling This article describes erro ...

  3. Exception Handling in ASP.NET Web API

    public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErr ...

  4. Asp.net web api部署在某些服务器上老是404

    asp.net web api部署在Windows服务器上后,按照WebAPI定义的路由访问,老是出现404,但定义一个静态文件从站点访问,却又OK. 这时,便可以确定是WebAPI路由出了问题,经调 ...

  5. "Asp.Net Web Api MediaTypeFormatter Error for x-www-formurlencoded data" 解决方法

    遇到标题中所说的问题原因是使用 jQuery AJAX 以 POST 方式调用 Asp.Net Web API .解决办法请看以下代码中有注释的部分. public static class WebA ...

  6. 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理

    原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  7. Professional C# 6 and .NET Core 1.0 - Chapter 42 ASP.NET Web API

    本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处: -------------------------------------------------------- ...

  8. 初试ASP.NET Web API/MVC API(附Demo)

    写在前面 HTTP RESTful 创建Web API 调用Web API 运行截图及Demo下载 ASP.NET Web API是​​一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览 ...

  9. ASP.NET Web API 异常日志记录

    如果在 ASP.NET MVC 应用程序中记录异常信息,我们只需要在 Global.asax 的 Application_Error 中添加代码就可以了,比如: public class MvcApp ...

随机推荐

  1. 无法解析指定的连接标识符 oracle错误12154

    导出的时候老是报这个错,exp userid=c##yh/yh@MyOracle tables=(stu3) file=d:\e.dmp; 解决了好久,最后都失败了,后来加了127.0.0.1:152 ...

  2. lintcode: 有效的括号序列

    题目: 有效的括号序列 给定一个字符串所表示的括号序列,包含以下字符: '(', ')', '{', '}', '[' and']', 判定是否是有效的括号序列. 样例 括号必须依照 "() ...

  3. iOS开发--数组

    1.sortedArrayUsingSelector (按Key值大小对NSDictionary排序) NSMutableArray *array = [NSMutableArray arrayWit ...

  4. TCL语言笔记:TCL中的数组

    一.介绍 Tcl 中的数组和其他高级语言的数组有些不同:Tcl 数组元素的索引,或称键值,可以是任意的字符串,而且其本身没有所谓多维数组的概念.数组的存取速度要比列表有优势,数组在内部使用散列表来存储 ...

  5. 74. Search a 2D Matrix

    题目: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the f ...

  6. Splunk作为日志分析平台与Ossec进行联动

    背景: Ossec安装后用了一段时间的analogi作为ossec的报警信息显示平台,但是查看报警分类信息. 以及相关图标展示等方面总有那么一点点的差强人意,难以分析.因此使用逼格高一点的splunk ...

  7. 爬虫Larbin解析(一)——Larbin配置与使用

    介绍 功能:网络爬虫 开发语言:c++ 开发者:Sébastien Ailleret(法国) 特点:只抓取网页,高效(一个简单的larbin的爬虫可以每天获取500万的网页) 安装 安装平台:Ubun ...

  8. !!无须定义配置文件中的每个变量的读写操作,以下代码遍历界面中各个c#控件,自动记录其文本,作为配置文件保存

    namespace PluginLib{    /// <summary>    /// 遍历控件所有子控件并初始化或保存其值    /// </summary>    pub ...

  9. 【原创】MySql 数据库导入导出(备份)

    啥不说了,两周前刚刚做过mysql导入导出的结果现在又忘了.. 更可悲的是竟然同样的三篇blog,现在看起来还是如当初一样费劲,里面的内容..所以自己写个记录一下 环境:*nix 权限:有相关表的写读 ...

  10. JVM学习笔记(三)------内存管理和垃圾回收

    JVM内存组成结构 JVM栈由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)堆 所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制.堆被划分为新生代和旧生 ...