我的一个页面有一个相当复杂的模型;它由几个嵌套的模型对象组成。在一个使用带有子集合的子对象的部分中,我EditorFor
像这样使用帮助器:
@Html.EditorFor(m => m.CAS.LERoles[i].LE, "TinyText")
,我最终会得到类似的东西:
<input id="CAS_LERoles_0__LE" class="tinyText" type="text" value="0" name="CAS.LERoles[0].LE" data-val-required="The Legal Entity field is required." data-val-number="The field Legal Entity must be a number." data-val="true">
... 这很棒。但是,我编写了自己的助手来将枚举转换为选择列表,如下所示:
public static HtmlString EnumSelectListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> forExpression,
object htmlAttributes,
bool blankFirstLine)
where TModel : class
where TProperty : struct
{
//MS, it its infinite wisdom, does not allow enums as a generic constraint, so we have to check here.
if (!typeof(TProperty).IsEnum) throw new ArgumentException("This helper method requires the specified model property to be an enum type.");
//initialize values
var metaData = ModelMetadata.FromLambdaExpression(forExpression, htmlHelper.ViewData);
var propertyName = metaData.PropertyName;
var propertyValue = htmlHelper.ViewData.Eval(propertyName).ToStringOrEmpty();
//build the select tag
var returnText = string.Format("<select id=\"{0}\" name=\"{0}\"", HttpUtility.HtmlEncode(propertyName));
if (htmlAttributes != null)
{
foreach (var kvp in htmlAttributes.GetType().GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
{
returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
}
}
returnText += ">\n";
if (blankFirstLine)
{
returnText += "<option value=\"\"></option>";
}
//build the options tags
foreach (var enumName in Enum.GetNames(typeof(TProperty)))
{
var idValue = ((int)Enum.Parse(typeof(TProperty), enumName, true)).ToString();
var displayValue = enumName;
// get the corresponding enum field using reflection
var field = typeof(TProperty).GetField(enumName);
var display = ((DisplayAttribute[])field.GetCustomAttributes(typeof(DisplayAttribute), false)).FirstOrDefault();
var titleValue = string.Empty;
if (display != null)
{
// The enum field is decorated with the DisplayAttribute =>
// use its value
displayValue = display.Name;
titleValue = display.Description.ToStringOrEmpty();
}
returnText += string.Format("\t<option value=\"{0}\" title=\"{1}\"",
HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
if (enumName == propertyValue)
{
returnText += " selected=\"selected\"";
}
returnText += string.Format(">{0}</option>\n", HttpUtility.HtmlEncode(displayValue));
}
//close the select tag
returnText += "</select>\n";
return new HtmlString(returnText);
}
当我像这样在我的页面中使用它时:
@Html.EnumSelectListFor(m => m.CAS.LERoles[i].APMasterRole)
我最终得到了这个:
<select name="APMasterRole" id="APMasterRole">
(stuff)
</select>
回想起来,我想我认为这会被恰当地翻译,现在我意识到我有点天真。我真的希望 MVC 框架中内置了一种机制,我可以使用它来生成正确的名称和 id;否则这看起来像一个反射的迷宫。
所以问题是,是否有一种机制可以为这样的复杂模型对象创建名称和 ID 字符串?如果是这样,它将如何使用?如果没有,有没有比较简单的方法来生成name和id,从而可以将表单数据绑定回对象模型?
谢谢!