2017-11-17 3 views
0

Ich instanziiere das "Platte" -Objekt in der GET-Anfrage der Ansicht und dann darauf zugreifen, wenn das Formular gebucht wird. Das Plattenobjekt wird mit den Daten aus dem Formular gefüllt. Kann ich damit auch die übergebenen Koordinaten speichern? Oder was ist die idiomatische Art zu tun, was ich versuche zu erreichen?ASP.NET MVC 5: persistierende Variablen in Controller

Danke!

public class DrawingController : Controller 
{ 

     Plate plate; 

     [HttpGet] 
     public ActionResult Index() 
     { 
      plate = new Plate() 
      { 
       Holes = new Holes() 
      } 
      return View(plate); 
     } 

     // called by ajax when user clicks on "Save" to save the input coordinates 
     [HttpPost] 
     public void PassCoordinates(string coordinates) 
     { 
      // why is plate null here? 
      plate.Holes.coordinates = coordinates; 
     } 

     [HttpPost] 
     public ActionResult Index(Plate plate) 
     { 
     // I want to access plate.Holes.coordinates that I set in 'PassCoordinates' 
     // how can I achieve this? 
     } 
} 
+0

Sie können 'Platte' als statische Variable festlegen, dann wird sie beibehalten. Aber selbst dann wirst du hier ernsthafte Probleme mit den Race Conditions haben. Normalerweise bedeutet das Speichern von Werten, dass sie über eine Art Datenbank oder Caching-Mechanismus bestehen bleiben. – nurdyguy

+0

Warum gibt es 2 Post-Methoden? Können Sie Ihre Index.cshtml bereitstellen? – 0014

+0

@ 0014, 'PassCoordinates (Stringkoordinaten)' wird von ajax aufgerufen und 'Index (Plate plate)' wird am Formular submit aufgerufen. – user3453636

Antwort

1

Was Sie sehen, ist das erwartete Verhalten, weil Http staatenlos ist.

Jedes Mal, wenn Sie Ihre Aktionsmethode aufrufen, wird ein neues Objekt des Controllers erstellt. Also in Ihrem Fall, wenn Sie den Ajax-Aufruf machen, wird es ein neues Objekt der DrawingController erstellen und dieses Objekt wird eine Eigenschaft des Typs Plate haben, aber ist nicht auf ein Plate Objekt initialisiert. (die Sie in Ihrem Index Methodenaufruf tun)

Wenn Sie die gleiche Platte Instanz erhalten mögen, in Ihrer PassCoordinates Aktion Methode, die Sie auf unterschiedliche Weise tun können

  1. Haben Sie Ihren Beitrag Ajax-Aufruf der js Objekt der Plattenstruktur und haben einen Parameter in Ihrer Aktionsmethode von Plate Typ. Wenn die Anforderung gesendet wird, kann der Modellbinder das neue Objekt erstellen und die Werte der verschiedenen Projekte abbilden

  2. Speichern Sie das Plate-Objekt in einem persistenten Medium und lesen Sie es. In Ihrer Index-Aktionsmethode erstellen Sie das Objekt, initialisieren die property-Werte und speichern es in einer db-Tabelle/einem Session-Zustand usw. Sie können es an dieser Stelle in Ihrer zweiten Aktionsmethode erneut lesen. eine statische Variable ist eine weitere Option

Wenn Sie die Option # 2 und wählen gehen Session/statische Variable zu verwenden, denken Sie daran, dass Sie Stateful Verhalten an den stateless http hinzufügen möchten. :(

IMHO, Option 1 ist der Weg zu gehen. das staatenlos Verhalten von Http halten. Haben Sie Ihren Client-Code (der Code, der die Ajax-Aufruf macht) senden, um die JS Objekt, das die Platte Objekt und haben das Modell Binder bauen das Objekt für Sie

Wenn ich Ihren Code anschaue, ist die einzige Sache, die PassCoordinates Methode tut, einfach die Holes.coordinates Eigenschaft Wert des Plate-Objekts (die Sie zwar in der Steuerung verfügbar sein werden). Sie können diese Methode vollständig entfernen und sicherstellen, dass Sie dies in den Eingabeelementen in Ihrem Formular ausführen. Wenn Sie das Formular an die Indexaktionsmethode HttpPost übergeben, ist sie im Anforderungshauptteil und in der Modellbindung verfügbar Er wird es Ihrem Plattenparameter zuordnen.

@model Plate 
@using (Html.BeginForm("Index", "Home")) 
{  
    @Html.TextBoxFor(a=>a.Holes.coordinates)  
    <button type="submit" class="btn" >Save</button>  
} 

Dies wird ein Eingangselement mit dem Namen Holes.coordinates in dem Formular erstellen.

<input id="Holes_coordinates" name="Holes.coordinates" type="text" value=""> 

Geben Sie einen Wert ein und senden Sie das Formular ab. Wenn Sie jetzt in der Aktionsmethode HttpPost einen Haltepunkt setzen, können Sie sehen, dass Ihre Blechobjekte Loch propty gefüllt sind und Sie auf den Wert zugreifen können, den Sie in das Textfeld in der Eigenschaft coordinates eingegeben haben.

Jetzt alles, was Sie tun müssen, ist, was auch immer clientseitiger Code den Ajax-Anruf machte, anstatt den Ajax-Anruf zu machen, setzen Sie den Wert dieser Eingabe.

$("#Holes_coordinates").val("some value you want"); 

Wenn alles funktioniert, können Sie das sichtbare Textfeld zu einem versteckten Eingang durch einfaches Umschalten den Aufrufs HiddenFor Helfer konvertieren.

@Html.HiddenFor(a=>a.Holes.coordinates) 
+0

Vielen Dank für Ihren hilfreichen Kommentar :) Ich übergebe eine HTML-Liste zu String-Koordinaten und ich parse es in PassCoordinates (Code hier nicht gezeigt), aber es zu buchen, wenn das Formular eingereicht wird, wäre die beste Sache zu tun. aber ich weiß nicht, wie ich das machen soll. In Ihrem Punkt # 2, wenn der Ajax-Aufruf durchgeführt wird, ist das Modellobjekt noch nicht vollständig gefüllt. Wenn ich also das Formular einreiche, wird es überschrieben, oder? – user3453636

+0

Ich aktualisierte die Antwort mit Beispielcode, der funktionieren sollte – Shyju

+0

Danke! Ich werde es dich bald wissen lassen, wenn mein Problem gelöst ist. – user3453636

1

Wenn Sie Zustand über Anfragen erhalten wollen für jedem Benutzer

  • Verwenden TempData Sammlung und stellen Sie sicher stellen Sie die Werte jedes Mal. Sie sind nur für die nächsten Anfragen verfügbar, und wenn Sie möchten, dass sie mehrere Anfragen erhalten, müssen Sie sie jedes Mal einstellen.
  • Verwenden Session speichern Werte für die aktuelle Sitzung des Benutzers: https://msdn.microsoft.com/en-us/library/ms178581.aspx
  • Bewahren Sie es in einem Cookie
  • Bewahren Sie es in Query-String
  • speichern sie in einer Datenbank
  • speichern sie in einem In-Memory-Datenbank oder Caching-Service
  • Geben Sie den Wert über das Modell an die nächste zurückgegebene cshtml-Seite zurück, und platzieren Sie den Wert in einem Eingabeformularfeld, so dass es bei der nächsten Anfrage über den nächsten Beitrag
übergeben wird

Jede Methode hat Vor- und Nachteile und ohne weitere Informationen ist es schwer zu bestimmen, was die richtige Wahl ist.

+0

Danke für deine Antwort! werde das definitiv merken :) – user3453636