heymagurany / RegexRouting

Define your routes using regular expressions in ASP.NET MVC and Web API.
MIT License
1 stars 0 forks source link

Support ASP.NET Web API #6

Open heymagurany opened 11 years ago

heymagurany commented 11 years ago

Add extension methods to the RouteCollection class to map regex routes to Web API controllers.

This should be implemented in a separate module as to decouple the ASP.NET Web API dependency from the core routing module.

georgiosd commented 11 years ago

This seems impossible based on my findings here: https://aspnetwebstack.codeplex.com/discussions/451219

Any ideas?

heymagurany commented 11 years ago

Good point. It looks like this will have to wait until the next version of ASP.NET. In the meantime, I've been using System.Web.Routing.RouteCollection to map routes, for which there is an extension method available in the Magurany.Web.Mvc.RegularExpressions namespace

georgiosd commented 11 years ago

You mean API routes? Can you give an example?

heymagurany commented 11 years ago

After installing both the Magurany.Web.Routing.RegularExpressions and Magurany.Web.Mvc.RegularExpressions NuGet packages, you can add the following code to your API route registration:

using Magurany.Web.Routing.RegularExpressions;
...
protected void Application_Start()
{
    routes.MapRegexRoute(
        "RegexRoute",
        "{controller}",
        @"^/(?<controller>segment)/\d+$",
        new { controller = "home", id = RouteParameter.Optional },
        HttpControllerRouteHandler.Instance);

    GlobalConfiguration.Configuration.MessageHandlers.Add(new RegexRouteHandler(config));
}
...

That's probably a weird example, but the thing to take away from it is the last parameter of MapRegexRoute. That's how I get requests to dispatch to the Web API runtime.

I did run into a bug, however. Custom routes aren't aren't accounted for by Web API's default message handler, which casts routes to System.Web.Http.WebHost.Routing.HttpWebRoute. So I had to install a custom message handler to take care of this problem. That is what you're seeing on the last line of the example. That class is not included in the NuGet package (because that's part of my Web API support work), but it is in the source code here: /src/RegexRouting/RegexRouteHandler.cs

georgiosd commented 11 years ago

Funny, I concluded to the same solution: http://stackoverflow.com/questions/17856926/how-to-modify-asp-net-web-api-route-matching-to-allow-parameters-with-slashes-in - feel free to add your answer there to give more visibility to your project.

georgiosd commented 11 years ago

Hm... this is making my API tests (self-hosted Web API) fail (I get a 404 on the routes!) - the culprit seems to be the RouteHandler. Any ideas how to resolve this?

heymagurany commented 11 years ago

I've never testing this in a self-hosted environment before. I'll setup a test and let you know my findings. Do you know if the IHttpRoute interface is used correctly by the web API runtime in a self hosted environment?

georgiosd commented 11 years ago

So here's the drill:

The only thing I haven't managed to figure out is how to check for self-hosted without having a reference to the self-host nuget, which is really not necessary. I guess I could do something hacky like get the config type name and check for the self-hosted config type name... but that's hacky...

heymagurany commented 11 years ago

Were those changes you made to the code from this repo? If so, I think that's worth pulling in for self-hosting support.

I agree that the config type check is a bit gross. When you're adding the route, are you adding it to a RouteCollection or an HttpRouteCollection. That might be the differentiator since we know that's not going to work when hosted in IIS. Of course, that won't be the case when the next version does support IHttpRoute.

georgiosd commented 11 years ago

No, not on this repo, I would have pulled it already :) I had already started working on this before you answered so I kinda went my own way. But I'm happy to give any guidance you may need.

You mean in the self-host scenario? I am adding directly to HttpRouteCollection as it should be. It's all working well there.