문제

ViewContext (예 : 컨트롤러에서)를 모르고 조치에서 URL을 얻을 수 있습니까? 이 같은:

LinkBuilder.BuildUrlFromExpression(ViewContext context, Expression<Action<T>> action)

...하지만 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;

"foo"및 "bar"를 실명으로 바꾸십시오. 이것은 내 머리 꼭대기에서 벗어나기 때문에 가능한 가장 효율적인 솔루션이라고 보장 할 수는 없지만 올바른 길을 가야합니다.

다른 팁

크레이그, 정답에 감사드립니다. 그것은 훌륭하게 작동하며, 또한 나에게 생각합니다. 따라서 Refactor 저항성 "Magic Strings"를 제거하기위한 드라이브에서는 솔루션의 변형을 개발했습니다.

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

나는 어떤 사람들이 무엇을 말할 것인지 알고 있습니다 ... 두려운 성찰! 내 특정 응용 분야에서 유지 보수의 이점은 성능의 코너보다 중요하다고 생각합니다. 이 아이디어와 코드에 대한 피드백을 환영합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top