简体   繁体   English

ASP.NET MVC 3 - 带有区域路由的边缘案例

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

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, eg with no product pre-chosen in the URI.现在,问题是,我还需要允许用户 select 页面本身上的产品,例如在 URI 中没有预先选择产品。

Because this controller is in an area , this "default URL" will be like this:因为这个 controller 在一个area中,这个“默认 URL”会是这样的:

/myarea/questions/ask /myarea/问题/询问

So what's happening is, when i get to the action, "someProductUri" is set to "myarea", causing all sorts of grief.所以发生的事情是,当我开始行动时,“someProductUri”被设置为“myarea”,引起了各种各样的悲伤。

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.我想对两组 URL 重复使用相同的操作/视图,但是当它是默认的 URL 时,我不希望将路由值设置为“myarea”。

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?我可以添加一个路由约束,使“someProductUri”不能是“myarea”,这样它就与路由不匹配并回退到默认值?

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" }
        );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM