Zach Smith
Zach Smith

Reputation: 8961

How to pass all routes to a single controller in Web API?

I have an OWIN hosted app that does 2 things:

  1. Provides an API at mydomain.com/api/...

  2. Routes ALL other requests to a single controller that returns an HTML page

I currently have this route:

config.Routes.MapHttpRoute(
    name: "default",
    routeTemplate: "{controller}",
    defaults: new { controller = "Index" }
);

And this controller:

public class IndexController : ApiController
{
    public HttpResponseMessage Get()
    {
        string html = File.ReadAllText(@"C:/www/.../index.html");
        HttpResponseMessage response = new HttpResponseMessage
        {
            Content = new StringContent(html),
            StatusCode = System.Net.HttpStatusCode.OK
        };
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
        return response;
    }
}

This works fine when I go to my home route:

mydomain.com => HTML

How can I configure the route template so that I always go to the same controller?

mydomain.com/path1 => I want the same HTML
mydomain.com/path1/something => I want the same HTML
mydomain.com/path2 => I want the same HTML
mydomain.com/path3/somethingElse => I want the same HTML
etc

What I want seems so simple... I don't care if it's a GET, POST, whatever. Unless the route starts with api/ I want to return a single HTML page.

Is there a good way of achieving this with web API?

=== EDIT

I am also using static files - so the path to the static files system should be ignore explicitly:

HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Routes.IgnoreRoute("StaticFiles", "Public/{*url}");
...

Upvotes: 3

Views: 2518

Answers (1)

Nkosi
Nkosi

Reputation: 247018

Create separate routes. One for the API and a catch all route for all other paths

//mydomain.com/api/...
config.Routes.MapHttpRoute(
    name: "api",
    routeTemplate: "api/{controller}",
    defaults: new { controller = "Service" }
);


//mydomain.com/path1 => I want the same HTML
//mydomain.com/path1/something => I want the same HTML
//mydomain.com/path2 => I want the same HTML
//mydomain.com/path3/somethingElse => I want the same HTML
config.Routes.MapHttpRoute(
    name: "default-catch-all",
    routeTemplate: "{*url}",
    defaults: new { controller = "Index", action = "Handle" }
);

The controller can handle the request as desired.

public class IndexController : ApiController {
    [HttpGet]
    [HttpPost]
    [HttpPut]
    public IHttpActionResult Handle(string url) {
        string html = File.ReadAllText(@"C:/www/.../index.html");
        var response = Request.CreateResponse(System.Net.HttpStatusCode.OK, html, "text/html");
        return ResponseMessage(response);
    }
}

Upvotes: 6

Related Questions