URL格式动作,而不ViewContext
-
21-08-2019 - |
题
时有可能得到从动作的URL而不知道ViewContext(例如,在一个控制器)?是这样的:
LinkBuilder.BuildUrlFromExpression(ViewContext context, Expression<Action<T>> action)
...但使用Controller.RouteData代替ViewContext。我似乎对这种金属块。
解决方案
下面是如何做到这一点在一个单元测试:
private string RouteValueDictionaryToUrl(RouteValueDictionary rvd)
{
var context = MvcMockHelpers.FakeHttpContext("~/");
// _routes is a RouteCollection
var vpd = _routes.GetVirtualPath(
new RequestContext(context, _
routes.GetRouteData(context)), rvd);
return vpd.VirtualPath;
}
每评论,我会适应控制器:
string path = RouteTable.Routes.GetVirtualPath(
new RequestContext(HttpContext,
RouteTable.Routes.GetRouteData(HttpContext)),
new RouteValueDictionary(
new { controller = "Foo",
action = "Bar" })).VirtualPath;
用真实姓名替换“富”与“酒吧”。这是把我的头顶部,所以我不能保证这是最有效的解决方案成为可能,但它应该让你在正确的轨道上。
其他提示
克雷格,感谢您的正确答案。它的伟大工程,而且还去我的思维。所以在我的驱动器,以消除那些重构性能稳定的“魔术字符串”我已经制定了解决方案的变化:
public static string GetUrlFor<T>(this HttpContextBase c, Expression<Func<T, object>> action)
where T : Controller
{
return RouteTable.Routes.GetVirtualPath(
new RequestContext(c, RouteTable.Routes.GetRouteData(c)),
GetRouteValuesFor(action)).VirtualPath;
}
public static RouteValueDictionary GetRouteValuesFor<T>(Expression<Func<T, object>> action)
where T : Controller
{
var methodCallExpresion = ((MethodCallExpression) action.Body);
var controllerTypeName = methodCallExpresion.Object.Type.Name;
var routeValues = new RouteValueDictionary(new
{
controller = controllerTypeName.Remove(controllerTypeName.LastIndexOf("Controller")),
action = methodCallExpresion.Method.Name
});
var methodParameters = methodCallExpresion.Method.GetParameters();
for (var i = 0; i < methodParameters.Length; i++)
{
var value = Expression.Lambda(methodCallExpresion.Arguments[i]).Compile().DynamicInvoke();
var name = methodParameters[i].Name;
routeValues.Add(name, value);
}
return routeValues;
}
我知道有些人会说......可怕的体现!在我的具体应用,我觉得可维护性远远超过性能值得关注的问题的好处。我欢迎这个想法和代码的任何反馈。
不隶属于 StackOverflow