[英]Extracting route table from MVC app in T4 template
Does anyone have any ideas on how I might extract the route table from a MVC app in a T4 template ? 有人对我如何从T4模板中的MVC应用程序提取路由表有任何想法吗?
Ideally what Id like to do is create an instance of the 'MvcApplication : System.Web.HttpApplication' and get it to 'startup' so the routes are registered and I can just extract them from Routes.RouteTable. 理想情况下,Id要做的是创建'MvcApplication:System.Web.HttpApplication'的实例并将其转到'startup',以便路由被注册,我可以从Routes.RouteTable中提取它们。
Failing that, I thought about using reflection to find static classes with methods that follow the Register[xxxx]Route naming convention. 失败了,我想到了使用反射来遵循符合Register [xxxx] Route命名约定的方法来查找静态类。 Would work in a lot of cases. 在很多情况下都会起作用。
Any other suggestions I might have missed ? 我可能还错过了其他建议吗?
Edit - seems to be some confusion over the question. 编辑-似乎对这个问题有些困惑。 I know that T4 runs at design time. 我知道T4在设计时运行。 I know that routes are registered at runtime. 我知道路由是在运行时注册的。 This guy did something similar to what im looking to do - extract roues at design time but he forces you to register routes in a particular way so he can use reflection to read them back out. 这个人所做的事情与我想做的事情类似–在设计时提取路线,但他强迫您以特定方式注册路线,以便他可以使用反射将其读出。 Wanted to avoid that if at all possible. 希望尽可能避免这种情况。
You can use library Microsoft.Web.Mvc in MVC futures that has method 您可以在具有方法的MVC期货中使用库Microsoft.Web.Mvc
ExpressionHelper.GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action)
It give you what you want. 它给你你想要的。
Update: it can work without Asp.Net MVC but you need to copy realization of Microsoft.Web.Mvc.Internal.ExpressionHelper to your own class and remove restriction where TController:Controller
from signature of GetRouteValuesFromExpression method: 更新:它可以在没有Asp.Net MVC的情况下工作,但是您需要将Microsoft.Web.Mvc.Internal.ExpressionHelper的实现复制到您自己的类中,并从GetRouteValuesFromExpression方法的签名中删除where TController:Controller
限制:
public static class MyOwnExpressionHelper
{
public static RouteValueDictionary GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action) //where TController : Controller
{
if (action == null)
throw new ArgumentNullException("action");
MethodCallExpression call = action.Body as MethodCallExpression;
if (call == null)
throw new ArgumentException("MustBeMethodCall", "action");
string name = typeof(TController).Name;
if (!name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("TargetMustEndInController", "action");
string str = name.Substring(0, name.Length - "Controller".Length);
if (str.Length == 0)
throw new ArgumentException("_CannotRouteToController", "action");
string targetActionName = GetTargetActionName(call.Method);
RouteValueDictionary rvd = new RouteValueDictionary();
rvd.Add("Controller", (object)str);
rvd.Add("Action", (object)targetActionName);
ActionLinkAreaAttribute linkAreaAttribute = Enumerable.FirstOrDefault<object>((IEnumerable<object>)typeof(TController).GetCustomAttributes(typeof(ActionLinkAreaAttribute), true)) as ActionLinkAreaAttribute;
if (linkAreaAttribute != null)
{
string area = linkAreaAttribute.Area;
rvd.Add("Area", (object)area);
}
AddParameterValuesFromExpressionToDictionary(rvd, call);
return rvd;
}
public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
{
if (expression.Body.NodeType == ExpressionType.Call)
return GetInputName((MethodCallExpression)expression.Body).Substring(expression.Parameters[0].Name.Length + 1);
else
return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
}
private static string GetInputName(MethodCallExpression expression)
{
MethodCallExpression expression1 = expression.Object as MethodCallExpression;
if (expression1 != null)
return MyOwnExpressionHelper.GetInputName(expression1);
else
return expression.Object.ToString();
}
private static string GetTargetActionName(MethodInfo methodInfo)
{
string name = methodInfo.Name;
if (methodInfo.IsDefined(typeof(NonActionAttribute), true))
{
throw new InvalidOperationException(string.Format((IFormatProvider)CultureInfo.CurrentCulture,"An Error", new object[1]
{
(object) name
}));
}
else
{
ActionNameAttribute actionNameAttribute = Enumerable.FirstOrDefault<ActionNameAttribute>(Enumerable.OfType<ActionNameAttribute>((IEnumerable)methodInfo.GetCustomAttributes(typeof(ActionNameAttribute), true)));
if (actionNameAttribute != null)
return actionNameAttribute.Name;
if (methodInfo.DeclaringType.IsSubclassOf(typeof(AsyncController)))
{
if (name.EndsWith("Async", StringComparison.OrdinalIgnoreCase))
return name.Substring(0, name.Length - "Async".Length);
if (name.EndsWith("Completed", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException(string.Format((IFormatProvider)CultureInfo.CurrentCulture, "CannotCallCompletedMethod", new object[1]
{
(object) name
}));
}
return name;
}
}
private static void AddParameterValuesFromExpressionToDictionary(RouteValueDictionary rvd, MethodCallExpression call)
{
ParameterInfo[] parameters = call.Method.GetParameters();
if (parameters.Length <= 0)
return;
for (int index = 0; index < parameters.Length; ++index)
{
Expression expression = call.Arguments[index];
ConstantExpression constantExpression = expression as ConstantExpression;
object obj = constantExpression == null ? CachedExpressionCompiler.Evaluate(expression) : constantExpression.Value;
rvd.Add(parameters[index].Name, obj);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.