2009-09-26 33 views
18

是否有将字符串URL转换为RouteValueDictionary集合的简单方法?一些方法,如UrlToRouteValueDictionary(string url)字符串URL到RouteValueDictionary

我需要这样的方法,因为我想根据我的路由设置'解析'URL,修改一些路由值并使用urlHelper.RouteUrl()根据修改的RouteValueDictionary集合生成字符串URL。

谢谢。

回答

36

这里是不需要嘲笑的溶液:

var request = new HttpRequest(null, "http://localhost:3333/Home/About", "testvalue=1"); 
var response = new HttpResponse(new StringWriter()); 
var httpContext = new HttpContext(request, response); 
var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext)); 
var values = routeData.Values; 
// The following should be true for initial version of mvc app. 
values["controller"] == "Home" 
values["action"] == "Index" 

希望这有助于。

+0

Piotr,非常感谢你的帮助。这个解决方案看起来不错 – Roman 2009-12-02 21:44:08

+2

有人已经写过这样的:[从URL创建一个RouteData实例](http://www.scottschluer.com/creating-a-routedata-instance-from-a-url/) – 2012-07-23 18:41:39

+0

@ david.s我遇到了您发布的解决方案问题。它无法从查询字符串中分离路由值。 Piotr的解决方案正常工作。 – 2013-09-11 08:12:53

3

您将需要创建一个模拟HttpContext作为路由约束需要它。

这里是我用来单元测试我的路线的例子(它是从Pro ASP.Net MVC framework复制):

 RouteCollection routeConfig = new RouteCollection(); 
     MvcApplication.RegisterRoutes(routeConfig); 
     var mockHttpContext = new MockedHttpContext(url); 
     RouteData routeData = routeConfig.GetRouteData(mockHttpContext.Object); 
     // routeData.Values is an instance of RouteValueDictionary 
     //... 
+0

谢谢,这个解决方案看起来很有趣。但可惜没有“轻量级”的方法,不需要嘲笑,因为我在单元测试中使用了Mocks,而不是一般的代码。看起来我应该。 – Roman 2009-11-04 11:02:14

+0

我有类似的问题,最后决定在请求之间传递序列化的RouteCollection。 – 2009-11-05 15:36:29

+0

完美。非常感谢。 – 2011-11-09 05:55:20

0

这是一个不需要实例化一大堆新类的解决方案。

var httpContext = context.Get<System.Web.HttpContextWrapper>("System.Web.HttpContextBase"); 
var routeData = System.Web.Routing.RouteTable.Routes.GetRouteData(httpContext); 
var values = routeData.Values; 
var controller = values["controller"]; 
var action = values["action"]; 

owin上下文包含一个包含HttpContext的环境。

+0

你能解释一下你的owin环境吗?如果我们引用Microsoft.Owin库,你是否在说你的代码片段? – bkwdesign 2015-12-21 21:27:48

+0

我在使用OWIN的MVC项目中运行上面的代码。 MVC 5使用OWIN,但早期版本没有。如果您使用的是MVC 5或更高版本,则不需要添加任何引用。 – 2015-12-22 22:30:39

0

我不会依赖前面示例中的RouteTable.Routes.GetRouteData,因为在这种情况下,您可能会丢失一些值(例如,如果您的查询字符串参数不完全适合任何已注册的映射路由)。另外,我的版本不需要嘲笑一堆请求/响应/上下文对象。

public static RouteValueDictionary UrlToRouteValueDictionary(string url) 
{ 
    int queryPos = url.IndexOf('?'); 

    if (queryPos != -1) 
    { 
     string queryString = url.Substring(queryPos + 1); 
     var valuesCollection = HttpUtility.ParseQueryString(queryString); 
     return new RouteValueDictionary(valuesCollection.AllKeys.ToDictionary(k => k, k => (object)valuesCollection[k])); 
    } 

    return new RouteValueDictionary(); 
}