À ce stade, je m'attends à ce que la zone de texte soit vide car j'ai défini ViewData ["SomeText"] sur string.Empty
Pourquoi la valeur de la zone de texte n'est-elle pas mise à jour en chaîne vide après une action de publication?
Voici les actions:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Message(int ID)
{
ViewData["ID"] = ID;
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Message(int ID, string SomeText)
{
// save Text to database
SaveToDB(ID, SomeText);
// set the value of SomeText to empty and return to view
ViewData["SomeText"] = string.Empty;
return View();
}
Et la vue correspondante:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm())
{ %>
<%= Html.Hidden("ID", ViewData["ID"])%>
<label for="SomeText">SomeText:</label>
<%= Html.TextArea("SomeText", ViewData["SomeText"]) %>
<input type="submit" value="Save" />
<% } %>
</asp:Content>
Le problème est que HtmlHelper récupère la valeur ModelState, qui est renseignée avec les données publiées. Plutôt que de contourner ce problème en réinitialisant ModelState, pourquoi ne pas rediriger vers l'action [get]. L'action [post] peut également définir un message d'état temporaire comme celui-ci:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Message(int ID, string SomeText)
{
// save Text to database
SaveToDB(ID, SomeText);
TempData["message"] = "Message sent";
return RedirectToAction("Message");
}
Cela me semble être un comportement plus correct.
Le problème est que votre ModelState est rempli à nouveau avec les valeurs publiées.
Ce que vous pouvez faire, c’est effacer l’action qui a l’attribut Post:
ModelState.Clear();
Les aides HTML lisent la valeur de ModelState. Et il n'y a pas de moyen élégant de remplacer ce comportement.
Mais si vous ajoutez cette ligne après SaveToDB(ID, SomeText)
, cela devrait fonctionner:
ModelState["SomeText"].Value =
new ValueProviderResult("", "", CultureInfo.CurrentCulture);
Au lieu d'utiliser ModelState.Clear (), qui efface tout l'état du modèle, vous pouvez effectuer ModelState.Remove ("SomeText"), si vous le souhaitez. Ou restituer l'entrée sans les extensions htmlhelper. Elles sont conçues pour prendre la valeur de ModelState au lieu du modèle (ou viewdata).
J'ai tout essayé, mais je n'ai travaillé que lorsque j'ai fait quelque chose comme ceci:
ModelState.Clear();
//This will clear the address that was submited
viewModel.Address = new Address();
viewModel.Message = "Dados salvos com sucesso!";
return View("Addresses", ReturnViewModel(viewModel));
J'espère que cela t'aides.
Do.th. comme ça:
ajouter:
ModelState.Clear();
avant l'instruction return
de la méthode d'action boutons de soumission. Travaille pour moi. Cela pourrait fonctionner pour vous.
Est-il possible que l'état du modèle ait été mis à jour avec une erreur? Je pense que la valeur tentée sera extraite de l'état du modèle plutôt que de la vue ou du modèle si l'état du modèle n'est pas valide.
EDIT: J'inclus la section correspondante du code source de l'extension TextArea HtmlHelper ci-dessous. Il me semble que cela correspond exactement à mes attentes - en cas d'erreur de modèle, il extrait la valeur de l'état du modèle, sinon il l'utilise de ViewData. Notez que dans votre méthode Post, la clé "SomeText" ne devrait même pas exister tant que vous ne l’avez pas définie, c’est-à-dire qu’elle ne sera pas reportée de la version du code qui répond à GET.
Étant donné que vous fournissez explicitement une valeur à ViewData, useViewData
doit être false, attemptedValue
doit être false sauf si une erreur a été définie dans l'état du modèle.
// If there are any errors for a named field, we add the css attribute.
ModelState modelState;
if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState)) {
if (modelState.Errors.Count > 0) {
tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
}
}
// The first newline is always trimmed when a TextArea is rendered, so we add an extra one
// in case the value being rendered is something like "\r\nHello".
// The attempted value receives precedence over the explicitly supplied value parameter.
string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.SetInnerText(Environment.NewLine + (attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : value)));
return tagBuilder.ToString(TagRenderMode.Normal);
C'est un comportement côté client. Je recommanderais d'utiliser javascript. Si vous utilisez JQuery, vous pouvez le faire comme ceci:
<script type="text/javascript">
$(function(){ $("#SomeText").val("");});
</script>
Je n'utilise plus Javascript, mais je crois en JS classique que c'est comme:
document.getElementById("SomeText").value = "";
(Vous feriez ceci sur l'un des événements de charge.
<body onload="...">
J'espère que cela t'aides.
Je suis à peu près certain que la zone de texte récupère la valeur de Request.Form sous le capot puisque ViewData ["SomeText"] est vide.