通过modelbinder手动传递url以获取RouteData参数 [英] Manually pass a url through the modelbinder to obtain the RouteData parameters

查看:104
本文介绍了通过modelbinder手动传递url以获取RouteData参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个复杂的ASP.NET MVC路由方案,我希望能够使用现有路由来解析从"Referrer"请求标头中提取的URL.

I have a complex ASP.NET MVC routing scenario and I want to be able to parse a URL that I pull from the 'Referrer' request header using the existing routes.

我收到的传入请求看起来像这样:

I have incoming requests that look like this:

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

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

在我的控制器基类的OnActionExecuting方法中,我从RouteData中拉出结果scope:

In the OnActionExecuting method of the base class of my controllers I pull the resulting scope from the RouteData:

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

然后,我使用作用域为我的数据库查询构造一些过滤器.在我将所有返回Json的方法移至另一套WebApi2控制器之前,一切工作都很好.我现在也有一条路线:

I then use the scope to construct some filters for my database queries. It all worked perfectly fine until I moved all my Json-returning methods to a separate set of WebApi2 controllers. I now also have a route:

config.Routes.MapHttpRoute( 名称:"DefaultApi", routeTemplate:"api/{controller}/{action}" );

config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}" );

现在所有的ajax请求都向api控制器发出,这意味着我没有可用的scope值.我想通过使用请求标头中的"Referrer" URL来解决此问题,该URL通常是确实包含scope的URL.

All ajax requests are now made to the api controllers, which means that I do not have the scope value available. I want to solve this by using the 'Referrer' URL from the request header, which is is usually a URL that does include the scope.

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

What I would like to do is something like this when the ApiController initializes:

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

    //do some magic to get the scope

}

困难之处在于,如果诸如" http之类的url,则范围还可以具有默认值(共享").//hostname/controller/action " get.传入任何URL的最佳(和DRYest)方法都是通过某种方式使用我在路由配置中映射的作用域"路由进行解析网址.我只是不知道该怎么做.有人可以帮忙吗?

The difficulty is that the scope can also have a default value ("shared"), in case a url like "http://hostname/controller/action" get's passed in. The best (and DRYest) way to get the scope from any URL, would be by somehow using the "scoped" route that I mapped in the routing config to parse the URL somehow. I just have no idea how to do that. Can anyone help?

推荐答案

您只需要根据您的URL构建一个伪造的HTTP上下文,然后使用静态RouteTable将URL解析为RouteValueDictionary./p>

You just need to build up a fake HTTP context based on your URL and then use the static RouteTable to parse the URL into a 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的名称来使用它的特定路由.

Note that you can also use a specific route from the RouteTable by specifying its name.

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

这篇关于通过modelbinder手动传递url以获取RouteData参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