手动通过模型绑定器传递一个url来获取RouteData参数

问题描述:

我有一个复杂的ASP.NET MVC路由场景,我希望能够解析我使用现有路由从“引用者”请求头中获取的URL。手动通过模型绑定器传递一个url来获取RouteData参数

我有像这样的传入请求:

http://hostname/{scope}/{controller}/{action} 

随着相应的路由映射:

routes.MapRoute( name: "scoped", url: "{scope}/{controller}/{action}/{id}", defaults: new { controller = "Equipment", action = "Index", id = UrlParameter.Optional, scope = "shared" } );

在基础类我的控制器的予拉所得scopeOnActionExecuting方法来自RouteData:

var scope= (filterContext.RouteData.Values["scope"] as string).ToLower(); 

然后我使用该范围为我的数据库查询构造一些过滤器。直到我将所有Json返回的方法移至单独的一组WebApi2控制器之前,它一切正常。我现在也有一个路线:

config.Routes.MapHttpRoute( 名: “DefaultApi”, routeTemplate: “API/{控制器}/{行动}” );

现在所有的ajax请求都发送到api控制器,这意味着我没有scope值可用。我想通过使用请求标题中的“引荐来源”网址来解决此问题,该请求标头通常是包含scope的网址。

我想什么做的是这样的事情,当ApiController初始化:

public void PullCurrentScopeDomainFromRequestHeader(System.Net.Http.Headers.HttpRequestHeaders headers) { 
    var refererUrl = headers.GetValues("Referer").First(); 

    //do some magic to get the scope 

} 

的困难在于,范围也可以有一个默认值(“共享”),如果一个网址,如“ http://hostname/controller/action“get的传入。从任何URL获取范围的最佳(和DRYest)方式将通过某种方式使用我在路由配置中映射的”范围“路由以某种方式解析URL。我只是不知道该怎么做。谁能帮忙?

您只需根据您的URL建立一个虚假的HTTP上下文,然后使用静态的RouteTable将URL解析为RouteValueDictionary

// Create a fake HttpContext using your URL 
var uri = new Uri("http://hostname/controller/action", UriKind.Absolute); 
var request = new HttpRequest(
    filename: string.Empty, 
    url: uri.ToString(), 
    queryString: string.IsNullOrEmpty(uri.Query) ? string.Empty : uri.Query.Substring(1)); 

// Create a TextWriter with null stream as a backing stream 
// which doesn't consume resources 
using (var nullWriter = new StreamWriter(Stream.Null)) 
{ 
    var response = new HttpResponse(nullWriter); 
    var httpContext = new HttpContext(request, response); 
    var fakeHttpContext = new HttpContextWrapper(httpContext); 

    // Use the RouteTable to parse the URL into RouteData 
    var routeData = RouteTable.Routes.GetRouteData(fakeHttpContext); 
    var values = routeData.Values; 

    // The values dictionary now contains the keys and values 
    // from the URL. 

    // Key   | Value 
    // 
    // controller | controller 
    // action  | action 
    // id   | {} 

} 

请注意,您也可以通过指定其名称使用RouteTable中的特定路线。

var routeData = RouteTable.Routes["scoped"].GetRouteData(fakeHttpContext); 
+0

谢谢,这真是太棒了! – jkokorian