2

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

首先:我无法让 Questionnaire.IList<QuestionGroup>.IList<Question> 对象图与活页夹一起使用。所以在下面的示例代码中,我只使用了一级 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>
4

2 回答 2

2

I have written how to do this with MvcContrib.FluentHtml:

One problem I see is that you are setting the value of your indexer of your Question list item to the Questionaire ID, which is two levels up. The value should be the ID of the question, if it exists, or some proxy value (such as a negative number) that tells you it's a new instance.

于 2009-01-20T19:08:40.173 回答
1

You can always write your own custom ModelBinder which would require you to write about two methods. See the UpdateCollection method here. You could then passs your repository to your custom ModelBinder.

于 2009-01-15T15:47:24.213 回答