2010-05-27 3 views
12

Das ist ein wirklich seltsames Verhalten, und ich habe einen Demo-Code eingerichtet, um herauszufinden, was los ist.MVC2 TextBoxFür einen Wert, der nach dem Senden nicht aktualisiert wird?

Grundsätzlich haben Sie eine zwei Aktionen und eine einzige Ansicht. Die erste Aktion sendet ein leeres Modell an die Ansicht, die Abschnittsaktion empfängt das Modell, ändert den Inhalt und sendet es an die gleiche Ansicht zurück.

Die Gewissheit ist, in der Ansicht, das Modell scheint die aktualisierten Werte in ihm zu haben, aber wenn ich eine Html.TextBoxFor (x => x.PropertyNameHere) macht es ein Textfeld mit dem unveränderten Wert darin gerendert.

lol ... Ich entschuldige mich im Voraus für den Toiletten-Humor, aber es hält den Tag davon ab, zu langweilig. ;)

Hat jemand eine Idee, was hier vor sich geht? Warum gibt die Ausgabe von TextBoxFor den alten Wert in das Wertattribut ein?

Hier ist der Code zu replizieren:

/Views/Demo/Index.aspx

namespace TestWeb { 
    public class DemoModel { 
     public string Foo { get; set; } 
     public int Bar { get; set; } 
     public string PoopSmith { get; set; } 
    } 
} 

public class AdminController : Controller { 

     public ActionResult Index() { 
      var m = new DemoModel(); 
      return View(m); 
     } 

     public ActionResult DemoSubmit(DemoModel demo) { 
      demo.Foo += "!!!"; 
      demo.Bar++; 
      demo.PoopSmith += " has pooped."; 
      return View("Index", demo); 
     } 
} 

DemoController.cs

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<TestWeb.DemoModel>" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
    <title>Demo</title> 
</head> 
<body> 
    <div> 
     <%using (Html.BeginForm("DemoSubmit", "Admin", FormMethod.Post)) { %> 
     Foo: <%=Html.TextBoxFor(x => x.Foo)%> <%:Model.Foo %><br /> 
     Bar: <%=Html.TextBoxFor(x => x.Bar) %> <%:Model.Bar %><br /> 
     PoopSmith: <%=Html.TextBoxFor(x => x.PoopSmith) %> <%:Model.PoopSmith %><br /> 
     <button type="submit">Submit</button> 
     <%} %> 
    </div> 
</body> 
</html> 

DemoModel.cs Und h ere ist die bizarre Ausgabe:

Bizarre http://i47.tinypic.com/308cwvb.png

Antwort

14

Standard-HTML-Helfer versuchen, die Daten erneut anzuzeigen, die sie gebucht wird. Sie verwenden zuerst den Wert aus den gebuchten Daten und wenn keine verbuchten Daten verfügbar sind, nehmen sie die Daten aus dem Modell.

Dies ist nicht das, was Sie offensichtlich wollen, aber immer noch die häufigste Verwendung: Sie zeigen einige Daten in Formularfelder nach Erhalt einer Anfrage abrufen. Sie veröffentlichen eine Update-Aktion. Wenn Sie Fehler haben, möchten Sie das Formular mit den von Ihnen eingegebenen Werten noch anzeigen.

Ich habe einige Leute gesehen, die damit umgehen (ich denke, indem ich an ModelState schreibe), aber meine Wahl war immer, die Standardhelfer nicht zu benutzen, wenn sie mir nicht helfen. Das gilt besonders für versteckte Felder: Die meisten Leute werden verwirrt, wenn sie einen Wert auf ein verstecktes Feld setzen, aber der Wert, der wirklich verwendet wird, stammt aus dem Post. Zumindest gibt es jeden zweiten Tag eine Frage dazu auf SO :-)

Vergiss die "meisten Leute" und ersetze sie durch "Everybody".

ASP.NET MVC: Hidden field value does not get rendered using HtmlHelper.Hidden

http://blog.johnwest.com/post/ASPNET-MVC-Hidden-Form-Field-Bug.aspx

http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx?utm_medium=Twitter&utm_source=Shared

UPDATE Oh ich ein anderes von heute gefunden (Du bist nicht allein):

How to update textbox value

+0

+1 LOL! Ihre Suchfähigkeiten sind meiner überlegen! Das macht Sinn, danke für die Antwort. –

6

Do ModellstatusKlar(); in Ihrem Controller, um dies zu verhindern. Überprüfen Sie MSDN dafür.

3

Ich würde ModelState.Clear() oder ModelState.Remove() vermeiden, es sei denn, Sie müssen unbedingt. Im Allgemeinen, wenn Sie dieses Verhalten sehen, liegt es daran, dass a) Sie dem Post-Redirect-Get-Muster nicht folgen und sein sollten, oder b) wenn das nicht angemessen ist, sollten Sie nicht die TextBox-Methode von HtmlHelper verwenden, wie es hauptsächlich ist entworfen, um bei der Validierung usw. zu helfen, wenn einem PRG-Muster gefolgt wird.

Ich bin mir sicher, dass es Ausnahmen gibt (zum Beispiel eine Wizard-ähnliche Benutzeroberfläche kann ein bisschen so enden), aber ich würde das als Standardansatz nehmen.

0

Ich habe das gleiche Problem mit VS 2010 und ich fand, dass ich den ganzen Tag die Wand traf. Nachdem ich über die ganze Nacht nachgedacht habe, habe ich den Grund gefunden. Der Grund ist die Persistenz. Es speichert nur den Wert, der im Browser eingegeben wurde. Ich denke jedoch, dass dies das bindende Prinzip verletzt. Wenn es mir erlaubt wird, einen Modellparameter an die Ansicht zu übergeben, sollte die Ansicht diesen Parameter binden, indem ich alles nehme, was ich im aktuellen Status des Modells passiere.

1

Die Lösung besteht darin, entweder ModelState.Remove ("[Eigenschaftsname des Modus]") zu verwenden, bevor dem Controller ein neuer Wert zugewiesen wird. Oder ändern Sie auf der Ansichtsseite Html.TextBoxFor() in Html.TextBox() für die bestimmte Modelleigenschaft.

Verwandte Themen