У меня есть несколько вопросов относительно привязки пользовательской модели, состояния модели и аннотаций к данным.
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);
}
}
}
}