开发者

Wcf Web Api service routes conflicting with regular asp.net mvc routes (web api preview 4)

I noticed that my mvc app is creating wrong url's when using:

@using (Html.BeginForm("Test", "Test"))
{
    <input type="submit" value="Submit" />
}

This is the generated html source:

<form action="/books?action=Test&am开发者_运维问答p;amp;controller=Test" method="post">

Notice that action starts with /books. This is WRONG!

What I've noticed is that Html.BeginForm is always including the beginning of the first web api which has been registered with MapServiceRoute. (see code below)

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    var builder = HttpHostConfiguration.Create();
    routes.MapServiceRoute<BooksService>("books", builder);

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
}

I spent a long time trying to figure out why the url's were broken in my app, but got nowhere. I then decided to test with an extremly simple mvc app and sure enough the problem can be easily reproduced. The mvc app I tested this on is as simple as it can get, was created by an asp mvp. You can find it here. All I did was add the TestController and the Views/Test/Index.cshtml view. In the view I added the Html.BeginForm shown above. If you launch the app and visit the test controller you can see the url is wrong by just hovering the mouse over the submit button (or look at the html source).

Anyone know how to avoid this problem?

EDIT: This applies for web api preview 4 (april 2011).


another way is to define a route constraint:

public class WcfRoutesConstraint : IRouteConstraint {
    public WcfRoutesConstraint(params string[] values) {
        this._values = values;
    }

    private string[] _values;

    public bool Match(HttpContextBase httpContext, Route route, string parameterName,
RouteValueDictionary values, RouteDirection routeDirection) {

    // Get the value called "parameterName" from the
    // RouteValueDictionary called "value"
    string value = values[parameterName].ToString();

    // Return true is the list of allowed values contains
    // this value.
    bool match = !_values.Contains(value);
    return match;
    }
}

Assigning the constraint to the MVC routes

routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
        new { controller = new WcfRoutesConstraint(new string[] {"contact","login"}) }
    );

This prevents MVC from touching the Urls "/login" and "/contact"


Found the answer. It is a known issue. Glenn Block posted a workaround. I just tested, and this does indeed fix the issue. It will be fixed with the next drop.

http://codebetter.com/glennblock/2011/08/05/integrating-mvc-routes-and-web-api-routes-2/


In our next drop in our protoype branch we've included a WebApiRoute that addresses this (using the approach I mentioned in my blog post). MapServiceRoute uses it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