Web API PUT缺少字段设置为null

时间:2014-12-29 09:22:09

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

我有一个带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的工作方式?

由于

修改

我考虑过对数据库进行LINQ选择,然后检查每个变量&amp;如果它为null,则将其设置为从select中获取的数据,但是这不会起作用,就好像该值实际上是来自用户的null,它将使DB值保持原样。如果有一种方法我可以确定JSON调用中是否缺少它而不是它是否为空,这将起作用,但它看起来效率很低。

1 个答案:

答案 0 :(得分:1)

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

由您首先加载现有记录,然后仅分配您要更改的值。

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

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

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

如果您正在控制请求,第一个选项将是最简单的。如果原始值未更改,请确保在请求中发送原始值。