简体   繁体   中英

Web API 2.2 return custom 404 when resource (url) not found

I want to be able to take over the 404 response from web api (iis) when the resource does not exist.

I have done my research and came across only one solution that made this work, but i am not sure how "safe" it is since the "routeTemplate" is just {*url}

This post is kinda to ask for help and explanation.

My App uses MVC and WebAPI... would this template affect MVC as well? Is there a way to add "api" with {*url} in the template? (to make sure only requests with ".../api/..." get affected)

config.Routes.MapHttpRoute("Error404", "{*url}", new { controller = "Error", action = "Handle404" });

Has anyone come across a cleaner way of doing this and handling 404 in web api?

EDIT 1

The above code DOES affect my MVC routes. How can i add "api" to "{*url}"?... if tried many different ways and no dice.

Had the exact same issue. After some research and trial and error, I was able to find a working solution.

I went with a RoutePrefix solution and I tried to implement something similar to how the MVC controllers used HandleUnknownAction in a base controller.

With the help from this post: .NET WebAPI Attribute Routing and inheritance to allow for route inheritance, I created a base controller for my web APIs with a HandleUnknownAction method like this:

public abstract class WebApiControllerBase : ApiController {

    [Route("{*actionName}")]
    [AcceptVerbs("GET", "POST", "PUT", "DELETE")]//Include what ever methods you want to handle
    [AllowAnonymous]//So I can use it on authenticated controllers
    [ApiExplorerSettings(IgnoreApi = true)]//To hide this method from helpers
    public virtual HttpResponseMessage HandleUnknownAction(string actionName) {
        var status = HttpStatusCode.NotFound;
        //This is custom code to create my response content
        //....
        var message = status.ToString().FormatCamelCase();
        var content = DependencyService
            .Get<IResponseEnvelopeFactory>()
            .CreateWithOnlyMetadata(status, message);
        //....
        return Request.CreateResponse(status, content);
    }
}

If you don't want to go down the inheritance path, you can always put the method directly into the controller you want to apply the functionality on.

This allows me to use route prefixes that handle custom not found messages that pertain to specific controllers as I have both back-office and public public facing APIs.

If a URL does not apply to an ApiController the default Error controller will handle the not found as usual.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM