La coutume de la liaison de modèle, de modèle d'état, et les annotations de données

J'ai quelques questions au sujet de la coutume de la liaison de modèle, de modèle d'état, et les annotations de données.

1) Est-il redondant de faire la validation dans le modèle de liaison personnalisé si j'ai des données annotations sur mon modèle, parce que c'est ce que je pensais, le point de données annotations ont été.

2) Pourquoi mon contrôleur de traiter le modèle de l'état comme valide même quand il ne l'est pas, j'en ai principalement que le Nom de la propriété null ou trop court.

3) Est-il correct de penser à des classeurs de modèles personnalisés comme les méthodes constructeur, parce que c'est ce qu'ils me rappellent.

D'abord voici mon modèle.

public class Projects
{     
    [Key]
    [Required]
    public Guid ProjectGuid { get; set; }

    [Required]
    public string AccountName { get; set; }

    [Required(ErrorMessage = "Project name required")]
    [StringLength(128, ErrorMessage = "Project name cannot exceed 128 characters")]
    [MinLength(3, ErrorMessage = "Project name must be at least 3 characters")]
    public string Name { get; set; }

    [Required]
    public long TotalTime { get; set; }
}

Alors que je suis en utilisant un modèle de liaison personnalisé pour lier certaines propriétés du modèle. S'il vous plaît ne pas l'esprit que c'est rapide et sale juste essayer d'obtenir qu'elle fonctionne et ensuite le refactoring.

public class ProjectModelBinder : IModelBinder
{
     public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }
        var p = new Project();
        p.ProjectGuid = System.Guid.NewGuid();
        p.AccountName = controllerContext.HttpContext.User.Identity.Name;
        p.Name = controllerContext.HttpContext.Request.Form.Get("Name");
        p.TotalTime = 0;

        //
        //Is this redundant because of the data annotations?!?!
        //
        if (p.AccountName == null)
            bindingContext.ModelState.AddModelError("Name", "Name is required");

        if (p.AccountName.Length < 3)
            bindingContext.ModelState.AddModelError("Name", "Minimum length is 3 characters");

        if (p.AccountName.Length > 128)
            bindingContext.ModelState.AddModelError("Name", "Maximum length is 128 characters");

        return p;
    }
}

Maintenant mon contrôleur de l'action.

    [HttpPost]
    public ActionResult CreateProject([ModelBinder(typeof(ProjectModelBinder))]Project project)
    {
        //
        //For some reason the model state comes back as valid even when I force an error
        //
        if (!ModelState.IsValid)
            return Content(Boolean.FalseString);

        //_projectRepository.CreateProject(project);

        return Content(Boolean.TrueString);

    }

MODIFIER

J'ai Trouvé un code sur un autre stackoverflow question, mais je ne suis pas sûr à quel point je voudrais injecter les valeurs suivantes dans cette solution possible.

Ce que je veux injecter lorsqu'un nouvel objet est créé:

        var p = new Project();
        p.ProjectGuid = System.Guid.NewGuid();
        p.AccountName = controllerContext.HttpContext.User.Identity.Name;
        p.Name = controllerContext.HttpContext.Request.Form.Get("Name");
        p.TotalTime = 0;

Comment puis-je obtenir le code ci-dessus dans ce qui est ci-dessous (solution):

    public class ProjectModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(Project))
            {
                ModelBindingContext newBindingContext = new ModelBindingContext()
                {

                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
                        () => new Project(), //construct a Project object,
                        typeof(Project)         //using the Project metadata
                    ),
                    ModelState = bindingContext.ModelState,
                    ValueProvider = bindingContext.ValueProvider

                };

                //call the default model binder this new binding context
                return base.BindModel(controllerContext, newBindingContext);
            }
            else
            {
                return base.BindModel(controllerContext, bindingContext);
            }
        }

    }

}

OriginalL'auteur Odnxe | 2011-04-28