简体   繁体   English

部分更新期间ASP.NET Web API中的显式vs.隐式null

[英]Explicit vs. implicit null in ASP.NET Web API during partial updates

I have been experimenting with Web API 2 for the past couple of weeks and I'm trying to figure out the best way to handle a particular scenario during partial updates. 在过去的几周中,我一直在尝试使用Web API 2,并且我试图找出在部分更新期间处理特定场景的最佳方法。

The API will allow the user to do partial updates via POST. 该API将允许用户通过POST进行部分更新。 By design, any properties that are not supplied in the request body are assumed to be unchanged and no changes will be made to those properties. 通过设计,请求主体中未提供的任何属性都假定为不变,并且不会对这些属性进行任何更改。

The challenge, however, is trying to determine when a user has explicitly set a property value to null. 但是,挑战在于尝试确定用户何时将属性值显式设置为null。 When the request body is pulled in via the controller, any absent properties are set as null automatically as the JSON request body is deserialized. 通过控制器拉入请求正文时,随着反序列化JSON请求正文,所有不存在的属性都会自动设置为null。 As such, I lose my ability to determine if the property value is null explicitly (ie the user is trying to set the property value as null, in which case I want to update the property to null) or if the property value is null implicitly (ie the property value was set to null during deserilaization, in which case I want to ignore it). 因此,我无法确定属性值是否显式为null(即,用户试图将属性值设置为null,在这种情况下,我想将属性更新为null),或者属性值隐式为null (即在反序列化期间将属性值设置为null,在这种情况下,我想忽略它)。

I am looking for any ideas of how I might approach this situation. 我正在寻找有关如何应对这种情况的任何想法。

I have played around with this a bit and I have come up with a way to work around this. 我对此进行了一些尝试,并提出了解决此问题的方法。 Maybe there's another way to address the issue but this seems to be a reasonable approach: 也许还有另一种方法可以解决该问题,但这似乎是一种合理的方法:

In Web API, the request body can only be read once. 在Web API中,请求正文只能读取一次。 Therefore, if you have the controller pull the object in for you, the object will be deserialized and you will lose access to the original request content and will not be able to determine if something was explicitly null or absent. 因此,如果让控制器为您拉入对象,则该对象将被反序列化,并且您将失去对原始请求内容的访问权限,并且将无法确定某些内容明确为空还是不存在。 This is demonstrated by something like this: 这可以通过以下示例得到证明:

[Route("cars"), HttpPost]
public IHttpActionResult AddCar(Car car)
{
Car newCar = Car.Add(car);
return Created<Car>("/cars/" + newCar.car_id, newCar);
}

If you want to be able to examine exactly what was sent in, you don't have the controller pull in the object for you, instead, you pull the request body in manually, thus preserving your ability to see exactly what was sent in, like this: 如果您希望能够准确检查发送的内容,则不必让控制器为您拉入对象,而是手动拉入请求正文,从而保留了准确查看发送的内容的能力,像这样:

[Route("cars"), HttpPost]
public IHttpActionResult AddCar()
{
HttpContent content = Request.Content;
string carJson = content.ReadAsStringAsync().Result;

// You now have the original JSON and can examine it before deserialization

}

It certainly adds a few more steps, but at least in my case where I needed to be able to see exactly what was POSTed, this provides a solution that seems to work. 它当然增加了一些步骤,但是至少在我需要能够准确查看POST内容的情况下,这提供了一个似乎可行的解决方案。

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

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