0

ASP.NET MVC は初めてです。従来の ASP.NET モデルを長い間使用してきたため、このモデルを理解するには時間がかかります。

物事がどのように機能するかを理解するために、NerdDinner を使用しています。

したがって、いくつかのビューを通過する必要があるオブジェクトがあります。記事NerdDinner Step 6: ViewData and ViewModelに似ています。

Get to Post からのデータを初めて保持し、それを TempData に入れて別のアクション (AnotherAction) に渡します。Get でデータを取得したら、Post で保持できません。

これが私のコードです:

public class DinnerFormViewModel
{
    public Dinner Dinner { get; private set; }

    public DinnerFormViewModel(Dinner dinner)
    {
        Dinner = dinner;
    }
}

public class DinnersController : Controller
{
    public ActionResult Action()
    {
        Dinner dinner = new Dinner();
        return View(new DinnerFormViewModel(dinner));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Action(Dinner dinner, FormCollection collection)
    {
        try
        {
            // Some code
            TempData["Dinner"] = dinner;
            return RedirectToAction("AnotherAction");
        }
        catch
        {
            return View();
        }
    }

    public ActionResult AnotherAction()
    {
        Dinner dinner = (Dinner)TempData["Dinner"]; // Got my dinner object
        return View(new DinnerFormViewModel(dinner));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AnotherAction(Dinner dinner, FormCollection collection)
    {
        // Lost my dinner object, dinner comes in as null
    }
}
4

4 に答える 4

2

期待する形式を取得するには、さまざまなビューから情報を収集するときに、いくつかの非表示フィールドに入力する必要がある場合があります。

また、モデルバインディングを使用すると、コードの見栄えを少し良くし、場所によってはTempDataを回避できます。

public ActionResult Action()
{
    Dinner dinner = new Dinner();
    return View(new DinnerFormViewModel(dinner));
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Action(Dinner dinner)
{
    try
    {
        return RedirectToAction("AnotherAction", dinner);
    }
    catch
    {
        return View();
    }
}

public ActionResult AnotherAction(Dinner dinner)
{
    return View(new DinnerFormViewModel(dinner));

    //In this view is where you may want to populate some hidden fields with the Dinner properties that have already been entered... so when the Post action picks up the dinner object it will be fully populated
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AnotherAction(Dinner dinner)
{
    //work with fully populated Dinner object
}

したがって、AnotherActionビューでは、次のようになります。

<% using(Html.BeginForm()) { %>

    <%= Html.Hidden("dinnerProperty1") %>
    <%= Html.Hidden("dinnerProperty2") %>
    <%= Html.Hidden("dinnerProperty3") %>
    <%= Html.TextBox("dinnerProperty4") %>
    <%= Html.TextBox("dinnerProperty5") %>
    <%= Html.TextBox("dinnerProperty6") %>

<% } %>

上記の例には使いやすさはありませんが、要点はわかります。

于 2009-11-29T05:05:22.093 に答える
1

このブログ投稿によると、 TempDataは、設定後の1つのリクエストに対してのみ存在します。

投稿からの引用は次のとおりです。

TempDataを設定し、アクションがViewResultを返す場合、次のリクエスト(AJAXリクエスト、ユーザーが別のタブで開いた別のページなど)は、設定したTempData値を表示します。 、および他のリクエストには表示されません。

したがって、私が見ているコードを考えると、getにTempDataからディナーを取得できます。AnotherActionこれは、に設定した後の最初のリクエストですAction。ただし、コードを表示しAnotherActionても表示用のコードが表示されない場合は、の投稿にデータを渡す方法が不明確ですAnotherAction。ディナーインスタンスは、TempDataで設定した後の2番目のリクエストであるため、そのリクエストのTempDataには含まれません。また、ビューに適切なフォームタグが設定されていない場合AntoherAction、フレームワークには、投稿でディナーオブジェクトをインスタンス化するための適切なフォーム値がありません。

AnotherActionしたがって、最初の呼び出しでディナーインスタンスを使用してTempDataをリセットしてから、投稿のTempDataからディナーを取得するAnotherAction必要があります。または、dmのアドバイスに従って、ビューの非表示フィールドを使用することもできます。

IMO、これを行うにはDMの方法を使用し、TempDataの使用は避けてください。

編集AnotherActionでTempDataをリセットして、投稿でアクセスできるようにする例を追加しました。

モデル:

  public class Dinner
  {
    public string Name{get;set;}
  }

  public class DinnerFormViewModel
  {
    public Dinner Dinner {get;private set;}

    public DinnerFormViewModel( Dinner dinner )
    {
      Dinner = dinner;
    }
  }

コントローラ:

  public class DinnersController : Controller
  {
    public ActionResult Action()
    {
      Dinner dinner = new Dinner();
      return View( new DinnerFormViewModel( dinner ) );
    }

    [AcceptVerbs( HttpVerbs.Post )]
    public ActionResult Action( Dinner dinner, FormCollection collection )
    {
      try
      {
        // Some code
        TempData[ "Dinner" ] = dinner;
        return RedirectToAction( "AnotherAction" );
      }
      catch
      {
        return View();
      }
    }

    public ActionResult AnotherAction()
    {
      Dinner dinner = ( Dinner )TempData[ "Dinner" ]; // Got my dinner object
      TempData[ "Dinner" ] = dinner; // Reset the dinner object in temp data
      return View( new DinnerFormViewModel( dinner ) );
    }

    [AcceptVerbs( HttpVerbs.Post )]
    public ActionResult AnotherAction( Dinner dinnerFromPostedFormValues, FormCollection collection )
    {
      //dinnerFromPostedFormValues is null
      var dinnerFromTempData = TempData[ "Dinner" ] as Dinner; // Got my dinner object

      return View( "Action", new DinnerFormViewModel( dinnerFromTempData ) );
    }
  }

アクションビュー:

<h2>Action</h2>

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
           Name: <%= Html.TextBox("Name", Model.Dinner.Name ) %>
        </p>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>

<% } %>

AnotherActionビュー:

<h2>AnotherAction</h2>

<% using (Html.BeginForm()) {%>

  <fieldset>
      <legend>Fields</legend>
      <p>
          Name:
          <%= Html.Encode(Model.Dinner.Name) %>
      </p>

      <p>
          <input type="submit" value="Do Something" />
      </p>
  </fieldset>

<% } %>
于 2009-11-29T05:54:17.780 に答える
1

ビューからコントローラーに未加工の C# オブジェクトを渡すことはできません。

ASP.NET MVC では、アクションがパラメーターのオブジェクトを受け取ると、ASP.NET MVC はすべての POST/GET データを調べて、パラメーター オブジェクトのプロパティ名と一致する値を探します。

public ActionResult SomeAction(Dinner myDinner)
{
        // do stuff
}

myDinner オブジェクトは、Dinner オブジェクトのプロパティ (場所、日付など) に対応するフォーム フィールドを使用してアクションに投稿する場合、またはその情報を GET URL に配置する場合 (Dinners/SomeAction?location=chicago&date) にのみ入力されます。 =2009/12/1 など)

非表示フィールドを絶対に使用できない場合 (DM が提案したように)、おそらくセッションが唯一の選択肢です。

于 2009-11-29T22:36:08.413 に答える
0

リポジトリから夕食を取得する必要があります。あなたの行動は次のようになります:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AnotherAction(int dinnerId, FormCollection collection)
{
    var dinner = dinnerRepository.Get(dinnerId);
    ... do something with dinner ...
    dinnerRepository.Save(dinner);
    return RedirectToAction("AnotherAction", ... pass dinner id ...);
}

GET アクションはリポジトリからも取得できるため、id のみを渡すことができます。

編集

ウィザード スタイルのページを作成する場合は、以前に入力したデータを Session オブジェクトに格納できます。

Session['CurrentDinner'] = dinner;

セッションに保存されたデータは、リクエストを通じて保持されます。

于 2009-11-28T23:34:13.777 に答える