Пользовательская привязка модели, состояние модели и аннотации данных

У меня есть несколько вопросов относительно привязки пользовательской модели, состояния модели и аннотаций к данным.

1) Излишне ли выполнять проверку в привязке пользовательской модели, если у меня есть аннотации данных в моей модели, потому что я думал, что это были точки аннотаций данных.

2) Почему мой контроллер обрабатывает состояние модели как действительное, даже если оно нет, в основном я делаю свойство Name нулевым или слишком коротким.

3) Можно ли думать о пользовательских связывателях модели как о методах конструктора, потому что это то, о чем они мне напоминают.

Сначала вот моя модель.

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; }
}

Затем я использую настраиваемый связыватель модели, чтобы связать некоторые свойства модели. Пожалуйста, не обращайте на это внимания » быстро и грязно, просто пытаясь заставить его работать, а затем реорганизуя его.

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;
    }
}

Теперь мое действие контроллера.

    [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);

    }

РЕДАКТИРОВАТЬ

Я нашел код в другом вопросе о переполнении стека, но я не уверен, в какой момент я бы ввел следующие значения в это возможное решение.

Что я хочу ввести при создании нового объекта:

        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;

Как мне добавить приведенный выше код в то, что ниже (Возможное решение):

    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);
            }
        }

    }

}

9
задан Community 23 May 2017 в 02:07
поделиться