简体   繁体   English

在T4模板中从MVC应用提取路由表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM