0

我有一个 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
}

有可能做这样的事情吗?还是有更好的解决方案?

谢谢你。

4

2 回答 2

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)
   }
}
于 2013-08-09T07:21:12.827 回答
0

这将解决您一半的问题。您还需要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>>其用作定义属性列表的类型。

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

此外,您还需要将其包装在某种缓存中,因为此代码很慢。

于 2013-08-16T02:06:56.070 回答