2016-01-06 1 views
1

Donc, j'ai une classe de modèle User. Il a la liste de UnitViewModel.MVC ModelState Validation de la liste des propriétés complexes

public class UserViewModel 
{ 
    [Required(ErrorMessage="FirstName")] 
    public string FirstName { get; set; } 

    [Required(ErrorMessage = "LastName")] 
    public string LastName { get; set; } 

    public List<UnitViewModel> DesiredUnits { get; set; } 
} 

public class UnitViewModel 
{ 
    public Guid? UnitID { get; set; } 
    [Required(ErrorMessage = "NAMEEE")] 
    public string Name { get; set; } 

    public bool Selected { get; set; } 
} 

Lorsque je tente de créer un nouveau User je poste UserViewModel de mon point de vue. Ici, je reçois ModelState.IsValidfalse. Cela se produit parce que la validation vérifie également la propriété UnitViewModel.Name qui est null (et il est normal que je crée User et que j'ai la liste checkbox pour UnitViewModel. L'utilisateur sélectionne UnitViewModel de la liste existante UnitViewModel).

Je pourrais le réparer d'une manière horrible de ModelState["DesiredUnits[0].UnitID"].Errors.Clear() par boucle foreach mais je ne le ferai pas.

Alors, quelle serait la solution? Comment puis-je désactiver la validation de la liste des propriétés complexes d'un modèle?

MISE À JOUR
Une autre solution, je suis actuellement en utilisant, est d'avoir HiddenFor(m=>m.Name) dans le modèle de l'éditeur de UnitViewModel mais inconvénient de cette approche est que Name est inutile quand je l'ai déjà étiquette editortemplate. De plus, si j'avais d'autres champs obligatoires, je devrais avoir une entrée cachée correspondante pour chacun d'entre eux.

+0

pouvez-vous rendre votre vue de création d'une manière que vous n'avez aucun champ qui lient la propriété de DesiredUnits? Thant way La liste de UnitViewModel resterait vide et aucune validation de Name n'est faite –

+0

J'ai 'EditorTemplate' pour' DesiredUnits' qui a 'UnitID' et' Name'. Et lors de la création 'User' je dois le montrer puisqu'ils doivent choisir les unités désirées – levi

+0

essayez d'utiliser un DesiredUnits Nullable alors – maztt

Répondre

0

Si votre modèle de vue de requête contient des propriétés ou des règles de validation qui ne sont pas requises pour la vue spécifiée, vous devez créer un nouvel objet à cet effet.

// New model, specific for request 
public class UserRequestViewModel 
{ 
    [Required(ErrorMessage="FirstName")] 
    public string FirstName { get; set; } 

    [Required(ErrorMessage = "LastName")] 
    public string LastName { get; set; } 
} 

public ActionResult Index(UserRequestViewModel requestModel) 
{ 
    //... do something 

    // Get the values required to return to the view 
    var responseModel = new UserViewModel(); 
    responseModel.DesiredUnits = new List<UnitViewModel>(); 

    // Return the response model 
    return View(responseModel); 
} 

Si vous le faites de cette façon, il est clair pour tout le monde en développement pour votre application, ce qui est acceptable pour être affiché à votre action.

Alternativement, si vous décidez que vous ne pouvez pas nu pour créer un tout nouveau modèleà cet effet, déplacez votre validation dans l'action du contrôleur:

public ActionResult Index(UserViewModel requestResponseModel) 
{ 
    // Perform validation 
    for (var i = 0; i < requestResponseModel.DesiredUnits.Count(); i++) 
    { 
     var validationErrorKey = string.Format("DesiredUnits[{0}]", i); 

     // Is the Name property empty? 
     if (string.IsNullOrWhiteSpace(requestResponseModel.DesiredUnits[i].Name)) 
     { 


      this.ModelState.AddModelError("Posted Name cannot be empty", validationErrorKey); 
     } 
    } 

    if (this.ModelState.IsValid) 
    { 
     // There was a model validation error 
    } 

    //... do something 

    // Return the response model 
    return View(requestResponseModel); 
} 

En dernier recours, vous pouvez utiliser , mais je ne sais pas si cela empêche la validation du champ - vous aurez besoin de donner ce un aller:

public ActionResult Index([Bind(Exclude = "DesiredUnits")]UserViewModel requestResponseModel) 
{ 
    // ... do something 
} 
0

Utilisez

[HttpPost]  
    public ActionResult CreateEnquiryOnly([Bind(Include="FirstName,LastName")]UserViewModel userviewmodel) 
    { 
     if(ModelState.IsValid) 
     {  
     } 
    }