通过modelbinder手动传递一个url获取RouteData参数
Manually pass a url through the modelbinder to obtain the RouteData parameters
我有一个复杂的 ASP.NET MVC 路由场景,我希望能够使用现有的 'Referrer' 请求 header 解析 URL路线。
我有这样的传入请求:
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" }
);
在我的控制器的基础 class 的 OnActionExecuting
方法中,我从 RouteData:
中提取结果 scope
var scope= (filterContext.RouteData.Values["scope"] as string).ToLower();
然后我使用作用域为我的数据库查询构造一些过滤器。在我将所有 Json-returning 方法移至一组单独的 WebApi2 控制器之前,一切都运行良好。我现在也有一条路线:
config.Routes.MapHttpRoute(
姓名:"DefaultApi",
路线模板:"api/{controller}/{action}"
);
所有 ajax 请求现在都发送给 api 控制器,这意味着我没有可用的 scope
值。我想通过使用请求 header 中的 'Referrer' URL 来解决这个问题,这通常是一个 URL,它确实包含 scope
.
当 ApiController 初始化时,我想做的是这样的事情:
public void PullCurrentScopeDomainFromRequestHeader(System.Net.Http.Headers.HttpRequestHeaders headers) {
var refererUrl = headers.GetValues("Referer").First();
//do some magic to get the scope
}
困难在于范围也可以有一个默认值("shared"),以防传入一个像“http://hostname/controller/action”这样的url。最好的(和DRYest ) 从任何 URL 获取范围的方法是使用我在路由配置中映射的 "scoped" 路由以某种方式解析 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);
我有一个复杂的 ASP.NET MVC 路由场景,我希望能够使用现有的 'Referrer' 请求 header 解析 URL路线。
我有这样的传入请求:
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" }
);
在我的控制器的基础 class 的 OnActionExecuting
方法中,我从 RouteData:
scope
var scope= (filterContext.RouteData.Values["scope"] as string).ToLower();
然后我使用作用域为我的数据库查询构造一些过滤器。在我将所有 Json-returning 方法移至一组单独的 WebApi2 控制器之前,一切都运行良好。我现在也有一条路线:
config.Routes.MapHttpRoute( 姓名:"DefaultApi", 路线模板:"api/{controller}/{action}" );
所有 ajax 请求现在都发送给 api 控制器,这意味着我没有可用的 scope
值。我想通过使用请求 header 中的 'Referrer' URL 来解决这个问题,这通常是一个 URL,它确实包含 scope
.
当 ApiController 初始化时,我想做的是这样的事情:
public void PullCurrentScopeDomainFromRequestHeader(System.Net.Http.Headers.HttpRequestHeaders headers) {
var refererUrl = headers.GetValues("Referer").First();
//do some magic to get the scope
}
困难在于范围也可以有一个默认值("shared"),以防传入一个像“http://hostname/controller/action”这样的url。最好的(和DRYest ) 从任何 URL 获取范围的方法是使用我在路由配置中映射的 "scoped" 路由以某种方式解析 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);