How to return json for 404s and 403s in WebAPI?

I have a pretty simple web API application that currently has one route setting. If the user tries to access any other route, he gets 404 back, but the body of 404 is HTML instead of JSON (this is what their acceptance header is requesting). What is the easiest (smallest code / config added to my project) to make IIS respond to requests for nonexistent routes with a JSON error response, and not on the web page?

The same question applies to 403s. If I try to go to the root of my application, I get 403 back, again as a web page. I would prefer it to be 404, but the more important question is how can I make all the responses from my JSON application, and not just the answers to the actual routes? I mention 403 because I am looking for a wider solution than just setting up a route for everyone, since I do not believe that this will help me with 403 or any other random exception that occurs outside the controller.

Preferably, I would like my application to respect the accept header in the request. However, since my API supports JSON right now, I am ready to live (for now), it always responds with JSON.

I am using WebAPI 2.2 and .NET 4.5.2.

Edit

This is not a formatting issue. Formatters correctly apply to successful messages by observing the accept header in the request. This is definitely a problem with raw routes and web server errors (for example, it is forbidden when trying to access the web root).

Edit 2

Steps to play:

  • Open Visual Studio 2013 Update 4
  • New project
  • Select .NET Framework 4.5.2
  • Choose Templates> Visual C #> Web> ASP.NET Web Application
  • Select "Empty", leave all folders and links to main links unchecked .
  • Right-click on the project> Add> New Forest Element> Web API 2 Controller - Empty
  • Change the DefaultController as shown below.
  • Modify WebApiConfig.cs as shown below.
  • Run / debug

I expect that when I go to http://localhost:<port>/api/do_stuff , I see Success! in XML or JSON depending on the accept headers (what I do), and when I go to any other page, I should see Failure! (which I do not). Instead, when I go to any other page, I see the IIS 404 answer.

DefaultController.cs:

 [RoutePrefix("api")] public class DefaultController : ApiController { [HttpGet] [Route("do_stuff")] public String DoStuff() { return "Success!"; } } 

WebApiConfig.cs:

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Filters.Add(new CustomExceptionFilter()); } private class CustomExceptionFilter : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext.Response.StatusCode == System.Net.HttpStatusCode.NotFound) { actionExecutedContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.NotFound) { Content = new StringContent(@"""Failure!"""), }; } } } } 

Edit 3

I also tried adding a global exception handler and an exception log, as shown here: http://www.asp.net/web-api/overview/error-handling/web-api-global-error-handling

They are not called when I try to go to the wrong route or go to the root site of the site in the above example.

+6
source share
3 answers

Create an exception filter in the WebAPI and apply it globally to handle any kind of .Net or Custom exception. Internally, in the OnException method, modify the Response property of the Context class for the corresponding Json by serializing an Error object with code and a Json message. Check out the link:

The following is the implementation in my code:

// Create a filter

 public class ViewRExceptionFilterAttribute : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext context) { context.Response = new HttpResponseMessage { Content = new StringContent(globalHttpContextMessage) }; } } 

Here globalHttpContextMessage using the following code:

 globalHttpContextMessage = JsonConvert.SerializeObject(exceptionMessageUI, Formatting.Indented); 

Exception UI Schema:

  [JsonObject] public class ExceptionMessageUI { /// <summary> /// /// </summary> public int ErrorCode { get; set; } /// <summary> /// /// </summary> public string ErrorMessage { get; set; } } 

// Register a filter

  public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Filters.Add(new ViewRExceptionFilterAttribute()); } } 
0
source

Call httpget for 404 notfound response use this

 public JsonResult DoSomething() { try { var result = getData(); return Json(result, JsonRequestBehavior.AllowGet); } catch (Exception ex) { return Json(HttpNotFound()); } } 
0
source

Call the function below from the planned catch-all-route route to return the jsonResult action, as shown below.

 public JsonResult Handle404() { return Json(new { error404 = "NOT FOUND", Message = "Additional Message" }); } 

which will produce

 var result = { "error404": "NOT FOUND", "Message": "Additional Message" }; alert(result.error404); allert(result.Message); 
-1
source

Source: https://habr.com/ru/post/980199/


All Articles