2014-01-28 177 views
3

我想創建一個調查頁面,可以有文本框和單選按鈕或複選框字段的列表。無論我嘗試什麼,我都無法獲得model.Questions屬性以在提交表單時綁定;該模型是使用null Questions屬性創建的。ASP.Net MVC表單帖子無法綁定模型列表屬性

請告訴我你有一些想法可以幫助我!

視圖模型看起來像這樣:

// Survey view model 
public class Question 
{ 
    public int Id { set; get; } 
    public string QuestionText { set; get; } 

    public bool IsHeading { get; set; } 
    public bool IsList { get; set; } 
    public bool IsCheckBox { get; set; } 

    public List<Answer> Answers { set; get; } 
    [Required] 
    public string SelectedAnswer { set; get; } 
    public string GivenAnswer { get; set; } 
    public Question() 
    { 
     Answers = new List<Answer>(); 
     GivenAnswer = "-1"; 
     SelectedAnswer = "-1"; 
     QuestionText = ""; 
    } 
} 

public class Answer 
{ 
    public int Id { set; get; } 
    public string AnswerText { set; get; } 
} 

public class Assessment 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int LessonId { get; set; } 
    public Module Lesson { get; set; } 

    public SurveyType SurveyType { get; set; } 

    public virtual List<Question> Questions { set; get; } 
    public Assessment() 
    { 
     Questions = new List<Question>(); 
    } 
} 

控制器方法看起來像這樣:

[HttpPost] 
public ActionResult Survey(Assessment model) 
{ 
    if (ModelState.IsValid) 
    { 
     foreach (var q in model.Questions) 
     { 
      var qId = q.Id; 
      var selectedAnswer = q.SelectedAnswer; 
      // Save the data 
     } 
     return RedirectToAction("ThankYou", new { id = model.Id }); //PRG Pattern 
    } 
    //to do : reload questions and answers 
    return View(model); 
} 

Assessment是主視圖模型。以下是在圖(Survey.cshtml)和編輯器模板(EditorTemplates/Question.cshtml,對於每個問題)

Survey.cshtml:

@model ZTTDD.Models.Assessment 
@using ZTTDD.Models 

<div class="row"> 
    <div class="col-md-9"> 
     @using (Html.BeginForm()) 
     { 
      @Html.HiddenFor(m => m.Id) 

      @Html.EditorFor(m => m.Questions) 

      <input type="submit" /> 
     } 
    </div> 
    <div class="col-md-3"> 
     <p> 
      @Html.ActionLink((string)ViewBag.LessonLinkBackText, "Lesson", "Lessons", new { id = Model.Lesson.Id }, null) 
     </p> 
     <p> 
      @Html.ActionLink(linkName, linkMethod, "Lessons", new { id = Model.Lesson.Id }, null) 
     </p> 
    </div> 
</div> 

EditorTemplates/Question.cshtml

@model ZTTDD.Models.Question 


@if (Model.IsHeading) 
{ 
    <div class="survey-heading"> 
     <h4>@Model.QuestionText</h4> 
    </div> 
    <hr/> 
} 
@if (!Model.IsHeading) 
{ 
    <div class="form-group"> 
     @Html.HiddenFor(m => m.Id) 

     <p> @Model.QuestionText </p> 

     @if (Model.IsList) 
     { 
      <div class="radio"> 
       @Html.HiddenFor(m => m.GivenAnswer) 
       @foreach (var a in Model.Answers) 
       { 
        if (Model.IsCheckBox) 
        { 
        <span class="form-horizontal"> 
         @Html.CheckBox(String.Format("Questions_{0}__SelectedAnswer", Model.Id), false, new { value = "", name = String.Format("Questions[{0}].SelectedAnswer", Model.Id) }) @Html.Raw(a.AnswerText) &nbsp;&nbsp; 
        </span> 
        } 
        else 
        { 
         @Html.RadioButtonFor(b => b.SelectedAnswer, a.Id) @Html.Raw(a.AnswerText) <br /> 
        } 
       } 
      </div> 
     } 
     @if (!Model.IsList) 
     { 
      Model.GivenAnswer = ""; 
      @Html.HiddenFor(m => m.SelectedAnswer) 
      @Html.TextAreaFor(m => m.GivenAnswer) 
     } 
    </div> 
} 

下面是得到張貼鍵列表:

