类属性列表

时间:2013-08-09 04:42:56

标签: asp.net-mvc linq lambda

我有一个带有一个视图模型类的ASP.NET MVC 4应用程序,以及代表此视图模型的大约20个视图。此视图仅与用户可以编辑的字段不同。我想将所有视图合并为一个,并以强类型方式定义可用于编辑的属性列表。理想情况下,我想要这样的事情:

// Action
public ActionResult EditAsEngineer(int id)
{
    //...
    viewModel.PropertiesToChange = new List<???>()
    {
        v => v.LotNumber,
        v => v.ShippingDate,
        v => v.Commentary
    };
    return View(viewModel);
}

// View
if (@Model.PropertiesToChange.Contains(v => v.LotNumber)
{
    @Html.TextBoxFor(m => m.LotNumber)
}
else
{
    @Model.LotNumber
}

有可能做这样的事吗?或者有更好的解决方案吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

为什么要注意这样的事情(其伪代码

public class Prop{
   string PropertyName {get;set;}
   bool PropertyEditable {get;set;}
}

public ActionResult EditAsEngineer(int id)
{
    viewModel.PropertiesToChange = new List<Prop>()
    {
        new Prop{PropertyName = LotNumber, PropertyEditable  = true}
    };
    return View(viewModel);
}

@foreach (var pin Model.PropertiesToChange)
{
   if(p.PropertyEditable){
      @Html.TextBoxFor(p)
   }else{
      @Html.DisplayFor(p)
   }
}

答案 1 :(得分:0)

这将解决您的问题的HALF。您还需要为您的代码创建一个IEqualityComparer<Expression>(默认设置是检查ref-equals)。

    return from p in typeof(T).GetProperties()
            let param = System.Linq.Expressions.Expression.Parameter(typeof(T), "x")
            let propExp = System.Linq.Expressions.Expression.Property(param, p)
            let cast = System.Linq.Expressions.Expression.Convert(propExp, typeof(object))
            let displayAttribute = p.CustomAttributes.OfType<System.ComponentModel.DataAnnotations.DisplayAttribute>()
                        .Select(x => x.Order).DefaultIfEmpty(int.MaxValue).FirstOrDefault()
            orderby displayAttribute
            select System.Linq.Expressions.Expression.Lambda<Func<T, object>>(cast, new [] {param});

这将列出T的所有属性。您也可能希望使用Expression<Func<T, object>>作为定义属性列表的类型。

这将允许您创建所有属性的通用视图。

此外,您还希望将其包装在某种缓存中,因为此代码为SLOW。