Связывание сложных типов в MVC5

Я новичок-разработчик, пытающийся разработать веб-приложение с asp .net mvc 5 для личного использования. Сайт вроде викторины, в которую я могу вставить русские слова со значениями и подготовить викторину, используя эти слова.

Когда я пытался закодировать страницу викторины и опубликовать данные методом действия, я столкнулся с проблемой, которую не мог обойти. Я перебрал модель, прочитал данные и записал их на страницу. Теперь, что я хочу сделать, когда я отправляю форму, я хочу получить каждую строку вопроса и выбранный ответ (возможно, в этом формате: imgur.com/QETnafx). Поэтому я легко могу проверить строку ответа, верна она или нет.

Я ознакомился со следующими руководствами: «Привязка модели к списку» Фила Хаака и «Проводной формат ASP.NET для привязки модели к массивам, спискам, коллекциям, словарям» Скотта Хансельмана.

Надеюсь понятно объяснил ситуацию. Если вам нужна дополнительная информация, я могу с радостью предоставить.

Модель представления

public class QuizInitializationModel
{
    public List<Question> Questions { get; set; }
}

public class QuestionString
{
    public int Id { get; set; }
    public string WordString { get; set; }
}

public class Question
{
    public QuestionString QuestionString { get; set; }
    public List<AnswerItem> Answers { get; set; }
}

public class AnswerItem
{
    public int Id { get; set; }
    public string WordString { get; set; }
}

ПОСМОТРЕТЬ

        @using (Html.BeginForm("Begin", "Quiz", FormMethod.Post))
    {
        <table class="table table-striped table-condensed table-bordered">
            @for (int i = 0; i < Model.Questions.Count; i++)
            {
                <tr>
                    <td>
                        @Html.Label(Model.Questions[i].QuestionString.WordString)
                    </td>
                    <td>
                        @for (int item = 0; item < Model.Questions[0].Answers.Count; item++)
                        {
                            @Html.Label(Model.Questions[i].Answers[item].WordString)@:&nbsp;
                            @Html.RadioButton("array" + "[" + @i + "]" + "." + Model.Questions[i].QuestionString.WordString, Model.Questions[i].Answers[item].Id)<br />
                        }
                    </td>
                </tr>
            }
        </table>
        <input type="submit" value="Send" class="btn btn-primary" />
    }

ВЫВОД

<form action="/Admin/Quiz/Begin" method="post">
<table class="table table-striped table-condensed table-bordered">
    <tr>
        <td>
            <label for="">вулкан</label>
        </td>
        <td>
            <label for="trade">trade</label>&nbsp;
            <input id="array_0________" name="array[0].вулкан" type="radio" value="18" /><br />
            <label for="volcano">volcano</label>&nbsp;
            <input id="array_0________" name="array[0].вулкан" type="radio" value="24" /><br />
            <label for="talk__conversation">talk, conversation</label>&nbsp;
            <input id="array_0________" name="array[0].вулкан" type="radio" value="15" /><br />
            <label for="time">time</label>&nbsp;
            <input id="array_0________" name="array[0].вулкан" type="radio" value="13" /><br />
            <label for="income">income</label>&nbsp;
            <input id="array_0________" name="array[0].вулкан" type="radio" value="21" /><br />
        </td>
    </tr>
    <tr>
        <td>
            <label for="">мама</label>
        </td>
        <td>
            <label for="universe">universe</label>&nbsp;
            <input id="array_1______" name="array[1].мама" type="radio" value="25" /><br />
            <label for="peace">peace</label>&nbsp;
            <input id="array_1______" name="array[1].мама" type="radio" value="2" /><br />
            <label for="value">value</label>&nbsp;
            <input id="array_1______" name="array[1].мама" type="radio" value="20" /><br />
            <label for="mom__mama">mom, mama</label>&nbsp;
            <input id="array_1______" name="array[1].мама" type="radio" value="17" /><br />
            <label for="industry">industry</label>&nbsp;
            <input id="array_1______" name="array[1].мама" type="radio" value="19" /><br />
        </td>
    </tr>
</table>

И как я могу исправить идентификаторы меток типа «массив

public class QuizInitializationModel
{
    public List<Question> Questions { get; set; }
}

public class QuestionString
{
    public int Id { get; set; }
    public string WordString { get; set; }
}

