Custom Modell-Bindung, Modell, Zustand und Daten Anmerkungen
Ich habe ein paar Fragen bezüglich custom-Modell der Bindung, Modell, Zustand und Daten-Anmerkungen.
1) Ist es überflüssig, das zu tun-Validierung in der custom-Modell der binder, wenn ich Daten-Anmerkungen zu meinem Modell, denn das ist, was ich dachte, der Punkt der Daten Anmerkungen wurden.
2.) Warum ist mein controller die Behandlung der Modell-Staat als gültig, auch wenn es nicht, vor allem habe ich die Name-Eigenschaft null oder zu kurz.
3) Ist es ok zu denken, custom-Modell Bindemittel als Konstruktor-Methoden, weil es das ist, was Sie erinnern mich an.
Erste ist hier mein Modell.
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; }
}
Dann bin ich mit einem benutzerdefinierten Modell-Bindemittel zum binden einige Eigenschaften des Modells. Bitte nicht daran, dass es schnell und schmutzig, nur versuchen, es funktioniert und dann die Umgestaltung es.
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;
}
}
Nun meine controller-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);
}
BEARBEITEN
Fand ich einige code auf einem anderen stackoverflow-Frage, aber ich bin mir nicht sicher, an welchem Punkt ich würde injizieren Sie die folgenden Werte in dieser mögliche Lösung des Problems.
Was ich will, um zu injizieren, wenn ein neues Objekt erstellt wird:
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;
Wie bekomme ich den oben genannten code in das, was ist unten (Mögliche Lösung):
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);
}
}
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Finden Sie Dinge, die die Arbeit viel einfacher, wenn Sie Erben von der
DefaultModelBinder
überschreiben Sie dieBindModel
- Methode, rufen Sie diebase.BindModel
- Methode, und stellen Sie dann die manuellen änderungen (einstellen des guid, den Kontonamen und die Gesamtzeit).1) Es ist überflüssig, zu überprüfen, wie Sie es getan haben. Sie können code schreiben zu reflektieren, die Validierung von Metadaten viel wie der Standard es tut, oder entfernen Sie einfach die Daten-Annotationen Validierung, da Sie es nicht verwenden in Ihrem Modell binder.
2) ich weiß nicht, es scheint korrekt zu sein, sollten Sie Schritt für Schritt durch den code, und stellen Sie sicher, dass Ihre benutzerdefinierte binder Auffüllen alle geltenden Regeln.
3) Es ist eine Fabrik für sicher, aber nicht so viel ein Konstruktor.
EDIT: Sie könnte nicht näher an der Lösung, nur die Eigenschaften müssen Sie in der Modell-Fabrik-Funktion
Oder Sie könnte alternativ überschreiben Sie die
CreateModel
Methode:CreateModel
Methode, da das genau das ist, was Sie versuchen, zu überschreiben. In der anderen Frage, die Sie verknüpfte, war die person versucht, die Metadaten über eine Schnittstelle zu validieren, die eine konkrete Umsetzung, und daher benötigt, um das überschreiben der Metadaten-Anbieter. DieCreateModel
code ist auch weniger verwirrend.