gpt4 book ai didi

c# - 不存在的目录/文件 Web API(不是 Controller )的自定义错误页面

转载 作者:太空宇宙 更新时间:2023-11-03 23:30:29 24 4
gpt4 key购买 nike

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

最佳答案

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

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.

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;
}
}

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,

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

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,

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;
}
}

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,

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;
}
}

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

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

关于c# - 不存在的目录/文件 Web API(不是 Controller )的自定义错误页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32429444/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com