DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • ASP.NET Web API: Benefits and Why to Choose It
  • Revolutionizing Content Management
  • Building a Microservices API Gateway With YARP in ASP.NET Core Web API
  • Implementing CRUD Operations With NLP Using Microsoft.Extensions.AI

Trending

  • The Hidden Cost of AI Tokens: Engineering Patterns for 10x Resource Efficiency
  • Building a High-Throughput Distributed Sequence Generator Using the Hi-Lo Algorithm
  • Build a GitHub Slack Bot With AWS Bedrock and MCP, Part 2
  • Securing the AI Host: Spring AI MCP Server Communication With API Keys
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Handling HTTP 404 Error in ASP.NET Web API

Handling HTTP 404 Error in ASP.NET Web API

By 
Imran Baloch user avatar
Imran Baloch
·
Jun. 22, 12 · Interview
Likes (0)
Comment
Save
Tweet
Share
51.4K Views

Join the DZone community and get the full member experience.

Join For Free

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 quite 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. 

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());

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.

HTTP 404 ASP.NET API Web API Web Service

Published at DZone with permission of Imran Baloch. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • ASP.NET Web API: Benefits and Why to Choose It
  • Revolutionizing Content Management
  • Building a Microservices API Gateway With YARP in ASP.NET Core Web API
  • Implementing CRUD Operations With NLP Using Microsoft.Extensions.AI

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook