2016-10-18 1 views
0

Es ist schon eine Weile her, dass ich Umbraco benutzt habe. Derzeit wird eine Umbraco 7-Instanz eingerichtet, die viele Formen hat. Ich habe Probleme, ModelState korrekt zu handhaben. Hoffentlich kann jemand erklären, was ich falsch mache. Ich habe in den letzten Tagen viele Artikel gelesen und es sieht so aus, als ob es viele Möglichkeiten gibt, dies zu tun, aber nichts, was ich versucht habe, funktioniert für mich. Ich werde erklären, wo ich gerade bin.Wie gebe ich ein Umbraco 7 MVC-Formular zurück, das eingereicht wurde, aber Fehler aufweist?

Meine Seite Controller, die Ditto verwendet eine stark typisierte Seite Modell zurück:

public override ActionResult Index(RenderModel model) 
    { 
     var customModel = model.Content.As<MyCustomPage>(); 

     // Init the model that I want to bind to the form 
     ViewBag.EditFormModel = new EditFormModel() 
     { 
      MyProperty = "init value" 
     }; 

     return this.CurrentTemplate(customModel); 
    } 

Meine Form Modell:

public class EditFormModel 
{ 
    public int Id { get; set; } 

    [System.ComponentModel.DisplayName("Label")] 
    [System.ComponentModel.DataAnnotations.Required] 
    public string MyProperty{ get; set; } 
} 

Aus meiner Sicht:

@{ 
    // Get the model returned after postback if available, otherwise the initialised model 
    var editFormModel = TempData["EditFormModel"] as LocationEditFormModel ?? ViewBag.EditFormModel as LocationEditFormModel; 
} 

@Html.Partial("CustomEditForm", editFormModel) 

Das Teilansicht :

@model EditFormModel 
    @using (Html.BeginUmbracoForm("PostForm", "PostFormSurface", FormMethod.Post)) 
    { 
     @Html.ValidationSummary(false, string.Empty) 
     @Html.AntiForgeryToken() 
     @Html.EditorFor(m => m.MyProperty) 
     <input type="submit" class="btn btn-primary" value="Submit" /> 
    } 

Meine Oberfläche Controller:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult PostForm(LocationSearchFormModel model) 
    { 
     bool passesServerSideValidation = this.Validate(model); 

     if (passesServerSideValidation) 
     { 
      // Save and perform a redirect 
     } 
     else 
     { 
      // I read something that suggested I should clear model state here but it doesn't seem to make a difference 
      ModelState.Clear(); 

      ModelState.AddModelError(string.Empty, "Not valid"); 
     } 

     // Add the model to temp data so we can retain values on postback 
     TempData["SearchFormModel"] = model; 

     return CurrentUmbracoPage(); 
    } 

Das Problem ist, dass, wenn ich die Form, an der Stelle, lege ich traf die Linie return CurrentUmbracoPage(); ich beobachten kann, dass ModelState.IsValid falsch ist, wie ich erwarten würde. Aber während ich durchtrete, ist der nächste Treffer die Indexmethode im Controller der Seite. Sofort ist ModelState.IsValid jetzt wahr. Daher wird meine Validierungszusammenfassung nicht angezeigt, wenn das Formular erneut geladen wird.

So klar mache ich hier etwas falsch, aber nichts, was ich bisher gelesen habe, hat mich in die richtige Richtung gezeigt. Ich bin dankbar für deinen Rat.

Antwort

0

Was wir im Grunde tun CurrentUmbracoPage zurückzukehren(), wenn das Formular nicht gültig ist und allein RedirectToCurrentUmbracoPage(), wenn es gültig ist und es keine Werte erforderlich zu halten, um die Form zum Beispiel erneute Entsendung. Wir verwenden ModelState, um zu überprüfen, ob das Modell gültig ist.

Ihr Code kann so etwas vereinfacht werden:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult PostForm(LocationSearchFormModel model) 
{ 
    if (ModelState.IsValid == false || !this.Validate(model)) 
     return CurrentUmbracoPage(); 

    TempData["SearchFormModel"] = model; 

    return RedirectToCurrentUmbracoPage(); 
} 

Es ist nicht getestet, byt wahrscheinlich wird Ihnen helfen, dieses Problem zu lösen.

+0

Vielen Dank für Ihre Zeit, aber das Problem ist, dass CurrentUmbracoPage() mein ModelState durch meine Ansicht nicht beibehalten, so kann ich MVC Validierungszusammenfassung usw. nicht verwenden. Ich habe jetzt eine coole Lösung für dieses Problem gefunden, die ich werde Post hier, wenn ich Zeit habe. – getsetcode

+0

Cool! Werde dann mal schauen :) –

0

Eine Lösung gefunden.

In meinem Setup habe ich ein Formular, das über einen RenderMvcController-Subtype gerendert wird. Das Modell dafür erbt von RenderModel.

Ich poste auf einen SurfaceController Subtyp. Das Modell hierfür kann RenderModel nicht erben, da es den IP-publishedContent benötigt, der für den Post nicht verfügbar ist.

Das Problem, wenn Validierungsfehler sind, ist, dass ich tun muss, was mein RenderMvcController tut, basierend auf dem Modell, das der SurfaceController erhielt, ohne den Controller-Kontext zu verlassen, der ModelState enthält.

Ich habe festgestellt, dass der SurfaceController eine Eigenschaft CurrentPage enthält, die der IP PublishedContent ist, der benötigt wird, um die Instanz von RenderModel zum Rendern der Ansicht zu erstellen. Durch das Rendern dieser Ansicht, ohne den Controller-Kontext zu verlassen, bleibt ModelState für die Ansicht verfügbar.

Umbraco (oder MVC) ist sogar schlau genug, die geposteten Werte zu verwenden, ohne sie im Code kopieren zu müssen.

Das Erstellen eines vollständigen Codebeispiels ist im Moment zu viel Arbeit. Lass mich also die Aktion auf dem SurfaceController teilen. (Oder besser gesagt, eine anonymisierte Version davon.)

[HttpPost] 
public ActionResult Index(MySurfaceControllerModel model) 
{ 
    if (!ModelState.Isvalid) 
    { 
     return View("MyView", new MyRenderModel(CurrentPage)); 
    } 

    // Do some stuff with my valid model. 

    return RedirectToAction("thenextpage"); 
} 

Ich hoffe, das andere von der Suche nach einem Weg zu halten, es zu tun, solange ich habe.

Verwandte Themen