Asp.net MVC ModelState.Borrar

Resuelto Mr Grok asked hace 15 años • 10 respuestas

¿Alguien puede darme una definición sucinta de la función de ModelState en Asp.net MVC (o un enlace a uno)? En particular necesito saber en qué situaciones es necesario o deseable llamar ModelState.Clear().

Un poco abierto, eh ... lo siento, creo que podría ayudar si te cuento lo que estoy haciendo realmente:

Tengo una acción de edición en un controlador llamado "Página". Cuando veo por primera vez el formulario para cambiar los detalles de la página, todo se carga bien (vinculándose a un objeto "MyCmsPage"). Luego hago clic en un botón que genera un valor para uno de los campos del objeto MyCmsPage ( MyCmsPage.SeoTitle). Genera bien y actualiza el objeto y luego devuelvo el resultado de la acción con el objeto de página recién modificado y espero que se <%= Html.TextBox("seoTitle", page.SeoTitle)%>actualice el cuadro de texto relevante (representado usando)... pero lamentablemente muestra el valor del modelo anterior que se cargó.

Lo he solucionado usando ModelState.Clear(), pero necesito saber por qué y cómo ha funcionado para no hacerlo a ciegas.

Controlador de página:

[AcceptVerbs("POST")]
public ActionResult Edit(MyCmsPage page, string submitButton)
{
    // add the seoTitle to the current page object
    page.GenerateSeoTitle();

    // why must I do this?
    ModelState.Clear();

    // return the modified page object
     return View(page);
 }

Aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyCmsPage>" %>
....
        <div class="c">
            <label for="seoTitle">
                Seo Title</label>
            <%= Html.TextBox("seoTitle", page.SeoTitle)%>
            <input type="submit" value="Generate Seo Title" name="submitButton" />
        </div>
Mr Grok avatar Nov 21 '09 18:11 Mr Grok
Aceptado

Creo que es un error en MVC. Luché con este problema durante horas hoy.

Dado este:

public ViewResult SomeAction(SomeModel model) 
{
    model.SomeString = "some value";
    return View(model); 
}

La vista se renderiza con el modelo original, ignorando los cambios. Entonces pensé, tal vez no le guste que use el mismo modelo, así que intenté así:

public ViewResult SomeAction(SomeModel model) 
{
    var newModel = new SomeModel { SomeString = "some value" };
    return View(newModel); 
}

Y aún así la vista se representa con el modelo original. Lo extraño es que cuando pongo un punto de interrupción en la vista y examino el modelo, tiene el valor cambiado. Pero el flujo de respuesta tiene los valores antiguos.

Finalmente descubrí la misma solución que tú:

public ViewResult SomeAction(SomeModel model) 
{
    var newModel = new SomeModel { SomeString = "some value" };
    ModelState.Clear();
    return View(newModel); 
}

Funciona como se esperaba.

No creo que esto sea una "característica", ¿verdad?

Tim Scott avatar Apr 20 '2010 21:04 Tim Scott

Actualizar:

  • Esto no es un error.
  • Deje de regresar View()de una acción POST. Utilice PRG en su lugar y redirija a GET si la acción es exitosa.
  • Si devuelve un mensaje View()de una acción POST, hágalo para la validación del formulario y hágalo de la forma en que está diseñado MVC utilizando los asistentes integrados. Si lo haces de esta manera entonces no deberías necesitar usar.Clear()
  • Si está utilizando esta acción para devolver ajax para un SPA , use un controlador de API web y olvídese, ModelStateya que no debería usarlo de todos modos.

Antigua respuesta:

ModelState en MVC se usa principalmente para describir el estado de un objeto modelo en gran medida en relación con si ese objeto es válido o no. Este tutorial debería explicar mucho.

Por lo general, no debería ser necesario borrar ModelState, ya que el motor MVC lo mantiene por usted. Borrarlo manualmente puede provocar resultados no deseados al intentar cumplir con las mejores prácticas de validación de MVC.

Parece que estás intentando establecer un valor predeterminado para el título. Esto debe hacerse cuando se crea una instancia del objeto modelo (capa de dominio en algún lugar o en el objeto mismo - ctor sin parámetros), en la acción de obtención de modo que baje a la página la primera vez o completamente en el cliente (a través de ajax o algo así) para que parezca como si el usuario lo hubiera ingresado y regrese con la colección de formularios publicados. De alguna manera, su enfoque de agregar este valor al recibir una colección de formularios (en la acción POST // Editar) está causando este comportamiento extraño que podría hacer que parezca .Clear() que funciona para usted. Créame, no querrá utilizar el clear. Pruebe una de las otras ideas.

Matt Kocaj avatar Nov 21 '2009 11:11 Matt Kocaj

Si desea borrar un valor para un campo individual, la siguiente técnica me resultó útil.

ModelState.SetModelValue("Key", new ValueProviderResult(null, string.Empty, CultureInfo.InvariantCulture));

Nota: Cambie "Clave" por el nombre del campo que desea restablecer.

Carl Saunders avatar Mar 19 '2010 00:03 Carl Saunders