Reputation: 5134
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?
Upvotes: 7
Views: 2490
Reputation: 66783
WebAPI allows you to define custom route constraints by implementing System.Web.Http.Routing.IHttpRouteConstraint.
In regular ASP.NET MVC you can do the same by implementing System.Web.Routing.IRouteConstraint.
This way, you can create routes that are only active for a certain HTTP Accept header e.g. "application/json" or "text/html".
Upvotes: 3
Reputation: 86
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) ;)
Upvotes: 4
Reputation: 3240
In theory, you can use web api and build a content provider that will return html (possible from razor) when the client requests text\html and json when the client requests application\json
Upvotes: 1
Reputation: 93464
Since the Web API uses the same routing system as MVC, if you have some way to differentiate the routes then you can use the same base url for both. You would need some kind of route constraint to map api calls to the api. This could be querystring parameter, for instance.
If your url is exactly the same, even down to querystring, then no. You're out of luck.
Upvotes: 0
Reputation: 58494
Previous answers have explained the situation. One thing to add is that, ASP.NET MVC or Web API, your all routes get collected under the same list.
For example, on the default project template, if you register the ASP.NET MVC route before the Web API one, you will see that requests under /api
path are picked up by ASP.NET MVC route.
Upvotes: 1
Reputation: 23472
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.
Upvotes: 4
Reputation: 28338
No, you cannot have a single URL route to two different classes. If more than one route matches an incoming request, the first one to be matched will be used.
I'm not sure why you would need to mix the two in a single project, at least not any practical reason. The ApiController
can return HTML and the MVC Controller
can return JSON, so just pick one and use it.
Upvotes: 1