У меня довольно сложная модель для одной из моих страниц; он состоит из нескольких вложенных объектов модели. В одной секции, которая использует дочерний объект с коллекцией детской, я использую EditorFor
помощника, как так:MVC3: предоставление помощнику информации о местоположении объекта модели на графике
@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; иначе это выглядит как лабиринт отражения.
Итак, вопрос в том, существует ли механизм для создания имен и строк идентификаторов для сложного объекта модели, подобного этому? Если да, то как он будет использоваться? Если нет, существует ли относительно простой способ сгенерировать имя и идентификатор, чтобы данные формы могли быть привязаны к объектной модели?
Спасибо!
... Я думаю, что вы просто шутите о чтении исходного кода MVC Framework ... Надеюсь, вы. «TagBuilder» - это то, что я буду исследовать, хотя в моей защите все, что нужно закодировать, кодируется. Учитывая практические ограничения размера на поле выбора, я не думаю, что операции '+ =' обязательно являются большой проблемой, но да, это может быть лучше. –
Нет, конечно, я не шучу о чтении исходного кода. Я даже не представляю, как люди могут разрабатывать продвинутые приложения с некоторыми рамками, не зная, как эта структура строится и работает. Я согласен с тем, что вы кодируете все, но почему вы должны делать это вручную? Зачем изобретать колеса, когда есть уже существующие механизмы, встроенные в рамки, которые помогают вам в этом аспекте? –
Честно говоря, я не знал, что есть такие механизмы, которые являются причиной этого вопроса. Я всегда ищу способы улучшить свой код, но чтение исходного кода фреймворка ... кажется немного сложным. –