Pregunta

Tengo un problema que surge en un formulario que intento publicar. En el escenario donde el formulario no se valida, estoy tomando la ruta estándar de llamar a ModelState.AddModelError () y luego devolver un resultado Ver.

La cuestión es que los ayudantes HTML. * deben recoger el valor publicado al renderizar y me doy cuenta de que mis campos de texto SOLO lo hacen si los incluyo en la lista de parámetros de la acción de devolución de datos, que no debería ' No será necesario, ya que algunos formularios tienen demasiados campos para querer enumerarlos todos como parámetros.

Mi código de acción es 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);
    }

}

Ahora, dataDefinition (que es una entidad LINQ to SQL) tiene un campo MinVolume , se maneja en la vista mediante esta línea:

Minimum: <%= Html.TextBox("MinVolume", null, new { size = 5 })%>

Sin embargo, cuando la vista se representa después de una validación fallida de ModelState, el valor escrito en la página original que publicamos no se conserva A MENOS DE QUE lo incluya como parámetro en el método de devolución de datos. Literalmente, puedo "resolver el problema" haciendo esto:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(long? id, string name, string minVolume)

Por alguna razón, eso obligará a preservar el valor del campo. Esto me parece estúpido porque mi formulario tiene muchos más valores que eso y no debería tener que agregar un parámetro solo para ese campo.

¿Alguna idea?

¿Fue útil?

Solución

¿Podría ser que su código:

<%= Html.TextBox("MinVolume", null, new { size = 5 })%>

..tiene el nulo para el valor predeterminado param? Tal vez si cambia null a Model.MinVolume persistirá el valor. Así:

<%= Html.TextBox("MinVolume", Model.MinVolume, new { size = 5 })%>

No estoy seguro de si su acción devuelve el valor MinVolume en el modelo aunque. Si lo hace, lo anterior debería funcionar. De lo contrario, es posible que deba refactorizar la acción ligeramente.

Otros consejos

Oh hombre, acabo de mejorar el diseño de mi aplicación. El problema ocurre porque tienes una validación personalizada (yo también). Tienes que agregar después

ModelState.AddModelError()

esto

ModelState.SetModelValue("MinVolume", ValueProvider["MinVolume"]);

En vista tiene que ser

Mimum:<%=Html.Textbox("MinVolume")%>

Todavía no estoy seguro de por qué funciona, pero funcionó para mí.

¿Cuál es la clave que está utilizando cuando establece el valor en ModelState por error? El código que establece el parámetro de valor para un TextBox se ve así:

Parte relevante del código marco descargado .

string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);

Como puede ver si el valor de intento existe, lo usará, pero solo si la misma clave está disponible.

Sé que esto funciona porque tengo una acción que no toma parámetros y obtiene los valores directamente del ValueProvider y usa AddModelError para indicar errores de validación. Estoy seguro de que los valores de mis cuadros de texto se conservan.

EDITAR : para que los valores se conserven, deben asociarse de alguna manera con el modelo. Una forma de hacerlo es agregarlos a la lista de parámetros. Otra forma es usar UpdateModel (con los nombres de los parámetros en la lista blanca o no). Una tercera forma es agregar el parámetro explícitamente al modelo como en la respuesta de @ Jenea. Como el ayudante solo extrae del estado del modelo, debe estar allí para que se conserven los valores. No mira la propiedad Formulario de la solicitud.

Según tengo entendido, la solución es:

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

¡buena suerte!

Otra solución es si escribe view:

<%var minVolume=Request["MinVolume"]??"";%>
<%=Html.Textbox("MinVolume",minVolume,new {size=5})%>

Consulte este artículo para ver diferentes formas de manejar la devolución de datos en ASP.NET MVC

texto del enlace

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top