2

asp.net mvcでアンケートアプリを作成していますが、複雑なタイプのリストのモジュールバインダーで問題が発生しています。

まず、Questionnaire.IList <QuestionGroup>.IList<Question>オブジェクトグラフをバインダーで機能させることができません。したがって、以下のサンプルコードでは、1つのレベルのIListのみを使用しています。

2番目:クラスではなくリポジトリ/ファクトリをバインダーに渡したいのですが、そうすれば、フォームの質問とデータベースの質問の間のマッピングを省略して、1セットのオブジェクトで作業することができます。または、少なくともこのコードよりも少しきれいなもの;)。

誰かが私にとって正しい方向へのポインタを手に入れましたか?

コントローラー:

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

私はMvcContrib.FluentHtmlでこれを行う方法を書きました:

私が見ている問題の1つは、質問リスト項目のインデクサーの値を2レベル上の質問票IDに設定していることです。値は、質問のID(存在する場合)、または新しいインスタンスであることを示すプロキシ値(負の数など)である必要があります。

于 2009-01-20T19:08:40.173 に答える
1

約 2 つのメソッドを記述する必要がある独自のカスタム ModelBinder をいつでも記述できます。ここで UpdateCollection メソッドを参照してください。その後、リポジトリをカスタム ModelBinder に渡すことができます。

于 2009-01-15T15:47:24.213 に答える