我有一个剃刀助手来渲染树视图下拉列表。我试图制作类似于DropDownFor
助手,以便在视图中轻松熟悉地使用。是否有解析通过表达式提供的模型属性的值,而不是DataBinder.Eval()
?
以前我可以通过使用PropertyInfo.GetValue
方法解决问题,但它在检索属性的值时遇到问题,该属性是我使用索引器进行预测的集合:model => model.SettingsModel.Categories[i].CategoryKey
public static ITreeViewDropdown<ITreeViewItem> TreeDropDownFor<TModel, TProperty, ITreeViewItem>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<ITreeViewModel<ITreeViewItem>> tree,
string optionLabel,
object htmlAttributes = null)
{
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
TModel model = (TModel)html.ViewContext.ViewData.ModelMetadata.Model;
var memberExpr = expression.Body as MemberExpression;
if (memberExpr == null)
{
throw new ArgumentException($"Expected body of type '{typeof(MemberExpression).Name}' but received '{expression.Body.GetType().Name}'", nameof(expression));
}
MemberInfo propertyMember = memberExpr.Member;
string propertyName = ExpressionHelper.GetExpressionText(expression);
if (propertyMember.MemberType != MemberTypes.Property)
{
throw new MemberAccessException($"{propertyName} must be a property");
}
// An alternative is needed here
var propertyValue = DataBinder.Eval(model, propertyName);
return new TreeViewDropdown<ITreeViewItem>(html, tree, propertyName, propertyValue, optionLabel, htmlAttributes);
}
上述解决方案目前适合我的需求:
@Html.TreeViewDropdownFor(m => m.SettingsModel.Categories[i].CategoryKey, Model.CategoryTree, "Please Select")
但我read认为Eval()方法可能很慢,我想以'正确'的方式做到这一点,我想不出如何获得SettingsModel.Categories[i].CategoryKey
的价值。如果提供的表达式更简单,例如,我可以轻松获得我需要的值。
m = > m.ProjectViewModel.CategoryKey
,但没有收藏和索引器。
expression.Compile().Invoke(model)
实际上得到了正确的价值。考虑到这些类型是通用的,我认为它不会比这更好