Redefinir o valor da área de texto após o envio do formulário

  1. Eu quero enviar uma mensagem para userID = 3, indo para / MyController / Message / 3
  2. Isso executa a ação Message () [get], eu entro algum texto na área de texto e clico em Save para postar o formulário
  3. A ação Message () [post] salva as alterações, reconfigura o valor de SomeText para string vazia e retorna para a view.

Neste ponto, espero que a área de texto esteja vazia, porque defini ViewData [“SomeText”] como string.Empty

Por que o valor da área de texto não é atualizado para string vazia após a ação post?

Aqui estão as ações:

[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(); } 

E a visão correspondente:

          

    O problema é o HtmlHelper está recuperando o valor ModelState, que é preenchido com os dados lançados. Em vez de restringir isso ao redefinir o ModelState, por que não redirect de volta para a ação [get]? A ação [post] também pode definir uma mensagem de status temporária como esta:

     [AcceptVerbs(HttpVerbs.Post)] public ActionResult Message(int ID, string SomeText) { // save Text to database SaveToDB(ID, SomeText); TempData["message"] = "Message sent"; return RedirectToAction("Message"); } 

    Isso me parece um comportamento mais correto.

    O problema é que o seu ModelState é preenchido novamente com os valores postados.

    O que você pode fazer é limpá-lo na ação que tem o atributo Post:

     ModelState.Clear(); 

    Os ajudantes html lêem o valor do ModelState. E não há uma maneira elegante de replace esse comportamento.

    Mas se você adicionar esta linha após SaveToDB(ID, SomeText) , deve funcionar:

     ModelState["SomeText"].Value = new ValueProviderResult("", "", CultureInfo.CurrentCulture); 

    Eu tentei de tudo, mas só trabalhei quando fiz algo assim:

     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)); 

    Espero que isto ajude.

    Em vez de usar ModelState.Clear () que limpa todo o modelstate, você pode fazer ModelState.Remove (“SomeText”), se quiser. Ou renderize a Entrada sem as extensões htmlhelper. Eles são projetados para obter o valor do ModelState em vez do modelo (ou viewdata).

    Esse é um comportamento do lado do cliente. Eu recomendaria o uso de javascript. Se você usa o JQuery, você pode fazer assim:

      

    Eu não uso mais Javascript, mas eu acredito em JS regular que é como:

     document.getElementById("SomeText").value = ""; 

    (Você faria isso em um dos events de carga.

      

    Espero que isto ajude.

    Eu estou bastante certo de que a textarea está pegando o valor do Request.Form sob o título, pois ViewData [“SomeText”] está vazio.

    É possível que o estado do modelo tenha sido atualizado com um erro? Acredito que ele extrairá o valor da tentativa do estado do modelo e não dos dados da visualização ou do modelo se o estado do modelo não for válido.

    EDIT : Estou incluindo a seção relevante do código-fonte da extensão TextArea HtmlHelper abaixo. Parece-me que ele faz exatamente o que eu esperava – se houve um erro de modelo, ele puxa o valor do estado do modelo, caso contrário, ele o usa do ViewData. Note que no seu método Post a tecla “SomeText” não deveria existir até que você a defina, ou seja, ela não será transportada da versão do código que responde ao GET.

    Como você fornece explicitamente um valor para ViewData, useViewData deve ser false, useViewData deve ser false, a menos que um erro tenha sido definido no estado do modelo.

      // 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); 

    Fazer s.th. como isso:

    adicionar:

     ModelState.Clear(); 

    antes da instrução de return do método de ação dos botões de envio. Funciona para mim. Pode funcionar para você.