表单未绑定到正确的对象
Form is not binding to correct object
我有类似的对象(我正在使用 Model 和 ViewModel,其中 ViewModel 与 Model 对象具有相同的属性)。
当我编辑一个项目时,我为 viewmodel 和处理 update/edit 的控制器放置了编辑器,他接收 ViewModel:
[HttpPost]
public ActionResult Edit(DocumentViewModel model) {
Mapper.CreateMap < DocumentViewModel, BE.Document > ();
BE.Document instanceOfDestination = Mapper.Map < BE.Document > (model);
Container < BE.Document > container = BL.DocumentBL.UpdateDocument(instanceOfDestination);
if (!container.HasErrors) {
SetInfo("Saved!");
} else {
SetError(container.ErrorMessage);
}
return RedirectToAction("Index");
}
问题是此方法永远无法实现,因为模型联编程序构造 BE.Document 而不是 DocumentViewModel。
浏览器发送的值如下:
__RequestVerificationToken:xxx-dontcare
id:36
name:test flash files
documentType.id:5
unit.id:2
reference:FLASH0016
isActive:true
isActive:false
recyclingSpan:1
selectedTopics:1
selectedTopics:2
trainer.id:615952
selectedInstallations:1
selectedInstallations:2
selectedProfessions:3
selectedProfessions:4
selectedProfessions:6
这是 return 虚拟机制作编辑页面的控制器:
[HttpGet]
public ActionResult Edit(int id) {
var container = BL.DocumentBL.GetAllDocument(new BE.Document() {
id = id
});
if (!container.HasErrors) {
Mapper.CreateMap < BE.Document, DocumentViewModel > ();
DocumentViewModel instanceOfDestination = Mapper.Map < DocumentViewModel > (container.Value);
// fill values for dropdowns and co
instanceOfDestination.FillPredefinedValuesForUser(GetAdminOrVisibilityUnits());
return View(instanceOfDestination);
} else {
SetError(container.ErrorMessage);
return RedirectToAction("Index");
}
}
文档有模型和视图模型:
文档视图模型:
public int id { get; set; }
[Required]
public string name { get; set; }
[Required]
public string reference { get; set; }
[Required]
[Range(0, 100)]
public int recyclingSpan { get; set; }
[Required]
public bool isActive { get; set; }
[DocumentTypeValidator("DocType is required")] // custom validator
public DocumentType documentType { get; set; }
public PersonnelAM trainer { get; set; }
public List<DocumentVersion> versions { get; set; }
public List<Installation> installations { get; set; }
public List<Profession> professions { get; set; }
public List<Topic> topics { get; set; }
public Unit unit { get; set; }
// not used for edit or create
public PersonnelAM createdBy { get; set; }
public DateTime createdOn { get; set; }
public PersonnelAM editedBy { get; set; }
public DateTime editedOn { get; set; }
// to fill dropdowns
public IEnumerable<SelectListItem> documentTypeSelect { get; set; }
public IEnumerable<SelectListItem> personnelSelect { get; set; }
public IEnumerable<SelectListItem> installationsSelect { get; set; }
public IEnumerable<SelectListItem> professionsSelect { get; set; }
public IEnumerable<SelectListItem> topicTypeSelect { get; set; }
public IEnumerable<SelectListItem> unitSelect { get; set; }
// for multi-selects - uses FillListsFromIds to fill Lists from Ids
public int[] selectedProfessions { get; set; }
public int[] selectedInstallations { get; set; }
public int[] selectedTopics { get; set; }
// For file upload
[MinLengthAttribute(1)]
public HttpPostedFileBase[] files { get; set; }
// for file get
public List<string> filesList { get; set; }
BE.Document
public int id { get; set; }
public string name { get; set; }
public string reference { get; set; }
public int recyclingSpan { get; set; }
public bool isActive { get; set; }
public DocumentType documentType { get; set; }
public PersonnelAM trainer { get; set; }
public List<string> filesList { get; set; }
public List<Installation> installations { get; set; }
public List<DocumentVersion> versions { get; set; }
public List<Profession> professions { get; set; }
public List<Topic> topics { get; set; }
public Unit unit { get; set; }
public PersonnelAM createdBy { get; set; }
public DateTime createdOn { get; set; }
public PersonnelAM editedBy { get; set; }
public DateTime editedOn { get; set; }
感谢帮助我:-)
编辑:
这是完整的 Get/id 控制器
[HttpGet]
public ActionResult Edit(int id)
{
if (User.IsInRole("Admin") || User.IsInRole("Moderator") || SessionManager.matricule.IsDocumentCreator(id))
{
var container = BL.DocumentBL.GetAllDocument(new BE.Document() { id = id });
if (!container.HasErrors)
{
Mapper.CreateMap<BE.Document, DocumentViewModel>();
DocumentViewModel instanceOfDestination = Mapper.Map<DocumentViewModel>(container.Value);
// fill values for dropdowns and co
instanceOfDestination.FillPredefinedValuesForUser(GetAdminOrVisibilityUnits());
return View(instanceOfDestination);
}
else
{
SetError(container.ErrorMessage);
return RedirectToAction("Index");
}
}
else
{
SetError("Vous n'avez pas le droit d'accéder à l'édition de ce document.");
return RedirectToAction("Index");
}
}
编辑 2:
[HttpPost]
public ActionResult Edit(DocumentViewModel model)
{
if (User.IsInRole("Admin") || User.IsInRole("Moderator") || SessionManager.matricule.IsDocumentCreator(model.id))
{
Mapper.CreateMap<DocumentViewModel, BE.Document>();
BE.Document instanceOfDestination = Mapper.Map<BE.Document>(model);
Container<BE.Document> container = BL.DocumentBL.UpdateDocument(instanceOfDestination, new PersonnelAM() { id = SessionManager.matricule });
if (!container.HasErrors)
{
SetInfo("Modifications suavegardées");
}
else
{
model.FillPredefinedValuesForUser(GetAdminOrVisibilityUnits());
SetError(container.ErrorMessage);
return View(instanceOfDestination);
}
}
return RedirectToAction("Index");
}
请确保将视图模型绑定到您的视图(您的 cshtml 文件),而不是您的模型,在您的视图文件之上(例如 edit.cshtml):
@model your.namespace.DocumentViewModel
而不是
@model your.namespace.BE.Document
但是,如果视图模型与您的模型相同,为什么还要使用视图模型?为什么不直接使用你的模型呢
您的视图模型绑定正确,但在您的 POST 方法中,这行代码
return View(instanceOfDestination);
正在返回 Document
的实例(由 BE.Document instanceOfDestination = Mapper.Map<BE.Document>(model);
定义,而不是导致异常
的 DocumentViewModel
的实例
The model passed in the dictionary is of type BE.Document but this dictionary requires a model of type DocumentViewModel
改为
return View(model);
以便将正确的类型传递回视图。
我有类似的对象(我正在使用 Model 和 ViewModel,其中 ViewModel 与 Model 对象具有相同的属性)。
当我编辑一个项目时,我为 viewmodel 和处理 update/edit 的控制器放置了编辑器,他接收 ViewModel:
[HttpPost]
public ActionResult Edit(DocumentViewModel model) {
Mapper.CreateMap < DocumentViewModel, BE.Document > ();
BE.Document instanceOfDestination = Mapper.Map < BE.Document > (model);
Container < BE.Document > container = BL.DocumentBL.UpdateDocument(instanceOfDestination);
if (!container.HasErrors) {
SetInfo("Saved!");
} else {
SetError(container.ErrorMessage);
}
return RedirectToAction("Index");
}
问题是此方法永远无法实现,因为模型联编程序构造 BE.Document 而不是 DocumentViewModel。
浏览器发送的值如下:
__RequestVerificationToken:xxx-dontcare
id:36
name:test flash files
documentType.id:5
unit.id:2
reference:FLASH0016
isActive:true
isActive:false
recyclingSpan:1
selectedTopics:1
selectedTopics:2
trainer.id:615952
selectedInstallations:1
selectedInstallations:2
selectedProfessions:3
selectedProfessions:4
selectedProfessions:6
这是 return 虚拟机制作编辑页面的控制器:
[HttpGet]
public ActionResult Edit(int id) {
var container = BL.DocumentBL.GetAllDocument(new BE.Document() {
id = id
});
if (!container.HasErrors) {
Mapper.CreateMap < BE.Document, DocumentViewModel > ();
DocumentViewModel instanceOfDestination = Mapper.Map < DocumentViewModel > (container.Value);
// fill values for dropdowns and co
instanceOfDestination.FillPredefinedValuesForUser(GetAdminOrVisibilityUnits());
return View(instanceOfDestination);
} else {
SetError(container.ErrorMessage);
return RedirectToAction("Index");
}
}
文档有模型和视图模型:
文档视图模型:
public int id { get; set; }
[Required]
public string name { get; set; }
[Required]
public string reference { get; set; }
[Required]
[Range(0, 100)]
public int recyclingSpan { get; set; }
[Required]
public bool isActive { get; set; }
[DocumentTypeValidator("DocType is required")] // custom validator
public DocumentType documentType { get; set; }
public PersonnelAM trainer { get; set; }
public List<DocumentVersion> versions { get; set; }
public List<Installation> installations { get; set; }
public List<Profession> professions { get; set; }
public List<Topic> topics { get; set; }
public Unit unit { get; set; }
// not used for edit or create
public PersonnelAM createdBy { get; set; }
public DateTime createdOn { get; set; }
public PersonnelAM editedBy { get; set; }
public DateTime editedOn { get; set; }
// to fill dropdowns
public IEnumerable<SelectListItem> documentTypeSelect { get; set; }
public IEnumerable<SelectListItem> personnelSelect { get; set; }
public IEnumerable<SelectListItem> installationsSelect { get; set; }
public IEnumerable<SelectListItem> professionsSelect { get; set; }
public IEnumerable<SelectListItem> topicTypeSelect { get; set; }
public IEnumerable<SelectListItem> unitSelect { get; set; }
// for multi-selects - uses FillListsFromIds to fill Lists from Ids
public int[] selectedProfessions { get; set; }
public int[] selectedInstallations { get; set; }
public int[] selectedTopics { get; set; }
// For file upload
[MinLengthAttribute(1)]
public HttpPostedFileBase[] files { get; set; }
// for file get
public List<string> filesList { get; set; }
BE.Document
public int id { get; set; }
public string name { get; set; }
public string reference { get; set; }
public int recyclingSpan { get; set; }
public bool isActive { get; set; }
public DocumentType documentType { get; set; }
public PersonnelAM trainer { get; set; }
public List<string> filesList { get; set; }
public List<Installation> installations { get; set; }
public List<DocumentVersion> versions { get; set; }
public List<Profession> professions { get; set; }
public List<Topic> topics { get; set; }
public Unit unit { get; set; }
public PersonnelAM createdBy { get; set; }
public DateTime createdOn { get; set; }
public PersonnelAM editedBy { get; set; }
public DateTime editedOn { get; set; }
感谢帮助我:-)
编辑:
这是完整的 Get/id 控制器
[HttpGet]
public ActionResult Edit(int id)
{
if (User.IsInRole("Admin") || User.IsInRole("Moderator") || SessionManager.matricule.IsDocumentCreator(id))
{
var container = BL.DocumentBL.GetAllDocument(new BE.Document() { id = id });
if (!container.HasErrors)
{
Mapper.CreateMap<BE.Document, DocumentViewModel>();
DocumentViewModel instanceOfDestination = Mapper.Map<DocumentViewModel>(container.Value);
// fill values for dropdowns and co
instanceOfDestination.FillPredefinedValuesForUser(GetAdminOrVisibilityUnits());
return View(instanceOfDestination);
}
else
{
SetError(container.ErrorMessage);
return RedirectToAction("Index");
}
}
else
{
SetError("Vous n'avez pas le droit d'accéder à l'édition de ce document.");
return RedirectToAction("Index");
}
}
编辑 2:
[HttpPost]
public ActionResult Edit(DocumentViewModel model)
{
if (User.IsInRole("Admin") || User.IsInRole("Moderator") || SessionManager.matricule.IsDocumentCreator(model.id))
{
Mapper.CreateMap<DocumentViewModel, BE.Document>();
BE.Document instanceOfDestination = Mapper.Map<BE.Document>(model);
Container<BE.Document> container = BL.DocumentBL.UpdateDocument(instanceOfDestination, new PersonnelAM() { id = SessionManager.matricule });
if (!container.HasErrors)
{
SetInfo("Modifications suavegardées");
}
else
{
model.FillPredefinedValuesForUser(GetAdminOrVisibilityUnits());
SetError(container.ErrorMessage);
return View(instanceOfDestination);
}
}
return RedirectToAction("Index");
}
请确保将视图模型绑定到您的视图(您的 cshtml 文件),而不是您的模型,在您的视图文件之上(例如 edit.cshtml):
@model your.namespace.DocumentViewModel
而不是
@model your.namespace.BE.Document
但是,如果视图模型与您的模型相同,为什么还要使用视图模型?为什么不直接使用你的模型呢
您的视图模型绑定正确,但在您的 POST 方法中,这行代码
return View(instanceOfDestination);
正在返回 Document
的实例(由 BE.Document instanceOfDestination = Mapper.Map<BE.Document>(model);
定义,而不是导致异常
DocumentViewModel
的实例
The model passed in the dictionary is of type BE.Document but this dictionary requires a model of type DocumentViewModel
改为
return View(model);
以便将正确的类型传递回视图。