InT*_*ons 5 c# asp.net-mvc lambda
我的 Html 帮助器方法如下所示
public static MvcHtmlString Control<TModel>(this MyHtmlHelper<TModel> helper,
string propertyName, LayoutHelper layout, TemplateType templateType = TemplateType.Screen)
{
//...
}
Run Code Online (Sandbox Code Playgroud)
我想将我的属性名称转换为以下内容
Expression<Func<TModel, string>> expression
Run Code Online (Sandbox Code Playgroud)
任何帮助都感激不尽
看起来你想打电话ModelMetadata.FromLambdaExpression,但不是FromStringExpression。您可以创建一个表达式,例如
x => x.PropertyName
Run Code Online (Sandbox Code Playgroud)
从头开始,像这样:
// Get a reference to the property
var propertyInfo = ExpressionHelper.GetPropertyInfo<TModel>(propertyName);
var model = ExpressionHelper.Parameter<TModel>();
// Build the LINQ expression tree backwards:
// x.Prop
var key = ExpressionHelper.GetPropertyExpression(model, propertyInfo);
// x => x.Prop
var keySelector = ExpressionHelper.GetLambda(typeof(TModel), propertyInfo.PropertyType, model, key);
Run Code Online (Sandbox Code Playgroud)
为了使代码更具可读性,表达式树的具体操作被移至此辅助类中:
public static class ExpressionHelper
{
private static readonly MethodInfo LambdaMethod = typeof(Expression)
.GetMethods()
.First(x => x.Name == "Lambda" && x.ContainsGenericParameters && x.GetParameters().Length == 2);
private static MethodInfo GetLambdaFuncBuilder(Type source, Type dest)
{
var predicateType = typeof(Func<,>).MakeGenericType(source, dest);
return LambdaMethod.MakeGenericMethod(predicateType);
}
public static PropertyInfo GetPropertyInfo<T>(string name)
=> typeof(T).GetProperties()
.Single(p => p.Name == name);
public static ParameterExpression Parameter<T>()
=> Expression.Parameter(typeof(T));
public static MemberExpression GetPropertyExpression(ParameterExpression obj, PropertyInfo property)
=> Expression.Property(obj, property);
public static LambdaExpression GetLambda<TSource, TDest>(ParameterExpression obj, Expression arg)
=> GetLambda(typeof(TSource), typeof(TDest), obj, arg);
public static LambdaExpression GetLambda(Type source, Type dest, ParameterExpression obj, Expression arg)
{
var lambdaBuilder = GetLambdaFuncBuilder(source, dest);
return (LambdaExpression)lambdaBuilder.Invoke(null, new object[] { arg, new[] { obj } });
}
}
Run Code Online (Sandbox Code Playgroud)
从头开始构建表达式树可以让您在创建 lambda 表达式时获得最大的灵活性。根据目标属性类型,它可能并不总是 an Expression<Func<TModel, string>>- 最后一个类型可能是 anint或其他类型。无论目标属性类型如何,此代码都将构建正确的表达式树。
参考以下内容供参考
Expression<Func<TModel, string>> GetPropertyExpression<TModel>(string propertyName) {
// Manually build the expression tree for
// the lambda expression model => model.PropertyName.
var parameter = Expression.Parameter(typeof(TModel), "model");
var property = Expression.Property(parameter, propertyName);
var expression = Expression.Lambda<Func<TModel, string>>(property, parameter);
return expression;
}
Run Code Online (Sandbox Code Playgroud)
这将允许您导出助手中的表达式
public static MvcHtmlString Control<TModel>(this MyHtmlHelper<TModel> helper, string propertyName,
LayoutHelper layout, TemplateType templateType = TemplateType.Screen) {
Expression<Func<TModel, string>> expression = GetPropertyExpression<TModel>(propertyName);
var propertyMetadata = ModelMetadata.FromStringExpression(expression, helper.Html.ViewData);
//...other code...
}
Run Code Online (Sandbox Code Playgroud)