2

T4テンプレートのMVCアプリからルートテーブルを抽出する方法について誰かがアイデアを持っていますか?

理想的には、「MvcApplication:System.Web.HttpApplication」のインスタンスを作成し、それを「startup」にして、ルートが登録され、Routes.RouteTableから抽出できるようにするのが理想的です。

それができなかったので、Reflectionを使用して、Register[xxxx]Routeの命名規則に従うメソッドを持つ静的クラスを見つけることを考えました。多くの場合に機能します。

私が見逃したかもしれない他の提案はありますか?

編集-質問について混乱しているようです。T4は設計時に実行されることを私は知っています。ルートは実行時に登録されることを知っています。このは、imがやろうとしていることと似たようなことをしました。設計時にルートを抽出しますが、リフレクションを使用してルートを読み戻すことができるように、特定の方法でルートを登録するように強制します。可能な限りそれを避けたかった。

4

1 に答える 1

1

メソッドを持つMVC先物でライブラリMicrosoft.Web.Mvcを使用できます

ExpressionHelper.GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action)

それはあなたが望むものをあなたに与えます。

更新:Asp.Net MVCがなくても機能しますが、Microsoft.Web.Mvc.Internal.ExpressionHelperの実現を独自のクラスにコピーしwhere TController:Controller、GetRouteValuesFromExpressionメソッドの署名から制限を削除する必要があります。

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);
        }
    }
}
于 2012-09-01T18:20:44.203 に答える