Я знаю, что это не дает прямого ответа на ваш вопрос, но есть ли причина, по которой вы пытаетесь написать свой собственный общий метод расширения, а не тот, который доступен в сборке MVC Futures? (Microsoft.Web.Mvc.dll) Или вы на самом деле пытаетесь провести модульное тестирование метода расширения msft?
[Редактировать 1]
Извините, я думал о вспомогательном расширении Html в Futures.
А пока я попробую свои силы на модульном тесте, чтобы увидеть, получу ли я такой же результат.
[Редактировать 2]
Хорошо, так что это еще не совсем работает, но это не взрывается. Результат просто возвращает пустую строку. Я взял несколько помощников насмешников по Mvc у Скотта Хансельмана по этой ссылке 1010 *
Я также создал Url.Action<TController>
метод вместе с вспомогательными методами, которые я скопировал из источника Mvc:
public static string Action<TController>(this UrlHelper helper, Expression<Action<TController>> action) where TController : Controller
{
string result = BuildUrlFromExpression<TController>(helper.RequestContext, helper.RouteCollection, action);
return result;
}
public static string BuildUrlFromExpression<TController>(RequestContext context, RouteCollection routeCollection, Expression<Action<TController>> action) where TController : Controller
{
RouteValueDictionary routeValuesFromExpression = GetRouteValuesFromExpression<TController>(action);
VirtualPathData virtualPath = routeCollection.GetVirtualPath(context, routeValuesFromExpression);
if (virtualPath != null)
{
return virtualPath.VirtualPath;
}
return null;
}
public static RouteValueDictionary GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action) where TController : Controller
{
if (action == null)
{
throw new ArgumentNullException("action");
}
MethodCallExpression body = action.Body as MethodCallExpression;
if (body == null)
{
throw new ArgumentException("MvcResources.ExpressionHelper_MustBeMethodCall", "action");
}
string name = typeof(TController).Name;
if (!name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("MvcResources.ExpressionHelper_TargetMustEndInController", "action");
}
name = name.Substring(0, name.Length - "Controller".Length);
if (name.Length == 0)
{
throw new ArgumentException("MvcResources.ExpressionHelper_CannotRouteToController", "action");
}
RouteValueDictionary rvd = new RouteValueDictionary();
rvd.Add("Controller", name);
rvd.Add("Action", body.Method.Name);
AddParameterValuesFromExpressionToDictionary(rvd, body);
return rvd;
}
private static void AddParameterValuesFromExpressionToDictionary(RouteValueDictionary rvd, MethodCallExpression call)
{
ParameterInfo[] parameters = call.Method.GetParameters();
if (parameters.Length > 0)
{
for (int i = 0; i < parameters.Length; i++)
{
Expression expression = call.Arguments[i];
object obj2 = null;
ConstantExpression expression2 = expression as ConstantExpression;
if (expression2 != null)
{
obj2 = expression2.Value;
}
else
{
Expression<Func<object>> expression3 = Expression.Lambda<Func<object>>(Expression.Convert(expression, typeof(object)), new ParameterExpression[0]);
obj2 = expression3.Compile()();
}
rvd.Add(parameters[i].Name, obj2);
}
}
}
И, наконец, вот мой тест:
[Test]
public void GenericActionLinkHelperTest()
{
RouteRegistrar.RegisterRoutesTo(RouteTable.Routes);
var mocks = new MockRepository();
var context = mocks.FakeHttpContext(); // the extension from hanselman
var helper = new UrlHelper(new RequestContext(context, new RouteData()), RouteTable.Routes);
string result = helper.Action<ProjectsController>(x => x.Index());
// currently outputs an empty string, so something is fudded up.
Console.WriteLine(result);
}
Пока не уверен, почему вывод - пустая строка, но я буду продолжать возиться с этим, так как у меня будет время. Мне было бы интересно узнать, если вы найдете решение в то же время.