2009-07-26 4 views
2

Wenn ich ein einfaches Modell wie folgt aus:Wie wird ein Wert geändert, der an eine MVC-Aktionsmethode gerundet wird?

Modell:

public class AnimalModel { 
     public string Species {get;set;} 
    } 

Ausblick:

<%= Html.TextBox("Species") %> 

ActionMethod (POST):

AnimalModel model = new AnimalModel(); 

    // update model 
    UpdateModel(model); // updates ViewData.ModeState 

    // correct spelling 
    if (model.Species == "catt") { 
     model.Species = "cat"; 
    } 

    // return view 
    return View(model); 

Also die Aktionsmethode auf einem POST soll die Schreibweise von "catt" zu "cat" korrigieren.

Das Problem ist, dass der Quelltext für 'TextBox' den Wert von ViewData.ModelState nimmt, wenn dort ein 'Species' Wert gefunden wird. Dies bedeutet, dass mein korrekter Wert für ein Postback nicht aktualisiert wird, da 'catt' Priorität hat. So

dachte ich - ah gut, ich werde einfach es so explizit machen:

<%= Html.TextBox("Species", Model.Species) %> 

Überraschenderweise dies nicht funktioniert und STILL nimmt den Wert von ViewData.ModelState. Ich bin mir ziemlich sicher, dass dies ein Fehler in MVC ist, da ich den Quellcode für diese Überladung sehe, finde ich diese Überlastung. Es zeigt deutlich, dass die ‚useViewData‘ Parameter falsch sein soll, wenn ‚Wert‘ zur Verfügung gestellt wird (was ich mache ausdrücklich oben):

public static string TextBox(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) { 
     return InputHelper(htmlHelper, InputType.Text, name, value, 
       (value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes); 
    } 

Unfortunatley obwohl der ‚InputHelper‘ Methode respektiert diese Eigenschaft nicht für eine TextBox und schaut immer noch zuerst im ViewDataDictionary. Es findet "catt" in diesem Wörterbuch, weil es direkt von den POST-Daten kam.

Ich habe eine Lösung gefunden, wenn ein UserControl verwendet wird, das NULL für ViewDataDictionary übergibt.

<% Html.RenderPartial("AnimalControl", Model, null); %> 

Was ist die Lösung dafür? Ich bin mir sicher, dass das irgendwo dokumentiert ist, aber ich kann es nicht finden. Ich möchte ViewDataDictionary nicht manuell löschen müssen, aber ich sehe keine andere Lösung.

Antwort

0

Ich bin froh, dass ich von Anfang an Modellbindung und eingebaute HTML-Helfer beiseite gelegt habe.

Sie können entweder den benötigten Helfer reparieren/außer Kraft setzen oder Ihren eigenen bauen. Ich sehe nicht, was sonst in dieser Situation getan werden kann.

+0

ich entweder. Ich habe gerade ein paar Stunden damit verbracht, an etwas Komplizierterem zu arbeiten. Schließlich stellte sich heraus, dass es so etwas wie ein niedriges Niveau war. sehr frustrierend! –

1

Es scheint ein Fehler in MVC zu sein, von dem, wie Sie es beschrieben, aber ...

Wenn Sie Species im Modell haben, warum auch Sie es in der Viewdata Dictionary haben?


Betrachten Sie diesen Beitrag im NerdDinner Tutorial Check-out:

http://nerddinnerbook.s3.amazonaws.com/Part6.htm

Nach unten, wo es heißt, "Mit einem Viewmodel-Muster" und überprüfen.

+0

das ist der Kern des Problems. Ich wünschte, es wäre nicht dort. aber MVC stellt es da, da es 'von der Seite abgerundet' wird –

+0

Der einzige Weg, wie es sein könnte, ist, wenn Sie es dort setzen. Warum ruderst du das Modell nicht herum? –

+1

Wenn Sie Ihre Seite von Ihrem Modell erben, können Sie anstelle von ViewState ein Modellobjekt in Ihren Controller einfügen und damit arbeiten. –

0

Meine beste Lösung so weit (da ich nicht Viewdata oder Model ausdrücklich in meiner Ansicht verwenden):

 ViewData.ModelState.Clear(); 
     return View(model); 

Kann jemand bitte eine bessere Lösung finden. Das stinkt!

+0

Betrachten Sie diesen Beitrag in der NerdDinner Tutorial: http://nerddinnerbook.s3.amazonaws.com/Part6.htm Gehen Sie hinunter zu, wo es heißt, "Using ein ViewModel Pattern "und überprüfen Sie das. –

+0

danke für den Link. Das mache ich mit meiner AnimalModel-Klasse. Leider behandeln sie keine komplexen Szenarien wie diese - obwohl es mich schließlich dazu brachte, das Nerd Dinner Kapitel auszudrucken. Ich bin sicher, dass ich etwas lernen werde. und glücklicherweise wird mein Drucker seine 50 Blatt Papier automatisch duplexieren. –

0

Versuchen Sie den folgenden Code, um den "Status" des Modells tatsächlich zu ändern. Ich weiß, Sie würden erwarten, dass es funktioniert, wenn Sie <%= Html.TextBox("Species", Model.Species) %> dort setzen, aber aus den Gründen, die Sie erklärt haben, funktioniert es nicht.

ModelState["Species"].Value = 
      new ValueProviderResult("cat", "catt", CultureInfo.CurrentCulture); 
Verwandte Themen