Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can ASP.NET Web API work on same url as MVC?

Can I have same url for both ASP.NET MVC requests returning HTML and for ASP.NET Web API returning JSON?

I see in examples routes like this: "api/{id}" but can I get rid of this api/ part and use this address in MVC (not Web API) too?

On one side this should be possible as we have content negotiation. But this way I require two routes with same address so this doesn't make sense, right?

In other words: can I have Controller and ApiController with same url? Or should I use ApiController also for HTML?

like image 519
Pol Avatar asked Mar 04 '12 19:03

Pol


2 Answers

As stated in the previous answer you cannot do such a thing and I really can't see the point why you would want to do something like that.

But I do not agree that you should stick with one thing in a single project, if you want a clean API then I would go for the webapi and use MVC to host my pages, and at that point I would have the API in a separate folder plus under a separate route.

like image 194
Tomas Jansson Avatar answered Oct 05 '22 22:10

Tomas Jansson


I may be playing devils advocate here, but I can see the point why someone would want to do something like this.

Often it is nice to have an HTML representation of an API on the same URL. This approach allows users to click around and explore an API from within the browser.

I have gotten around this in the WebAPI by using a custom message handler which 302 redirects to an MVC route.

public class HtmlMessageHandler : DelegatingHandler
{
    private List<string> contentTypes = new List<string> { "text/html", "application/html", "application/xhtml+xml" };

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Method == HttpMethod.Get && request.Headers.Accept.Any(h => contentTypes.Contains(h.ToString())))
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Redirect);

            var htmlUri = new Uri(String.Format("{0}/html",request.RequestUri.AbsoluteUri));

            response.Headers.Location = htmlUri;

            return Task.Factory.StartNew<HttpResponseMessage>(()=> response);
        }
        else 
        {
            return base.SendAsync(request, cancellationToken);
        }
    }
}

Bit of a hack maybe but it does the job and I personally like it more than a custom HTML MediaTypeFormatter (which I also tried) ;)

like image 44
Oliver Picton Avatar answered Oct 05 '22 22:10

Oliver Picton