public class Question
{
    public QuestionString QuestionString { get; set; }
    public List<AnswerItem> Answers { get; set; }
}

public class AnswerItem
{
    public int Id { get; set; }
    public string WordString { get; set; }
}
_____»? Они появились, когда я добавил этот код "array" + "[" + @i + "]" + "." в элемент управления RadioButton с целью присвоения индекса каждому ответу.


person Community    schedule 05.02.2015    source источник
comment
Атрибут id не проблема. Это атрибут name, который отправляет обратно, и в настоящее время ваши имена не имеют отношения к свойству модели, поэтому не будут связываться.   -  person    schedule 05.02.2015
comment
И к вашему сведению, помощники html заменяют символы [, . и ] и недопустимые символы символами подчеркивания.   -  person    schedule 05.02.2015
comment
Какова ваша подпись метода публикации? Почему у вас нет свойства модели, к которому вы можете привязаться? И вам не нужно беспокоиться о id - это не имеет значения   -  person    schedule 05.02.2015
comment
Это (массив QuizInitializationModel[]).   -  person    schedule 05.02.2015
comment
Ваше мнение не будет возвращаться к этому, как я отметил в своем первом комментарии. QuizInitializationModel не содержит свойства с именем array! Вам нужно свойство для привязки. Вскоре я опубликую ответ, но я не уверен в вашем комментарии проверьте строку ответа, верна она или нет. У вас есть свойство, указывающее, правильный ответ или нет?   -  person    schedule 05.02.2015
comment
Спасибо за ваш интерес. Для меня это довольно сложно понять концепции. Я думаю, мне нужно больше изучить тему модели и привязки модели. Нет ничего, кроме общедоступных List‹Question› Questions { get; установлен; } в модели представления. Если я могу получить выбранную строку ответа и идентификатор, я могу сравнить строку с данными, которые я получаю из базы данных через идентификатор, и сказать, что если эта строка равна строке, полученной из базы данных, это правда, в противном случае это не так. Может быть, это плохой подход, но... Что угодно. Спасибо еще раз.   -  person    schedule 05.02.2015


Ответы (1)


Помощники HTML заменяют недопустимые символы символом подчеркивания (точка на самом деле не является недопустимой, но может вызвать проблемы с jquery, поэтому она также заменила подчеркивание). Однако атрибут id не является проблемой, хотя вы создаете дубликаты, которые являются недопустимыми html.

Вы вручную создаете атрибут name для переключателей, которые не имеют отношения к какому-либо свойству в вашей модели, поэтому не будут привязаны при отправке обратно. Ваша модель должна включать свойство, к которому вы можете привязать выбранный ответ. Измените модель Question на

public class Question
{
  public QuestionString QuestionString { get; set; }
  public List<AnswerItem> Answers { get; set; }
  public int SelectedAnswer { get; set; } // add this
}

и изменить вид на

@using (Html.BeginForm()) // note parameter not necessary if your posting to the same controller/action
{
  @for (int i = 0; i < Model.Questions.Count; i++)
  {
    ...
    @Html.HiddenFor(m => m.Questions[i].QuestionString.Id)
    <h2>@Model.Questions[i].QuestionString.WordString)</h2>
    ...
    @foreach(var answer in Model.Questions[i].Answers)
    {
      var id = string.Format("{0}-{1}", @i, answer.Id);
      @Html.Label(id, answer.WordString)
      @Html.RadioButtonFor(m => m.Questions[i].SelectedAnswer, answer.ID, new { id = id })
    }
    ....
  }
  <input type="submit" value="Send" class="btn btn-primary" />
}

Переключатели теперь привязаны к свойству SelectedAnswer, и когда вы отправляете ответ, значением будет идентификатор выбранного AnswerItem.

Обратите также внимание:

  1. Был добавлен скрытый ввод для идентификатора вопроса, чтобы вопрос можно было идентифицировать при обратной публикации.
  2. Текст вопроса находится в теге заголовка (может быть другим тегом), но метка не подходит — метка — это элемент, связанный с элементом управления (для установки фокуса на элемент управления), но у вас нет связанного элемента управления.
  3. Уникальный идентификатор создается в цикле foreach, поэтому вы можете присвоить каждому переключателю уникальный идентификатор (чтобы HTML-код был действительным) и связать метку (текст ответа) с кнопкой.
person Community    schedule 05.02.2015