2016-05-10 7 views
1

複雑なタイプの辞書を含むフォームを投稿しようとしています。 辞書には、次のようになります。MVC 6モデルバインディング複合辞書

public Dictionary<Question, List<QuestionAlternative>> Questions { get; set; } 

一つの質問は多くの選択肢を持つことができます。

質問自体は次のようになります。

public class Question 
{ 
    public Guid Id { get; set; } 

    public string Text { get; set; } 

    public Guid TestId { get; set; } 

    public Test Test { get; set; } 

    public ICollection<QuestionAlternative> QuestionAlternatives { get; set; } 

    public Guid? QuestionTypeId { get; set; } 
    public QuestionType QuestionType { get; set; } 
} 

そしてQuestionAlternativeがあります:

<form asp-controller="Answer" asp-action="AnswerMe" method="post"> 
     @foreach (var questionPair in Model.Questions) 
     { 
      @Html.Hidden("Questions[" + questionIndex + "].Key.Id", questionPair.Key.Id) 
      <br /> 
      foreach (var alternative in questionPair.Value) 
      { 
       <label for="@alternative.Id">@questionPair.Key.Text</label> 
       <textarea id="@alternative.Id" name="@("Questions["+ questionIndex + "].Value["+ index +"]")"></textarea> 

       index++; 
      } 
      } 
      questionIndex++; 
     } 
     <input type="submit" class="button" value="Answer" /> 
    </form> 

私はのActionResult:

public class QuestionAlternative 
{ 
    public Guid Id { get; set; } 

    public string Alternative { get; set; } 

    public Guid QuestionId { get; set; } 

    public Question Question { get; set; } 
} 

私のフォームは、このようになりますこのように投稿する:

[AllowAnonymous] 
    [HttpPost("AnswerMe")] 
    public IActionResult AnswerMe([FromBody]AnswerViewModel model) 
    { 
    foreach(var item in model.Questions) //throws exception 
    .... 
    } 

と私のviewmodel:

public class AnswerViewModel 
{ 
    public ODELDAL.Entities.Test Test { get; set; } 

    public Dictionary<Question, List<QuestionAlternative>> Questions { get; set; } 

    public Guid SelectedRole { get; set; } 
} 

私は自分のフォームを投稿するときの質問という名前の辞書はnullです。

デフォルトのモデルバインダーでこれを実現することは可能ですか、カスタムモデルバインダーを構築する必要がありますか?

もしそうなら、そのソリューションはどのように見えますか?事前

+1

を生成したとき、非表示の入力は次のようになりますか? – Shyju

+0

@Shyjuは私の質問を編集しました –

+0

あなたは 'QuestionAlternative'のコレクションを持つ辞書を持っていて、' QuestionAlternative'にはそれぞれ 'QuestionAlternative'の集合を持つ' Question'があります。このネスティング(そして範囲によって、拘束)が永遠に続くことができるのは意図ですか? –

答えて

1

おかげQuestionがすでにビューモデルにシンプルコレクト(リスト、配列....など)を使用しない理由QuestionAlternativeのコレクションを持っているので...

public class AnswerViewModel { 
    public ODELDAL.Entities.Test Test { get; set; }  
    public Question[] Questions { get; set; }  
    public Guid SelectedRole { get; set; } 
} 

...更新されたビュー...

<form asp-controller="Answer" asp-action="AnswerMe" method="post"> 
    @for(int i = 0; i < Model.Questions.Length; i++) { 
     @Html.HiddenFor(m => m.Questions[i].Id) 
     <br /> 
     for(int j = 0; j < m.Questions[i].QuestionAlternatives.Count; j++) { 
      @Html.LabelFor(m => m.Questions[i].QuestionAlternatives[j].Alternative,m.Questions[i].QuestionAlternatives[j].Text) 
      @Html.TextAreaFor(m => m.Questions[i].QuestionAlternatives[j].Alternative) 
     } 
    } 

    <input type="submit" class="button" value="Answer" /> 
</form> 

モデルバインダーは、ablになるようにこのアプローチを使用してモデルを再構築する簡単な作業を行いますe式を使用してhtmlタグのIDを生成します。例えば

あなたHttpPostアクションがどのように見えるんどのように

<input data-val="true" id="Questions_0__Id" name="Questions[0].Id" value="{Some-Guid-Value_Here}" type="hidden"> 
関連する問題