2010-04-14 17 views
5

Im aktuellen Projekt, an dem wir gerade arbeiten, haben wir noch kein Upgrade auf MVC 2.0 durchgeführt. Daher arbeite ich an einer einfachen Validierung mit den in 1.0 verfügbaren Tools.Simple ASP.Net MVC 1.0 Validierung

Ich bin auf der Suche nach Feedback auf dem Weg, ich mache das.

Ich habe ein Modell, das ein Benutzerprofil darstellt. Innerhalb dieses Modells habe ich eine Methode, die alle Felder und dergleichen validiert. Ich möchte einen Controller an die Validierungsmethode übergeben, damit das Modell die Modellvalidierungseigenschaft im Controller festlegen kann. Ziel ist es, die Validierung vom Controller in das Modell zu bekommen.

Hier ist ein kurzes Beispiel

public FooController : Controller 
{ 
    public ActionResult Edit(User user) 
    { 
      user.ValidateModel(this); 

      if (ModelState.IsValid) 
       ....... 
       ....... 
     } 
} 

Und meine Modellvalidierung Signatur ist wie

public void ValidateModel(Controller currentState) 

Welche Fragen können Sie mit diesem sehen? Bin ich auf dem Weg zum Mittagessen, wie ich das machen möchte?

Antwort

0

Für MVC 1.0-Projekte haben wir wie folgt vor:

/* In model class */ 

public void Validate(string dealerId) 
{ 
    ExceptionList exceptions = new ExceptionList(); 

    if (String.IsNullOrEmpty(this.UserName)) 
    { 
     exceptions.Exceptions.Add(new InvalidFieldException("Error message", "ContractType")); 
    } 

    ... other validations ... 

    if (exceptions.Exceptions.Count > 0) 
    { 
     throw exceptions; 
    } 
} 


/* In controller */ 

public virtual ActionResult UpdateProfile(User user) 
{ 

    try 
    { 
     user.Validate(); 
    } 
    catch (ExceptionList ex) 
    { 
     ex.CopyToModelState(ModelState); 
    } 
} 


/* Custom types (ExceptionList/InvalidFieldException) */ 

[Serializable] 
public class ExceptionList : Exception 
{ 
    private List<Exception> exceptions; 
    public List<Exception> Exceptions 
    { 
     get { return exceptions; } 
     set { exceptions = value; } 
    } 

    public ExceptionList() { Init(); } 
    public ExceptionList(string message) : base(message) { Init(); } 
    public ExceptionList(string message, 
     System.Exception inner) 
     : base(message, inner) { Init(); } 
    protected ExceptionList(
     System.Runtime.Serialization.SerializationInfo info, 
     System.Runtime.Serialization.StreamingContext context) 
     : base(info, context) { Init(); } 


    private void Init() 
    { 
     Exceptions = new List<Exception>(); 
    } 
} 

[Serializable] 
public class InvalidFieldException : Exception 
{ 
    private string fieldName; 
    public string FieldName 
    { 
     get 
     { 
      return fieldName; 
     } 
     set 
     { 
      fieldName = value; 
     } 
    } 

    private string fieldId; 
    public string FieldId 
    { 
     get 
     { 
      return fieldId; 
     } 
     set 
     { 
      fieldId = value; 
     } 
    } 

    public InvalidFieldException() { } 
    public InvalidFieldException(string message) : base(message) { } 
    public InvalidFieldException(string message, string fieldName) 
     : base(message) 
    { 
     this.fieldName = fieldName; 
    } 
    public InvalidFieldException(string message, string fieldName, string fieldId) 
     : base(message) 
    { 
     this.fieldName = fieldName; 
     this.fieldId = fieldId; 
    } 
    public InvalidFieldException(string message, System.Exception inner) 
     : base(message, inner) { } 
    public InvalidFieldException(string message, string fieldName, 
     System.Exception inner) 
     : base(message, inner) 
    { 
     this.fieldName = fieldName; 
    } 
    public InvalidFieldException(string message, string fieldName, string fieldId, 
     System.Exception inner) 
     : base(message, inner) 
    { 
     this.fieldName = fieldName; 
     this.fieldId = fieldId; 
    } 


