asp.net Core 2自定义模型绑定器与复杂模型
我有一个问题在asp.net核心2中构建一个自定义模型绑定器。 我读了这个Tutorial但这不是我所需要的。asp.net Core 2自定义模型绑定器与复杂模型
我有一个构建为例,换上github
我有一个简单的Person类这样的:
public class Person
{
public int ID { get; set; }
[Required]
public string Firstname { get; set; }
[Required]
public string Surename { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:dd.MMM.yyyy}")]
public DateTime DateOfBirth {get;set;}
[Required]
public Country Country { get; set; }
}
public class Country
{
public int ID { get; set; }
public string Name { get; set; }
public string Code { get; set; }
}
当我添加一个新的人,我可以用HTML选择标签选择国家。但select标签的价值是国家ID,我希望活页夹在数据库中查找并将合适的国家放入模型中。
在控制器中创建方法如下:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Firstname,Surename,DateOfBirth")] Person person, int Country)
{
ViewData["Countries"] = _context.Countries.ToList();
if (ModelState.IsValid)
{
_context.Add(person);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(person);
}
我还实现了IModelBinder将数据绑定:
public class PersonEntityBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
// here goes the fun
// looking for the countryId in the bindingContext
// binding everything else except the CountryID
// search the Country by countryID and put it to the model
return Task.CompletedTask;
}
}
的问题是,我怎么能做到这一点像我写的在Binder的评论中? 任何人的想法或最佳实践解决方案?
关于克里斯
首先,这是自定义模型活页夹的一个不好的用法。数据访问应该在控制器中进行,因为这是控制器的责任。其次,don't use [Bind]
。很认真。不要。这太可怕了,它会杀死小猫。
创建像一个视图模型:
public class PersonViewModel
{
public string FirstName { get; set; }
public string Surname { get; set; }
public DateTime DateOfBirth { get; set; }
public int CountryID { get; set; }
}
然后,你的行动接受这个,而不是(为[Bind]
不再需要):
public async Task<IActionResult> Create(PersonViewModel model)
然后,你的行动中,地图的发布值到Person
的新实例,并通过从数据库中查找来填充Country
属性:
var person = new Person
{
FirstName = model.FirstName,
Surname = model.Surname,
DateOfBirth = model.DateOfBirth,
Country = db.Countries.Find(model.CountryID)
}
然后,保存person
,照常。
好吧,我从一些Java框架知道的方式,在我看来这是最好的方法。看起来我不能信任Visual Studio的脚手架代码。谢谢 –
那么,脚手架只能做这么多。人们出错的地方是假定脚手架是它开始和结束的地方。重点是给你一个出发点。假设您将自定义代码并使其成为您自己的代码。 –
为什么你想做一些复杂的基本动作?只需添加属性public int CountryId {get;设置;}到你的模型,并在其上设置国家ID。实体框架将为你做其余的事情 – OrcusZ