您可以在具有方法的 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);
}
}
}