【问题标题】:Web API PUT missing fields set to nullWeb API PUT 缺少的字段设置为空
【发布时间】:2014-12-29 09:22:09
【问题描述】:

我有一个带有 PUT 方法的控制器,它通过 JSON 接受一组参数,然后更新数据库。但是,PUT 的默认行为似乎是,如果缺少参数,它将恢复为 null。

例如代码:

            // PUT: api/Business/5
        [ResponseType(typeof(void))]
        public async Task<IHttpActionResult> Putuser_business(int id, DTO_business_details dto_us_bus)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

//new code
                var dto_bus_details = await db.user_business.Select(us_bus =>
                new DTO_business_details()
                {
                    BusinessID = id,
                    BusinessName = us_bus.bus_name,
                    Address = us_bus.bus_address,
                    PhoneNumber = us_bus.bus_phone
                }).SingleOrDefaultAsync(us_bus=> us_bus.BusinessID == id);

            dto_us_bus.BusinessID = dto_bus_details.BusinessID;
            if (dto_us_bus.BusinessName == null) { dto_us_bus.BusinessName = dto_bus_details.BusinessName ; }
            if (dto_us_bus.Address== null) { dto_us_bus.Address= dto_bus_details.Address; }
            if (dto_us_bus.PhoneNumber == null) { dto_us_bus.PhoneNumber = dto_bus_details.PhoneNumber; }

            var user_business = new user_business()
            {
                bus_id = id,
                bus_name = dto_us_bus.BusinessName,
                bus_address = dto_us_bus.Address,
                bus_phone = dto_us_bus.PhoneNumber,

            };

            db.Entry(user_business).State = EntityState.Modified;

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!user_businessExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);

我发送的 JSON 可以正常工作,但是如果我发送 BusinessName 和 Address(即,如果我省略 PhoneNumber),它会将 PhoneNumber 更改为 null,而不是将 PhoneNumber 保留在数据库中。

我认为这是因为我将值设置为 DTO 值(因此,如果它们丢失,它将为空),但即使我不使用 DTO,行为也是一样的。我错过了什么还是这就是 PUT 的工作方式?

谢谢

编辑

我考虑过对 DB 进行 LINQ 选择,然后检查每个变量,如果它为空,则将其设置为从选择中获得的数据,但这不会像值实际通过一样工作作为用户的 null ,它将保留 DB 值。如果有一种方法可以确定 JSON 调用中是否缺少它而不是它是否为 null,这将起作用,但它似乎效率很低。

【问题讨论】:

    标签: asp.net asp.net-web-api dto put


    【解决方案1】:

    这与 PUT 无关。如果您不发布电话号码,则请求中不会有一个,因此绑定参数中不会有一个,无论动词如何。 MVC 框架不知道您的数据库中有什么或您希望它做什么。

    您可以先加载现有记录,然后只分配您想要更改的值。

    一个好的开始是为您的操作方法参数使用适当的视图模型,该参数仅包含该操作方法所需的属性(这也将有助于防止模型注入 - 人们包括您不想要的值包括)。

    如果您不知道要在编译时设置哪些字段,则必须将空值视为未更改更改为空。它不能真的意味着两者。如果您希望用户能够将值设置为 null,则必须执行以下操作:

    • 确保始终为“未更改”值发送非空值。
    • 接受一些特殊值来表示“删除”属性值。
    • 绑定到一些弱类型对象,例如可以检查属性是否存在的字典。
    • 使用不同的操作方法来设置不同的属性。

    如果您要控制请求,第一个选项将是最简单的。只需确保原始值在未更改的情况下在请求中发送即可。

    【讨论】:

    • 感谢您的回复,这是有道理的。我已经修改了代码以使其正常工作。如果用户不发送任何内容,它将使用存储在数据库中的值。如果他们想删除一个值,参数将发送但带有“”(即不为空)。它似乎真的效率低下。我现在将使用代码编辑 OP。
    • 好的,添加代码。如前所述,首先我从数据库加载值,然后检查用户是否留下空值(即留下参数)。如果他们这样做,它将值设置为 DB 值。当我用更多字段打表时,它会变得很长!
    猜你喜欢
    • 2012-01-03
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多