2008-12-15 20 views
6

Actualmente estoy usando el ModelStateDictionary en asp.net mvc para contener los errores de validación y luego lo devuelvo al usuario. Poder verificar si todo el modelo es válido con ModelState.IsValid es particularmente importante. Sin embargo, una aplicación actual en la que estoy trabajando tiene la necesidad de poder informar advertencias. Estos no son tan críticos, por lo que el contenido del formulario aún se puede guardar, pero se deben mostrar al usuario para que se pueda tomar una acción de forma opcional.Advertencias de modelo en ASP.NET MVC

He estado buscando a través del framework para ver si hay algún lugar obvio para extenderlo y permitirme hacer esto. Estoy pensando que otro diccionario con advertencias y una subclase de error de modelo llamado modelo de advertencia. Sin embargo, no estoy seguro de cómo conseguiría que el framework use mis nuevas clases de contenedor en la vista, etc., aún quiero que todo el error existente funcione.

Si alguien ha intentado algo similar o tiene algún pensamiento agradecería su opinión.

Actualización:

Tengo por lo que se extiende la ViewDataDictionary añadir algunas advertencias

public class AetherViewDataDictionary : ViewDataDictionary 
{ 
    public AetherViewDataDictionary() 
    { 
     ModelStateWarning = new ModelStateDictionary(); 
    } 

    public AetherViewDataDictionary(object model) : base(model) 
    { 
     ModelStateWarning = new ModelStateDictionary(); 
    } 

    public AetherViewDataDictionary(ViewDataDictionary viewDataDictionary) : base(viewDataDictionary) 
    { 
     ModelStateWarning = new ModelStateDictionary(); 
    } 

    public ModelStateDictionary ModelStateWarning { get; private set; } 
} 

El problema que estoy teniendo ahora es que cuando llego a mi código de la vista, esta es solo para la depuración, estoy perdiendo el hecho de que es mi nuevo tipo, así que cuando intento devolverlo y obtener acceso a mi nuevo diccionario, no me agrada.

public partial class Index : ViewPage<PageViewData> 
{ 
    protected override void SetViewData(ViewDataDictionary viewData) 
    { 
     base.SetViewData(viewData); 
    } 
} 

Lo establece correctamente aquí, pero cuando compruebo el tipo se ha ido.

Editar: Esto resultó ser una manera tonta de hacer las cosas, ver respuesta a continuación.

Respuesta

6

Así que la ruta que me dirigía hacia abajo antes de que resultó ser una mala idea, simplemente no es suficiente el acceso en el marco de llegar a los bits que necesita. Al menos no sin reinventar la rueda unas pocas veces.

que decidimos ir por el camino de extender la clase ModelState añadir una colección advertencias a ella:

public class AetherModelState : ModelState 
{ 
    public AetherModelState() { } 

    public AetherModelState(ModelState state) 
    { 
     this.AttemptedValue = state.AttemptedValue; 

     foreach (var error in state.Errors) 
      this.Errors.Add(error); 
    } 

    private ModelErrorCollection _warnings = new ModelErrorCollection(); 

    public ModelErrorCollection Warnings { get { return this._warnings; } } 
} 

Con el fin de ser capaz de añadir fácilmente las advertencias de la misma manera que lo haría errores creé algunos métodos de extensión para el ModelStateDictionary:

public static class ModelStateDictionaryExtensions 
{ 
    public static void AddModelWarning(this ModelStateDictionary msd, string key, Exception exception) 
    { 
     GetModelStateForKey(key, msd).Warnings.Add(exception); 
    } 

    public static void AddModelWarning(this ModelStateDictionary msd, string key, string errorMessage) 
    { 
     GetModelStateForKey(key, msd).Warnings.Add(errorMessage); 
    } 

    private static AetherModelState GetModelStateForKey(string key, ModelStateDictionary msd) 
    { 
     ModelState state; 
     if (string.IsNullOrEmpty(key)) 
      throw new ArgumentException("key"); 

     if (!msd.TryGetValue(key, out state)) 
     { 
      msd[key] = state = new AetherModelState(); 
     } 

     if (!(state is AetherModelState)) 
     { 
      msd.Remove(key); 
      msd[key] = state = new AetherModelState(state); 
     } 

     return state as AetherModelState; 
    } 

    public static bool HasWarnings(this ModelStateDictionary msd) 
    { 
     return msd.Values.Any<ModelState>(delegate(ModelState modelState) 
     { 
      var aState = modelState as AetherModelState; 
      if (aState == null) return true; 
      return (aState.Warnings.Count == 0); 
     }); 
    } 
} 

el código GetModelStateForKey es chungo, pero debe ser capaz de ver hacia donde voy con esto. Lo siguiente que hay que hacer es escribir algunos métodos de extensión que me permitan mostrar las advertencias junto con los errores

+0

¿Qué es AttemptedValue? –

+0

También "if (aState == null) return true;" la línea es incorrecta Deberíamos devolver verdadero si y solo si la colección relacionada tiene al menos un artículo. Por lo tanto, debe eliminar esta línea y cambiar la siguiente línea a "return (aState! = Null && aState.Warnings.Count> 0);" –

4

¿Por qué no simplemente agrega una lista de advertencias, o un diccionario, a ViewData y luego las visualiza en su vista?

p. Ej.

ViewData[ "warnings" ] = new[] { "You need to snarfle your aardvark" } ; 
Cuestiones relacionadas