    protected InvalidFieldException(
     System.Runtime.Serialization.SerializationInfo info, 
     System.Runtime.Serialization.StreamingContext context) 
     : base(info, context) { } 
} 


/* Extension method (to copy ExceptionList exceptions to ModelState) */ 

/// <summary> 
/// Copies an ExceptionList to ModelState for MVC 
/// </summary> 
/// <param name="exList">List of exceptions</param> 
/// <param name="modelState">Model state to populate</param> 
/// <param name="collection">Form collection of data posted to the action</param> 
/// <param name="prefix">Prefix used in view (if any)</param> 
/// <param name="isCollection">Indicates whether a collection of objects are being returned from the view (requires prefix)</param> 
[CLSCompliant(false)] 
public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState, FormCollection collection, string prefix, bool isCollection) 
{ 
    foreach (InvalidFieldException ex in exList.Exceptions) 
     if (String.IsNullOrEmpty(prefix)) 
     { 
      modelState.AddModelError(ex.FieldName, ex.Message); 
      modelState.SetModelValue(ex.FieldName, collection.ToValueProvider()[ex.FieldName]); 
     } 
     else 
     { 
      if (isCollection) 
      { 
       modelState.AddModelError(prefix + "[" + ex.FieldId + "]." + ex.FieldName, ex.Message); 
       modelState.SetModelValue(prefix + "[" + ex.FieldId + "]." + ex.FieldName, collection.ToValueProvider()[ex.FieldName]); 
      } 
      else 
      { 
       modelState.AddModelError(prefix + "." + ex.FieldName, ex.Message); 
       modelState.SetModelValue(prefix + "." + ex.FieldName, collection.ToValueProvider()[ex.FieldName]); 
      } 
     } 
} 

    /// <summary> 
    /// Copies an ExceptionList to ModelState for MVC 
    /// </summary> 
    /// <param name="exList">List of exceptions</param> 
    /// <param name="modelState">Model state to populate</param> 
    [CLSCompliant(false)] 
    public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState) 
    { 
     CopyToModelState(exList, modelState, null, false); 
    } 

    /// <summary> 
    /// Copies an ExceptionList to ModelState for MVC 
    /// </summary> 
    /// <param name="exList">List of exceptions</param> 
    /// <param name="modelState">Model state to populate</param> 
    /// <param name="collection">Form collection of data posted to the action</param> 
    [CLSCompliant(false)] 
    public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState, FormCollection collection) 
    { 
     CopyToModelState(exList, modelState, collection, null, false); 
    } 

Grundsätzlich sind wir nur eine Gruppe von Ausnahmen zurück an den Controller zu werfen und lassen die Steuerung sie Model hinzuzufügen. Ziemlich einfach und modular.

1

Das Problem, das ich mit diesem Ansatz sehen kann, ist, dass Ihre Validierungslogik an den Controller gekoppelt ist. Tatsächlich benötigt der Validator nicht den Controller, sondern nur einen IDictionary<string, ModelState>, um Fehler zu setzen.

Ich würde vorschlagen, Sie betrachten die fluent validation library, die Sie vollständig Ihre Validierungslogik von der Steuerung entkoppeln können. Es verwendet einen Modellordner, in dem es Zugriff auf den Controller hat, um Fehler zu setzen.

So Ihre Aktions-Code wird wie folgt aussehen:

public FooController : Controller 
{ 
    public ActionResult Edit(User user) 
    { 
     if (ModelState.IsValid) 
     { 

     } 
     return View(); 
    } 
} 

Modellfehler werden während der Bindung hinzugefügt. Here's a nice article demonstriert die Integration dieser Bibliothek mit ASP.NET MVC. Unit testing Ihre Validierungslogik ist auch sehr einfach und lesbar.