2009-01-15 83 views
2

我在asp.net mvc中构建了一个调查问卷应用程序,并且我遇到了复杂类型列表的模块联编程序问题。Asp.net MVC模块绑定与复杂类型的验证

第一:我无法得到Questionnaire.IList <QuestionGroup> .IList <问题>对象图使用活页夹。所以在下面的示例代码中,我只使用一个级别的IList。

第二:我喜欢将我的存储库/工厂而不是类传递给活页夹,这样我就可以放弃表单问题和数据库问题之间的映射,只需处理一组对象。或者至少比这段代码更漂亮一些;)。

任何人都有一个指向正确的方向对我来说?

控制器:

public class QuestionnaireController : Controller 
{ 
    #region Constructors 

    public QuestionnaireController(IRepositoryWithTypedId<QuestionGroup, string> questionnaireRepository) 
    { 
     repository = questionnaireRepository; 
    } 

    #endregion 

    public ActionResult Create(string Id) 
    { 
     if (!string.IsNullOrEmpty(Id)) 
     { 
      QuestionGroup questionnaire = repository.Get(Id); 
      return View(questionnaire); 
     } 
     else return RedirectToAction("Index"); 
    } 

    [Transaction] 
    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Create(string Id, QuestionGroup questionGroup) 
    { 
     QuestionGroup dbQuestionGroup = repository.Get(Id); 

     //Map Questions in form to Questions from db 
     foreach (var question in dbQuestionGroup.Questions) 
     { 
      Question persQuestion = 
        (from item in questionGroup.Questions where item.QuestionID.Equals(question.ID) select item) 
        .SingleOrDefault(); 
      if (persQuestion != null) 
      { 
       question.Answer = persQuestion.Answer; 
      } 
     } 

     //Validate Questions(db) 
     bool valid = true; 
     foreach (var question in dbQuestionGroup.Questions) 
     { 
      if (!question.IsValid()) 
      { 
       foreach (var item in question.ValidationMessages) 
       { 
        ViewData.ModelState.AddModelError("questionGroup.Questions[" + question.ID + "]." + 
         item.PropertyName, 
         item.Message); 
       } 
       valid = false; 
      } 
     } 

     //Return the same form with validation info appended 
     if (!valid) 
     { 
      return View(dbQuestionGroup); 
     } 

     //Persist to db and redirect to Complete 
     else 
     { 
      repository.SaveOrUpdate(dbQuestionGroup); 
      return RedirectToAction("Complete"); 
     } 
    } 
    private IRepositoryWithTypedId<QuestionGroup, string> repository; 
} 

局部视图(主视图只是没有在QuestionGroup问题一个foreach并呈现这种观点对每个问题)

<div class="Question"> 
    <div class="QuestionTitle"> 
     <%=ViewData.Model.Description %> 
    </div> 
    <input name="questionGroup.Questions.Index" value='<%=ViewData.Model.ID %>' type="hidden" /> 
    <input name='<%="questionGroup.Questions[" + ViewData.Model.ID + "].QuestionID" %>' value='<%=ViewData.Model.ID %>' type="hidden" /> 
    <div class="QuestionText"> 
     <%switch (ViewData.Model.Type.ToLower()) 
    { 
     case QuestionType.Text:%> 
     <%=Html.TextBox("questionGroup.Questions[" + ViewData.Model.ID + "].Answer")%> 
     <% break; 
       case QuestionType.Number:%> 
     <%=Html.TextBox("questionGroup.Questions[" + ViewData.Model.ID + "].Answer")%> 
     <%= Html.ValidationMessage("questionGroup.Questions[" + ViewData.Model.ID + "].Answer")%> 
     <% break; 
          case QuestionType.PhoneNumber:%> 
     <%=Html.TextBox("questionGroup.Questions[" + ViewData.Model.ID + "].Answer")%> 
     <% break; 
          case QuestionType.Email:%> 
     <%=Html.TextBox("questionGroup.Questions[" + ViewData.Model.ID + "].Answer")%> 
     <%= Html.ValidationMessage("response.Questions[" + ViewData.Model.ID + "].Answer")%> 
     <% break; 
          case QuestionType.Date:%> 
     <%=Html.TextBox("questionGroup.Questions[" + ViewData.Model.ID + "].Answer")%> 
     <% break; 
          case QuestionType.YesNo:%> 
     <%=Html.RadioButton("questionGroup.Questions[" + ViewData.Model.ID + "].Answer", "0", true)%>Ikke valgt<br /> 
     <%=Html.RadioButton("questionGroup.Questions[" + ViewData.Model.ID + "].Answer", "true", false)%>Ja<br /> 
     <%=Html.RadioButton("questionGroup.Questions[" + ViewData.Model.ID + "].Answer", "false", false)%>Nei<br /> 
     <% break; 
          case QuestionType.Alternative:%> 
     <%=Html.DropDownList("questionGroup.Questions[" + ViewData.Model.ID + "].Answer", new SelectList(ViewData.Model.Alternatives, "ID", "Description"))%> 
     <% break; 
      }%> 
    </div> 
</div> 

回答

1

你总是可以编写自己的自定义ModelBinder会要求你写两种方法。请参阅UpdateCollection方法here。然后,您可以将您的存储库传递给您的自定义ModelBinder。