4

次のようなシナリオがあります。「調査」には「質問」タイプのリストが含まれます。「質問」は ID と「テキスト」という文字列で構成されます。クラス定義は次のとおりです。

public class Survey
{
    public int SurveyId { get; set; }
    public string Title { get; set; }
    public List<Question> Questions { get; set; }

    public Survey()
    {
        this.Questions = new List<Question>();
    }
}

public class Question
{
    public int QuestionId { get; set; }
    public string QuestionText { get; set; }
    public int OwningSurveyId { get; set; }
}

特定の調査のページからリンクして新しい質問を作成できるようにしたいのですが (問題なく動作します)、質問フォームが送信されたときに 2 つのことを行いたいです。1) OwningSurveyId が正しく設定されていることを確認し、2) 質問を Survey.Questions リストに追加します。

私はこの機能を実現するためのあらゆるソリューションを受け入れています。私が取ったアプローチは最善ではないかもしれません。私が決定したのは、Survey オブジェクトを Question の Create フォームに渡すことでした。これにより、フォームが送信されたときにフォームに両方のオブジェクトが含まれ、上記の両方のタスク (1 と 2) を正しく実行できるようになります。

QuestionController で Create Question ページを次のように設定します。

// GET: /Question/Create

    public ActionResult Create(Survey OwningSurvey)
    {
        return View(OwningPulse);
    }

[HttpPost]
    public ActionResult Create(Pulse OwningPulse, Question NewQuestion)
    {
        ModelState["OwningSurveyId"].Errors.Clear();

        if (ModelState.IsValid)
        {
            OwningPulse.Questions.Add(NewQuestion);
            db.Questions.Add(NewQuestion);
            db.SaveChanges();
            return RedirectToAction("Index", "Survey");
        }

        return View(OwningSurvey);
    }

また、質問の Create.cshtml ファイルには次の内容が含まれています。

@model MoodTool.Interface.Models.Survey

@{
ViewBag.Title = "Create";

var Question = new MoodTool.Interface.Models.Question();
Question.OwningPulseId = Model.SurveyId;
}

@using (Html.BeginForm("Create", "Question", "{NewQuestion}", FormMethod.Post, new { NewQuestion = Question }))
{... code follows

私が抱えている問題は、.cshtml ファイルの "Model" の値が null であるため、ページがクラッシュすることです。質問コントローラー ("GET" バージョン) の Create メソッドの OwningSurvey の値も null です。

誰かが私を正しい方向に導くことができますか? 私はおそらく何か大きな間違い (設計パターン) を行っているか、単純な構文エラーを犯していることに気付きましたが、MVC は初めてで、ぐるぐる回っています。

ありがとう

4

2 に答える 2

2

調査アクションで質問を追加した調査のモデルをロードしていますか? そうでない場合、それがモデルがnullである理由です。それは私がここで見たものに基づいた私の推測です。RedirectToActions はモデルをロードしないため、モデルを TempData に入れて、リダイレクトされたアクションで再ロードする必要があります。

パート II

最初の部分では、質問を作成し、調査のインデックス アクションにリダイレクトします。

 OwningPulse.Questions.Add(NewQuestion);
 db.Questions.Add(NewQuestion);
 db.SaveChanges();
 return RedirectToAction("Index", "Survey");

index アクションに入ったら、最初に質問を配置した調査を再読み込みし、それをモデルに読み込んでビューに渡す必要があります。上記の lavriks メソッドを使用して id をアクション メソッドに渡すと、データベースからその調査を取得し、ビュー用に定義されたモデル内のビューに渡すことができます。

    public ActionResult Index(int id)
    {
         // assuming you have some built in functionality to retrieve the survey information from the db through the constructor given an id
        Survey s1 = new survey(id);  

        // some of this is pseudo code, assumes you have a model defined called survey for the view using it
        // Return view with model.
        return View( "Survey" , s1 );
    }

ID をアクション メソッドに渡してビューのアクション メソッドで再度検索する代わりに、tempdata について話したとき、オブジェクトを tempdata に格納できます。

     // save data to survey in teh create action method
     TempData["survey"] = survey

次に、Survey のデフォルトのインデックス アクション メソッドで、tempdata から Survey を呼び出してビューに送信します。

     Survey s1 = (Survey)Tempdata["survey"];
     return View ("Survey", s1);

繰り返しますが、これの一部は疑似コードであり、完全ではありませんが、正しい方向を示しているはずです。どちらのアプローチにも長所と短所がありますが、アプリ、オブジェクトのサイズ、ページにアクセスする人の数などによって、どちらかを使用できます。

于 2012-10-05T12:32:06.437 に答える
1

ここでの最良のアプローチの1つは、Post-Redirect-Getパターンです。アンケートIDを使用して質問フォームを投稿するだけです。コントローラでは、IDで調査を読み取り、存在するかどうかを確認できます。次に、質問を追加して調査を保存します。たとえば、SurveyGETアクションにリダイレクトします。新しく追加された質問を含めて表示されます。さらに、ここに質問と調査IDのみを投稿します。ここでは、これ以上何もする必要はありません。不要なデータを投稿してSurveyを変更することはないので、少し安全です。

編集。

例えば。

// GET: /Question/Create
public ActionResult Create(int surveyId)
{
    return View(new Question(){OwningSurveyId = surveyId });
}
[HttpPost]
public ActionResult Create(Question newQuestion)
{
    if (ModelState.IsValid)
    {
        //I've never used EntityFramework so just a pseudo code here
        var survey = db.Surveys.Get(newQuestion.OwningSurveyId);
        if(survey != null)
        {
            survey.Questions.Add(newQuestion);
            db.Surveys.Save(survey); 
            db.SaveChanges();
            //If you want to open specific survey, 
            //you can pass it's Id to read it in Survey index action
            return RedirectToAction("Index", "Survey", {Id = survey.Id});
        }
    }

    return View(newQuestion);
}

そして、質問を作成するためのビュー

@model MoodTool.Interface.Models.Question

@{
ViewBag.Title = "Create";
}

@using (Html.BeginForm("Create", "Question", FormMethod.Post))
{
     @Html.HiddenFor(x => x.OwningSurveyId)
     @Html.EditorFor(x => x.QuestionText)
       //etc.
 }
于 2012-10-05T13:13:58.683 に答える