Réinitialiser la valeur de textarea après la soumission du formulaire
- je veux envoyer un message à userID=3 en allant dans /MyController/Message/3
- ceci exécute le Message () [get] action, j'entre du texte dans la zone de texte et clique sur Enregistrer pour poster le formulaire
- Message() [post] l'action sauve les modifications, réinitialise la valeur de SomeText pour vider la chaîne et retourne à la vue.
à ce point je m'attends à ce que la zone de texte soit vide parce que j'ai défini ViewData ["SomeText"] à chaîne.Vide
pourquoi la valeur de zone de texte n'est-elle pas mise à jour pour vider la chaîne après l'action post?
Voici les mesures:
[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>
9 réponses
le problème est que le Helper HTML récupère la valeur ModelState, qui est remplie avec les données postées. Plutôt que de pirater ceci en réinitialisant le ModelState, pourquoi ne pas rediriger vers l'action [get]. L'action [post] peut aussi définir un message de statut temporaire comme ceci:
[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 avec les valeurs affichées.
Ce que vous pouvez faire est clair sur l'Action qui a le Poste d'attribut :
ModelState.Clear();
les helpers html lisent la valeur à partir du ModelState. Et il n'y a aucun moyen élégant de passer outre ce comportement.
mais si vous ajoutez cette ligne après SaveToDB(ID, SomeText)
, cela devrait fonctionner :
ModelState["SomeText"].Value =
new ValueProviderResult("", "", CultureInfo.CurrentCulture);
j'ai tout essayé, mais n'a travaillé que quand je faisais 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));
Espérons que cette aide.
au lieu D'utiliser ModelState.Clear () qui nettoie l'ensemble du modelstate, vous pouvez faire le ModelState.Supprimer("SomeText"), si vous le souhaitez. Ou rendre L'entrée sans les extensions htmlhelper. Ils sont conçus pour prendre la valeur de ModelState au lieu du modèle (ou viewdata).
C'est un comportement client. Je recommande l'utilisation de 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 normal que c'est comme:
document.getElementById("SomeText").value = "";
(vous feriez cela sur l'un des événements de charge.
<body onload="...">
Espérons que cette aide.
je suis assez certain que le textarea saisit la valeur de la requête.Forme sous le capot puisque ViewData["SomeText"] est vide.
est-il possible que l'état du modèle ait été mis à jour par une erreur? Je crois qu'il va tirer la valeur tentée de l'état du modèle plutôt que des données de vue ou le modèle si l'état du modèle n'est pas valide.
EDIT: J'inclus la section pertinente du code source dans le TextArea HtmlHelper extension ci-dessous. Il me semble que c'est exactement ce que j'attendais -- s'il y a eu une erreur de modèle, elle tire la valeur de la l'état du modèle, sinon il l'utilise à partir 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 à L'GET.
puisque vous fournissez explicitement une valeur à la ViewData,useViewData
doit être fausse, attemptedValue
devrait être false à moins qu'une erreur n'ait é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);
Do.th. comme ceci:
ajouter:
ModelState.Clear();
avant return
déclaration de la soumettre les boutons d'action de la méthode. Fonctionne pour moi. Ça pourrait marcher pour toi.