我有一个带有一个视图模型类的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
}
有可能做这样的事吗?或者有更好的解决方案吗?
谢谢。
答案 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。