开发者

ASP.NET MVC 3 - Edge case with Routing in Area

开发者 https://www.devze.com 2023-03-22 07:24 出处:网络
I have a page where user\'s can "Ask a Question" against a product. The route is: context.MapRoute(

I have a page where user's can "Ask a Question" against a product.

The route is:

context.MapRoute(
                "Q&A - Ask - by Product",
                "{someProductUri}/questions/ask",
                new { controller = "Questions", action = "Ask" }
            );

Which matches:

/car/questions/ask

/phone/questions/ask

Here's the action:

public class QuestionsController : Controller
{
    public ViewResult Ask(string someProductUri)
    {
      // ...
    }
}

Now, the problem is, i also need to allow the user to select the product on the page itself, e.g with no product pre-chosen in the URI.

Because this controller is in an area, this "default URL" will be like this:

/myarea/questions/ask

So what's happening is, when i get to the action开发者_StackOverflow中文版, "someProductUri" is set to "myarea", causing all sorts of grief.

I want to re-use the same action/view for both sets of URL's, but i don't want the route value to be set to "myarea" when it's the default URL.

Hope that makes sense - any ideas?

Do i need a seperate route? Can i add a route constraint so that the "someProductUri" can't be "myarea", so that it doesn't match the route and falls back to the default?


I already have too many routes, so i didn't want to add another just for this edge case.

So i ended up using a route constraint:

public class NotEqualToAreaName : IRouteConstraint
{
   public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
   {
      return String.Compare(values[parameterName].ToString(), route.DataTokens["area"].ToString(), true) != 0;
   }    
}

Pretty simple, and generic - so i can re-use it anytime i come across this type of edge case.


You need to add a separate route for the area:

context.MapRoute(
            "Q&A - Ask - by Product",
            "myarea/questions/ask",
            new { controller = "Questions", action = "Ask" }
        );
0

精彩评论

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

关注公众号