【问题标题】:Asp.net MVC Module binding with validation for Complex Types具有复杂类型验证的 Asp.net MVC 模块绑定
【发布时间】:2009-01-15 14:41:24
【问题描述】:

我正在 asp.net mvc 中构建一个问卷应用程序,但在使用模块绑定器来获取复杂类型列表时遇到问题。

首先:我无法让 Questionnaire.IList.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>

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-beta1 model-binders


    【解决方案1】:

    我已经写了如何用 MvcContrib.FluentHtml 做到这一点:

    我看到的一个问题是,您将问题列表项的索引器的值设置为问卷 ID,该 ID 高了两个级别。该值应该是问题的 ID(如果存在),或者告诉您它是一个新实例的某个代理值(例如负数)。

    【讨论】:

      【解决方案2】:

      您始终可以编写自己的自定义 ModelBinder,这需要您编写两种方法。请参阅 UpdateCollection 方法 here。然后,您可以将您的存储库传递给您的自定义 ModelBinder。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-26
        相关资源
        最近更新 更多