仅更新某些属性时,是否需要为整个模型添加隐藏字段?

问题描述 投票:0回答:1

考虑此模型和视图模型:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
}

public class PersonViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
}

仅用于编辑电子邮件的表单:

<form asp-action="UpdateEmail">
    <input type="hidden" asp-for="Id" />
    <label asp-for="Email"></label>
    <input asp-for="Email" />
    <button type="submit">Update e-mail address</button>
</form>

UpdateEmail() POST控制器方法:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UpdateEmail(int id, [Bind("Id,Email")] Person person)
{
    if (id != person.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            db.Update(person);
            await db.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            // ... stuff
        }
        return RedirectToAction("Details", new { id = person.Id });
    }
    return View(auto.Map<PersonViewModel>(person));
}

根据我的经验,在这种情况下,Email以外的所有其他属性都将被NULL值覆盖。我真的必须将它们添加为表单中的隐藏字段吗?如果是这样,那么使用[Bind("Id,Email")]有什么意义?

c# asp.net-core-mvc model-binding
1个回答
0
投票

您的表单仅包含字段名称IdEmail,因此只有这些值将被发送回Web服务器(和操作方法)。 ASP.NET MVC机械师可以将这些值填充到您提供的对象/类中,在本例中为Person对象,但所有其他值保持未定义状态,并具有其默认值(如null0等) 。)。

您可以更改UpdateEmail()方法签名以将表单数据保存在单独的参数中,例如:

public async Task<IActionResult> UpdateEmail(int id, string email)

从那里您可以从数据库中加载实体并更改值(or doing it directly)。

如果要使用一个对象而不是每个表单元素都具有多个参数,则可以定义一个新模型并使用它:

public class UpdateEmailModel
{
    public int Id { get; set; }
    public string Email { get; set; }    
}

然后您可以将方法更改为:

public async Task<IActionResult> UpdateEmail(UpdateEmailModel model)

或者您也可以将类型更改为PersonViewModel,因为无论如何这都是您要使用return View(auto.Map<PersonViewModel>(person));发送的型号。但这在某种程度上有点“过大杀伤力”,因为您向HTML表单发送的数据比使用它要多,但是这可能还可以,取决于您对“未使用”数据的处理方式。也许您应该使用return View(auto.Map<UpdateEmailModel>(person));将代码更改为新模型。

作为建议,您不应将Person实体用作表单数据的接收类/对象。这样,数据库中的列将指示如何命名HTML表单。这也意味着出于某种原因,HTML视图部分对存储数据的数据库有某种依赖性,而不应这样做。它仅应与控制器部件中定义的模型一起使用。但这只是一个建议,显然是基于意见的。

© www.soinside.com 2019 - 2024. All rights reserved.