ASP.Net MVC ModelState / Html.TextBox postback problema
-
08-07-2019 - |
Pergunta
Eu tenho um problema surgindo de uma forma que eu estou tentando enviar mensagens. No cenário em que o formulário não validarem, estou tomando a rota padrão de chamar ModelState.AddModelError()
em seguida, retornando um resultado View.
A coisa é, o HTML. * Ajudantes são supostamente para pegar o valor registrado quando o processamento e eu estou percebendo que meus campos de texto APENAS fazê-lo se eu incluí-los na lista de parâmetros da ação de postagem, que shouldn' t ser necessário ver como algumas formas têm muito muitos campos para querer enumerá-los todos como parâmetros.
Meu código de ação é de aproximadamente:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(long? id, string name)
{
var dataDefinition = ...
// do some validation stuff
if (!ModelState.IsValid)
{
// manually set checkbox fields via ViewData seeing as this STILL doesn't work in MC 1.0 :P
// ...
return View(dataDefinition);
}
}
Agora, dataDefinition (que é um LINQ to SQL entidade) tem um campo MinVolume , é tratado na vista por esta linha:
Minimum: <%= Html.TextBox("MinVolume", null, new { size = 5 })%>
No entanto, quando a vista é processado após uma validação ModelState falhou, o valor digitado para ele na página original postamos não é preservada MENOS eu incluí-lo como um parâmetro no método de postagem. Literalmente, eu posso "resolver o problema", fazendo isso:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(long? id, string name, string minVolume)
Por alguma razão que forçará o valor do campo para ser preservado. Isso parece estúpido para mim, porque a minha forma tem muito mais valores do que apenas isso e eu não deveria ter que adicionar um parâmetro para apenas nesse campo.
Todas as idéias?
Solução
Será que o seu código:
<%= Html.TextBox("MinVolume", null, new { size = 5 })%>
.. tem o null
para o valor padrão param? Talvez se você alterar o null
para Model.MinVolume
ele irá persistir o valor. Como esta:
<%= Html.TextBox("MinVolume", Model.MinVolume, new { size = 5 })%>
Eu não tenho certeza se a sua ação retorna o valor MinVolume
no modelo tho. Se isso acontecer, o acima deve funcionar. Senão, você pode precisar refazer a ação ligeiramente.
Outras dicas
Oh homem que eu apenas melhorou o meu design do aplicativo. O problema ocorre porque você tem de validação personalizada (eu tenho também). Você tem que adicionar após
ModelState.AddModelError()
este
ModelState.SetModelValue("MinVolume", ValueProvider["MinVolume"]);
Tendo em vista que tem que ser
Mimum:<%=Html.Textbox("MinVolume")%>
Ainda não tenho certeza por que ela funciona, mas ele trabalhou para mim.
O que é a chave que você está usando quando você define o valor no ModelState em caso de erro? O código que define o parâmetro valor para uma caixa de texto se parece com:
parte relevante do baixado código do framework .
string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);
Como você pode ver se o valor existir tentativa, ele vai usá-lo -. Mas somente se a mesma chave está disponível
Eu sei que isso funciona porque eu tenho uma ação que não tem parâmetros e obtém os valores diretamente do ValueProvider e usa AddModelError para indicar erros de validação. Tenho certeza de que os valores em minhas caixas de texto são mantidos.
Editar : Para que os valores a serem retidos, eles precisam ser associado com o modelo de alguma forma. Uma maneira de fazer isso é adicioná-los à lista de parâmetros. Outra maneira é usar UpdateModel (com os nomes de parâmetro na lista branca ou nenhuma whitelist). Uma terceira maneira é adicionar o parâmetro explicitamente ao modelo como na resposta da @ Jenea. Desde o ajudante única puxa a partir do estado do modelo, eles devem estar lá para os valores a serem retidos. Ele não olha para propriedade de formulário do pedido.
Como eu entendo a solução é:
[Transaction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(int id, FormCollection form)
{
T itemToUpdate = repository.Get(id);
UpdateModel(itemToUpdate, form.ToValueProvider());
if (itemToUpdate.IsValid())
{
repository.SaveOrUpdate(itemToUpdate);
return Json(ValidationResultToJson(itemToUpdate.ValidationResults()));
}
repository.DbContext.RollbackTransaction();
return Json(ValidationResultToJson(itemToUpdate.ValidationResults()));
}
boa sorte!
Outra solução é se você digitar em vista:
<%var minVolume=Request["MinVolume"]??"";%>
<%=Html.Textbox("MinVolume",minVolume,new {size=5})%>
Por favor, consulte este artigo para ver maneiras diferentes para postback alça em ASP.NET MVC