繁体   English   中英

asp.net Core 2自定义模型Binder,具有复杂的模型

[英]asp.net Core 2 Custom Model Binder with complex model

我在asp.net core 2中构建一个Custom-Model-Binder时遇到了问题。我读过这个教程,但这不是我需要的。

我有一个构建示例并放在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标签的值是国家标识,我希望绑定器在数据库中查找并将正确的国家/地区放入模型中。

Controller中的create方法如下所示:

    [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的评论中写的那样? 任何想法或最佳实践解决方案?

对克里斯说

首先,这是对自定义模型绑定器的错误使用。 数据访问应该在控制器中进行,因为这是控制器的责任。 其次, 不要使用[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 ,为正常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM