Я собираюсь вырвать те мелкие волосы, которые у меня остались - я изучал MVC в течение последних нескольких месяцев, так что я относительно новичок в этом, хотя я прошел большую часть работы ...
У меня возникают проблемы при попытке вывести флажки и переключатели с относительно сложной моделью представления.
У меня есть следующее представление (ненужные поля удалены):
@model CreateMediumModel
@using(Html.BeginForm()) {
<div class="formField">
<div class="label">
@Html.LabelFor(m => m.MetaData)
</div>
<div class="input">
@Html.EditorFor(m => m.MetaData)
</div>
@Html.ValidationMessageFor(m => m.MetaData)
</div>
}
Модель иерархического представления выглядит следующим образом:
public class CreateMediumModel {
public List<MetaData> MetaData { get; set; }
}
public class MetaData {
/// <summary>
/// The media type that this meta data belongs to.
/// </summary>
public int MediaTypeID { get; set; }
/// <summary>
/// The unique ID for the meta data.
/// </summary>
public int MetaDataID { get; set; }
/// <summary>
/// The unique text-based identifier for the meta data. Unique per MediaType.
/// </summary>
public string Key { get; set; }
/// <summary>
/// The UI description of the meta data.
/// </summary>
public string Description { get; set; }
/// <summary>
/// The max length of text based data.
/// </summary>
public int Length { get; set; }
/// <summary>
/// Provides a pre-defined list of values for the meta data.
/// </summary>
public List<MetaDataOption> Options { get; set; }
/// <summary>
/// Provides the text-based value for the meta data.
/// </summary>
public string Value { get; set; }
/// <summary>
/// Determines which value/s to use from the object graph
/// </summary>
public MetaDataDataType Type { get; set; }
/// <summary>
/// Defines the UI sort order of the meta data
/// </summary>
public int SortOrder { get; set; }
}
public class MetaDataDataType {
public int MetaDataTypeID { get; set; }
public MetaDataDataTypeEnum Type { get; set; }
public bool TextBased { get; set; }
}
public class MetaDataOption {
/// <summary>
/// The unique ID for the option
/// </summary>
public int MetaDataOptionID { get; set; }
/// <summary>
/// The pre-defined option value to display.
/// </summary>
public string Value { get; set; }
/// <summary>
/// The sort order of the value in the list.
/// </summary>
public int SortOrder { get; set; }
}
public enum MetaDataEnum {
Developer,
PEGI,
PEGIContent
}
public enum MetaDataDataTypeEnum {
/// <summary>
/// Simple text
/// </summary>
TEXT = 1,
/// <summary>
/// Multi-line text.
/// </summary>
MULTITEXT = 2,
/// <summary>
/// Simple number
/// </summary>
NUMBER = 3,
/// <summary>
/// Simple date
/// </summary>
DATE = 4,
/// <summary>
/// Simple time
/// </summary>
TIME = 5,
/// <summary>
/// Simple DateTime
/// </summary>
DATETIME = 6,
/// <summary>
/// Single option selection
/// </summary>
SELECTION = 7,
/// <summary>
/// Multi option selection
/// </summary>
MULTISELECTION = 8
}
Каждый фрагмент метаданных имеет один тип;тип определяет, как метаданные редактируются и как они отображаются (и где данные хранятся в слое данных).На стороне дисплея все работает отлично.
Когда тип «ВЫБОР», я хочу отобразить один набор переключателей, где можно выбрать только одну.Когда тип "MULTISELECTION", я хочу отобразить набор флажков, где можно выбрать более одного.Я могу это сделать, но мне удалось успешно привязать выбранные значения к модели.
В данный момент я использую шаблон редактора для отображения списка, который выглядит следующим образом:
@model MetaData
@using Business.Enumerations
@if(Model != null) {
@Html.HiddenFor(m => m.MetaDataID)
<div class="metaData@(Model.MediaTypeID) checkbox">
<div class="metaDescription">
@Model.Description
</div>
<div class="metaValue">
@switch(Model.Type.Type) {
case MetaDataDataTypeEnum.NUMBER:
case MetaDataDataTypeEnum.DATE:
case MetaDataDataTypeEnum.TEXT:
case MetaDataDataTypeEnum.TIME:
case MetaDataDataTypeEnum.DATETIME:
@Html.TextBoxFor(m => m.Value)
break;
case MetaDataDataTypeEnum.MULTITEXT:
@Html.TextAreaFor(m => m.Value)
break;
case MetaDataDataTypeEnum.SELECTION:
foreach(var o in Model.Options) {
@Html.RadioButtonFor(m => m.Value, o.MetaDataOptionID) @o.Value
}
break;
case MetaDataDataTypeEnum.MULTISELECTION:
foreach(var o in Model.Options) {
@Html.CheckBoxFor(m => m.Options.FirstOrDefault(opt => opt.Selected).Selected) @o.Value
}
break;
}
</div>
</div>
}
Это будет расширено, когда я преодолею эту проблему, но сейчас она выводит все как положено - я вижу список переключателей для типов SELECTION и список флажков для типов MULTISELECTION, но он не привязан кмодель правильно, когда я вызываю действие отправки.
Я немного схожу с ума.Может ли кто-нибудь увидеть что-то очевидное, что я делаю неправильно?
В качестве отступления:
Я также пытался создать шаблон редактора для класса MetaDataOption, но, похоже, существует ошибка, связанная спередача списка в шаблон подредактора, когда указано имя шаблона (Html.EditorFor (m => m.Options, "MetaDataOptionsSingle") и Html.EditorFor (m => m.Options, "MetaDataOptionsMulti")) -если я не указываю имя для шаблона редактора, шаблон может иметь модель MetaDataOption, но если указать имя, ему требуется список.
ОБНОВЛЕНИЕ
Хорошо, мне удалось заставить это работать, но сейчас у меня проблемы с ненавязчивой проверкой флажков.Исправление заключается в следующем:
Шаблон редактора MetaData теперь выглядит следующим образом:
@model MetaData
@using Business.Enumerations
@if(Model != null) {
@Html.HiddenFor(m => m.Description)
@Html.HiddenFor(m => m.Type)
<div class="metaData@(Model.MediaTypeID) checkbox">
<div class="metaDescription">
@Model.Description
</div>
<div class="metaValue">
@switch (Model.Type) {
case MetaDataDataTypeEnum.NUMBER:
case MetaDataDataTypeEnum.DATE:
case MetaDataDataTypeEnum.TEXT:
case MetaDataDataTypeEnum.TIME:
case MetaDataDataTypeEnum.DATETIME:
@Html.TextBoxFor(m => m.Value)
break;
case MetaDataDataTypeEnum.MULTITEXT:
@Html.TextAreaFor(m => m.Value)
break;
case MetaDataDataTypeEnum.SELECTION:
if(Model.Options != null) {
foreach (var o in Model.Options) {
@Html.RadioButtonFor(m => Model.SelectedMetaDataOptionID, o.MetaDataOptionID)
@o.Value
}
}
break;
case MetaDataDataTypeEnum.MULTISELECTION:
@Html.EditorFor(m => m.Options)
break;
}
</div>
</div>
}
Я добавил еще один шаблон Editor для шаблона MULTISELECTION Editor:
@model MetaDataOption
@if(Model != null) {
@Html.HiddenFor(m => m.MetaDataOptionID)
@Html.CheckBoxFor(m => m.Selected)
@Model.Value
}
ИКласс MetaDataOption выглядит следующим образом:
public class MetaDataOption {
/// <summary>
/// The unique ID for the option
/// </summary>
public int MetaDataOptionID { get; set; }
/// <summary>
/// The pre-defined option value to display.
/// </summary>
public string Value { get; set; }
/// <summary>
/// The sort order of the value in the list.
/// </summary>
public int SortOrder { get; set; }
}
Модель теперь заполняется правильно при отправке.Однако проверка выполняется во ВСЕХ флажках, отображаемых шаблоном редактора (в методе post-action, поскольку я еще не реализовал проверку клиента), однако аннотации данных для члена «Выбранный» класса MetaDataOption отсутствуют.
На что обратить внимание - член «Опции» класса MetaData имеет значение NULL, если не выбраны никакие флажки.
Я попытался установить для свойства Selected значение nollable bool (bool?), Но я запускаюиз-за проблем с помощником CheckBoxFor () в шаблоне редактора MetaDataOption, который не принимает обнуляемый bool.
Это сводит меня с ума ... Я потратил два дня, пытаясь заставить что-то работатьпросвистил с ASP.Net!