Frage

Ich bin neu in ASP.NET MVC. mit traditionellem ASP.NET Modell so lange nach der Arbeit, es nimmt etwas Zeit für mich, dieses Modell zu erhalten, zu verstehen.

Ich werde durch NerdDinner zu verstehen, wie die Dinge funktionieren.

So habe ich ein Objekt, das durch einige Ansichten weitergegeben werden muss. Ähnlich wie bei dem Artikel NerdDinner Schritt 6:. Viewdata und Ansichtsmodell

ich die Daten behalten von Get zum ersten Mal zu Post, dann habe ich es in TempData und gibt sie an eine andere Aktion (AnotherAction). Sobald ich meine Daten auf Get bekomme ich es auf Posten nicht behalten kann.

Hier ist mein Code:

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
    }
}
War es hilfreich?

Lösung

Nach dieser Blog-Post TempData ist nur etwa für 1 Einzel Anfrage nach seinem Satz.

Hier ist ein Zitat aus dem Beitrag:

  

Wenn Sie setzen TempData und Ihre Aktion gibt dann eine Viewresult, dann die nächste Anforderung, was auch immer es passiert zu sein (eine AJAX-Anforderung, eine andere Seite der Benutzer in einem anderen Tab geöffnet, etc.), wird die TempData sehen Wert, den Sie festgelegt, und keine andere Anforderung wird es sehen.

Also den Code gegeben, die ich sehe, können Sie das Abendessen von TempData auf dem get von AnotherAction erhalten, die die erste Anforderung ist, nachdem Sie es auf Action gesetzt. Allerdings Blick auf den Code und den Code nicht für Ansicht für AnotherAction sehen es unklar ist, wie Sie die Daten auf den Posten für AnotherAction sind vorbei. Das Abendessen Instanz wird nicht für diese Anforderung in TempData sein, weil es die zweite Anforderung ist, nachdem Sie es in TempData gesetzt. Und wenn Sie die richtigen keine Form-Tags auf der AntoherAction Ansicht festgelegt haben das Framework wird nicht die richtige Form Werte müssen ein Abendessen Objekt in der Post instanziiert.

Also entweder Sie TempData mit dem Abendessen Instanz es das erste AnotherAction Aufruf zurückgesetzt und dann rufen Sie das Abendessen aus TempData in der Post AnotherAction, oder Sie können den Rat von dm folgen und versteckte Felder in der Ansicht verwenden.

IMO, sollten Sie DMs Weg, dies zu tun und vermeiden TempData verwenden.

Bearbeiten am Beispiel der TempData in AnotherAction Reseting Zugang zu ihm in der Post zu erhalten.

Modell:

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

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

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

Controller:

  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 ) );
    }
  }

Action View:

<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 Ausblick:

<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>

<% } %>

Andere Tipps

das Format erhalten, die Sie erwarten, müssen Sie einige versteckte Felder bevölkern können, wie Sie die Informationen aus verschiedenen Ansichten zu sammeln.

Auch mit Modell Bindung könnten Sie Ihren Code Blick auf wenig besser machen und vermeiden TempData in Orten:

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
}

So in der AnotherAction ansehen würden Sie so etwas wie haben:

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

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

<% } %>

Es gibt keine Benutzerfreundlichkeit im obigen Beispiel, aber Sie erhalten den Punkt.

Sie können nicht roh C # Objekte von Ansichten zu Controllern passieren.

In ASP.NET MVC, wenn eine Aktion ein Objekt für einen Parameter nimmt, sieht ASP.NET MVC in allen POST / GET-Daten und sucht nach Werten, die mit Eigenschaftsnamen auf dem Parameter-Objekt übereinstimmen.

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

myDinner Objekt wird nur ausgefüllt werden, wenn Sie die Aktion mit Formularfeldern erstellen, die auf das Abendessen Eigenschaften des Objekts (Ort, Datum, etc.) entsprechen oder wenn Sie diese Informationen in einer GET-URL (Dinner / SomeAction platzieren sind? location = chicago & date = 12/1/2009 usw.)

Wenn Sie absolut nicht ausgeblendeten Felder verwenden können (A DM vorgeschlagen), dann Sessions sind wahrscheinlich die einzige Option.

Sie sollten Abendessen aus dem Repository erhalten. Sie Aktion sollte wie:

[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 Aktionen können auch aus dem Repository übernehmen, so können Sie nur id übergeben.

Bearbeiten

Wenn Sie Zaubererartschnittstelle Seite erstellen möchten, speichern können Sie zuvor Daten in Session-Objekt eingetragen.

Session['CurrentDinner'] = dinner;

Daten in Session gespeichert bestehen durch Anfragen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top