[0] "Id" string 
    [1] "Questions[1].Id" string 
    [2] "Questions[1].GivenAnswer" string 
    [3] "Questions[1].SelectedAnswer" string 
    [4] "Questions[2].Id" string 
    [5] "Questions[2].GivenAnswer" string 
    [6] "Questions[2].SelectedAnswer" string 
    [7] "Questions[3].Id" string 
    [8] "Questions[3].GivenAnswer" string 
    [9] "Questions[3].SelectedAnswer" string 
    [10] "Questions[5].Id" string 
    [11] "Questions[5].GivenAnswer" string 
    [12] "Questions[5].SelectedAnswer" string 
    [13] "Questions[6].Id" string 
    [14] "Questions[6].GivenAnswer" string 
    [15] "Questions[6].SelectedAnswer" string 
    [16] "Questions[7].Id" string 
    [17] "Questions[7].GivenAnswer" string 
    [18] "Questions[7].SelectedAnswer" string 
    [19] "Questions[9].Id" string 
    [20] "Questions[9].SelectedAnswer" string 
    [21] "Questions[9].GivenAnswer" string 
    [22] "Questions[10].Id" string 
    [23] "Questions[10].SelectedAnswer" string 
    [24] "Questions[10].GivenAnswer" string 

UPDATE:

只是澄清一點:Question對象可以表示一個標題(沒有字段關聯)或輸入(單選按鈕,複選框或textarea)。據我所知,我需要的值正確發佈。我會嘗試從調試器中抓住它們並在這裏發佈。

UPDATE:

下面這查詢字符串是從Request.Form.ToString(),網址爲解碼和格式化爲便於閱讀。正如你所看到的,這些值是張貼的,但由於某種原因沒有被綁定到Assessment.Questions。這實際上是否可以歸因於問題[xx]中的xx值,因爲它不是索引值,而是實際的ID?

Id=1& 
Questions[1].Id=2& 
Questions[1].GivenAnswer=-1& 
Questions[1].SelectedAnswer=2& 
Questions[2].Id=3& 
Questions[2].GivenAnswer=-1& 
Questions[2].SelectedAnswer=5& 
Questions[3].Id=5& 
Questions[3].GivenAnswer=-1& 
Questions[3].SelectedAnswer=8& 
Questions[5].Id=7& 
Questions[5].GivenAnswer=-1& 
Questions[5].SelectedAnswer=12& 
Questions[6].Id=8& 
Questions[6].GivenAnswer=-1& 
Questions[6].SelectedAnswer=15& 
Questions[7].Id=9& 
Questions[7].GivenAnswer=-1& 
Questions[7].SelectedAnswer=18& 
Questions[9].Id=11& 
Questions[9].SelectedAnswer=-1& 
Questions[9].GivenAnswer=sdfg sdfg dsfg& 
Questions[10].Id=12& 
Questions[10].SelectedAnswer=-1& 
Questions[10].GivenAnswer=sdfg dfsg sdfg 

最後更新:

的問題是事實,我沒有料到的標題,因此指數的問題,其實是不完整的問題發佈任何東西回服務器。爲每個標題添加一個隱藏的Id字段可解決問題。

+0

可以顯示去服務器的查詢字符串? –

+0

這是一個表單發佈,而不是查詢字符串。我將在我的原始文章底部添加Request.Form中的密鑰 – Silkster

+1

我沒有意識到EditorFor會像那樣綁定,但它在獲取時會執行此操作。不幸的是,你的代碼可以按原樣運行,並對我有所幫助。抱歉,我無法提供更多幫助。 :( – hutchonoid

回答

3

我設置了一個基本項目,利用您發佈的代碼示例,以及一些基本的虛擬數據和問題集合。

我想那麼在你正在呈現的特定調查的數據中有什麼是造成問題的。在代碼

看,我可以看到兩個可能的問題:

  • Question.IsHeader是真的,我不認爲任何事情都會得到回發到形式這個問題。那麼我會猜測模型活頁夾不會爲這個問題提供任何東西。從你的表單數據中,看起來會是這樣 - 它缺少0,4和8的索引。我實際上不知道這是否會導致模型聯編程序失敗,但它可以做到。您可以嘗試在問題編輯器模板的IsHeading爲真的情況下將問題ID設置爲HiddenFor
  • 您正在使用的@Html.CheckBox代碼使用問題的ID格式化輸入值,而不是列表中問題的索引。我猜這也會破壞綁定。

希望如果你能解決這些問題,綁定將起作用。我建議在沒有任何標題問題的調查中嘗試它,並且沒有任何複選框或單選按鈕問題,然後查看綁定是否有效。

+0

是的,我認爲問題是發佈的實際問題索引值。我將爲該標題添加一個隱藏的Id字段,以查看是否有幫助。 – Silkster

+0

標記此答案爲解決方案。我所做的只是爲每個標題添加一個隱藏的Id字段。我在控制器方法中處理它們。感謝所有的投入! – Silkster

相關問題