Строковый URL-адрес в RouteValueDictionary
Есть ли простой способ преобразования строкового URL в коллекцию RouteValueDictionary? Некоторый метод вроде UrlToRouteValueDictionary(string url)
.
Мне нужен такой метод, потому что я хочу "разобрать" URL в соответствии с настройками моих маршрутов, изменять некоторые значения маршрута и использовать urlHelper.RouteUrl() генерировать строковый URL-адрес в соответствии с измененной коллекцией RouteValueDictionary.
Спасибо.
Ответы
Ответ 1
Вот решение, которое не требует насмешек:
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"
Надеюсь, что это поможет.
Ответ 2
Вам нужно будет создать издевательский HttpContext, если это потребует ограничение маршрутов.
Вот пример, который я использую для unit test моих маршрутов (он был скопирован из 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
//...
Ответ 3
Вот решение, которое не требует создания экземпляра новых классов.
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.
Ответ 4
Я не буду полагаться на 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();
}