سؤال

هل من الممكن الحصول على 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;
}

وأنا أعرف ما سيقول البعض ... انعكاس اللعين! في التطبيق الخاص بي معين، وأعتقد أن مصلحة الصيانة تفوق conerns الأداء. I نرحب بأي ملاحظات حول هذه الفكرة والرمز.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top