MVC3 Eliminar errores de ModelState

83

Tengo una situación en la que estoy cargando una imagen que el usuario ha seleccionado de su sistema de archivos local. Mi formulario, en mi opinión, básicamente tiene dos botones de envío. Uno se utiliza para enviar el formulario normalmente y se ejecuta toda la validación. El segundo es solo para subir la imagen, en cuyo caso todavía no quiero validar.

Logré desactivar la validación del lado del cliente dando a mi botón de envío 'Subir imagen' un valor de clase de "cancelación de nombre de estilo", así que

<input type="submit" name="UploadImageButton" value="Upload Image" class="style-name cancel" /> 

Ahora, cuando publico, mi modelo tiene una propiedad UploadImageButton, cuando se hace clic en este botón, se completa esta propiedad (el nombre de la entrada coincide con la propiedad). De esta manera, sé si el formulario fue enviado por mi verdadero botón Enviar o por UploadImageButton.

Mi pregunta es la siguiente ... ¿Cómo puedo desactivar la validación del lado del servidor? No quiero que aparezca la información del Resumen de validación cuando el usuario haga clic en este botón. Sé que puede agregar errores de modelo personalizados usando este

ModelState.AddModelError("{key}", "{error msg}");

Estoy buscando un medio para eliminar errores de modelo. es posible?

EDITAR:

Esto es lo que se me ocurrió:

foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key))) {
     //ModelState.Remove(key); //This was my solution before
     ModelState[key].Errors.Clear(); //This is my new solution. Thanks bbak
}
Jeff Reddy
fuente
¿Por qué estás haciendo una Where(key => ModelState.Keys.Contains(key))? Parece que la cláusula Where es redundante, porque cada clave en ModelState.Keys tendrá su ModelState.Keys.Contains (clave) devuelto verdadero.
Maxim Zaslavsky
1
Actualicé la pregunta y el texto para usar el método más corto en ModelState.ContainsKey, aunque está equivocado en su suposición. Estos están haciendo lo mismo.
Jeff Reddy
Lo siento, es posible que le haya explicado mal o haya entendido mal su respuesta. Tienes razón en eso ModelState.ContainsKey(key)y ModelState.Contains(key)haces lo mismo, pero mi punto es que todos los valores de ModelState.Keys.ToList()por naturaleza estarán contenidos ModelState, por lo que la Wherecláusula completa es redundante y ralentizará el rendimiento. Sin embargo, es una cosa menor.
Maxim Zaslavsky
Eso fue ReSharper lanzando eso junto. Gracias por señalar eso.
Jeff Reddy
1
Solo observe la forma en que averigua qué botón fue el origen del envío. En ViewModel no es necesario tener esta propiedad. Simplemente agregue un parámetro FormCollection al Controller: public ActionResult Index (modelo YourViewModelClass, FormCollection formCollection). Y compruebe si el nombre del botón está en él: if (formCollection ["UploadImageButton"]! = Null). Creo que es mejor cuando tienes más botón de envío.
jannagy02

Respuestas:

145

Puede eliminar los errores del modelo haciendo algo como esto:

if (ModelState.ContainsKey("{key}"))
    ModelState["{key}"].Errors.Clear();
bbak
fuente
1
Esto es exactamente lo que estaba buscando. Cambié mi respuesta seleccionada (lo siento Adam Tuliper).
Jeff Reddy
Gracias, ¡eso me acaba de ahorrar un par de horas!
Agent007
1
En caso de que alguien se lo pregunte, esto también afectaModelState.IsValid
Red Taz
2
curiosamente, esto no fue suficiente en mi caso. Tuve que agregar ModelState ["{key}"]. ValidationState = ModelValidationState.Valid;
AGuyCalledGerald
67

Esto se basa en respuestas anteriores, pero lo simplifica un poco más:

foreach (var modelValue in ModelState.Values)
{
    modelValue.Errors.Clear();
}
Dan Friedman
fuente
7

En general, no desea desactivar la validación del lado del servidor o eliminar los errores ModelState manualmente. Es factible, pero propenso a errores, ya que debe depender de cadenas como claves. Elegí la respuesta sobre cómo eliminar las claves, porque es correcto y útil, pero recomiendo no diseñar un caso en el que deba considerarlo seriamente.

En su caso, tiene varios botones de envío para el mismo formulario, pero en realidad no está enviando el formulario cuando carga la imagen. Para evitar la validación del lado del cliente, puede usar la clase "cancelar" como ya ha indicado, pero también recomiendo tener el segundo botón de envío en una forma diferente, en cuyo caso no causa validación en su formulario principal.

Hay una segunda ventaja de usar el formulario diferente: puede enviarlo a un método ActionResult diferente que solo manejaría la lógica de cargar la imagen. Este método diferente simplemente no se molestaría en verificar la propiedad "IsValid" del estado del modelo: solo le importa si hay información en la imagen, y eso se puede verificar por separado. (Incluso si usa el mismo método ActionResult, puede canalizar la lógica para no depender de la propiedad IsValid del estado del modelo).

Si debe borrar los errores del estado del modelo y tiene sentido borrarlos todos, intente esto:

foreach (var key in ModelState.Keys)
{
    ModelState[key].Errors.Clear();
}

Esto le impide depender de obtener los nombres de clave correctos, pero conserva los valores si ya existen valores (válidos o no válidos) en el modelo.

Una última cosa que debe verificar en estos casos es si tiene valores que solo están a veces en la vista, lo que no provocará la validación del lado del cliente (no están en la vista), pero sí dan como resultado problemas de validación del lado del servidor. En este caso, es mejor usar @ Html.HiddenFor (model => model.PropertyName, si puede, asumiendo que el valor ya se ha establecido, simplemente no es visible en esta vista.

James
fuente
7

Lo uso a veces, así que hice un método de extensión a partir de él:

public static ModelStateDictionary ClearError(this ModelStateDictionary m, string fieldName)
{
    if (m.ContainsKey(fieldName))
        m[fieldName].Errors.Clear();
    return m;
}

Se puede utilizar con fluidez para eliminar errores de varios campos.

Mahmoodvcs
fuente
3

use ModelState.Remove ("{key}") para eliminar el error del modelo, que restablecerá ModelState.IsValid a verdadero

ModelState.Remove("{key}");
Ibrar
fuente