C# 具有可选字段的Post service属性,但如果为null或空,则需要更新
我正在使用C#中的Post端点,我希望所有字段都是可选的,但也希望将其更新为null/empty list。我知道这是一个很奇怪的要求。我可以将int和string数据类型设置为-1或一些默认字符串,但我发现列表或任何数据列表都有困难 我可以为条件更新添加任何额外的标志,但这会增加请求正文中的属性数量C# 具有可选字段的Post service属性,但如果为null或空,则需要更新,c#,json,webapi,C#,Json,Webapi,我正在使用C#中的Post端点,我希望所有字段都是可选的,但也希望将其更新为null/empty list。我知道这是一个很奇怪的要求。我可以将int和string数据类型设置为-1或一些默认字符串,但我发现列表或任何数据列表都有困难 我可以为条件更新添加任何额外的标志,但这会增加请求正文中的属性数量 如果有人做过类似的问题,有人能给我建议这个案例的解决方案吗。我知道解决方案会很棘手。如果您同时控制客户端和服务器,则可以使用请求的格式来管理它 假设您有这样一个对象: public class C
如果有人做过类似的问题,有人能给我建议这个案例的解决方案吗。我知道解决方案会很棘手。如果您同时控制客户端和服务器,则可以使用请求的格式来管理它 假设您有这样一个对象:
public class Customer {
public string Name { get; set; }
public int? Age { get; set; }
}
然后您可以管理两种请求。我将使用JSON格式解释它
{
"Name": null,
"Age": 12
}
在本例中,请求包含值“Name”,因此您将在数据库(或任何其他存储)中将其设置为null
在这种情况下,请求不包含值“Name”,因此ti表示它不需要更改
对于JSON格式,两个请求都是相同的(Name=null)。但在您的代码中,它们将以不同的方式工作
当然:
- 这不是一个标准,所以您必须自己做(JSON序列化程序/反序列化程序无法管理此场景)
- 因为它不是标准的,所以最好同时管理客户端和服务器端。如果您不遵守标准规则,请他人使用您的服务器可能是一个骗局
- 很抱歉耽搁了
让我试着用更多的代码来解释它
首先,我们要做一个通用方法,用从JSON字符串提取的数据填充通用对象
public static void FillObjectFromJson<T>(T objectToFill, string objectInJson)
where T : class
{
// Check parameters
if (objectToFill == null) throw new ArgumentNullException(nameof(objectToFill));
if (string.IsNullOrEmpty(objectInJson)) throw new ArgumentNullException(nameof(objectInJson));
// Deserialize in a typed object (helpful for the type converter)
var typed = JsonConvert.DeserializeObject<T>(objectInJson);
// Deserialize in an expando object (for check properties)
var expando = JsonConvert.DeserializeObject<ExpandoObject>(objectInJson);
// Converts the expando to dictionary for check all given properties
var dictionary = (IDictionary<string, object>)expando;
// Read all properties of the given object (the only one you can assign)
foreach (var property in typeof(T).GetProperties().Where(x => x.CanWrite))
{
// If dictionary contains the property, it was in the JSON string,
// so we have to replace it
if (dictionary.ContainsKey(property.Name))
{
var propValue = property.GetValue(typed);
property.SetValue(objectToFill, propValue);
}
}
}
然后,我们需要一种从存储器中提取要更新的数据的方法。在本例中,我们将简单地支持一个对象:
public static Person ReadPersonFromStorage()
{
return new Person
{
Name = "Name from storage",
Age = 44
};
}
最后,我们可以编写我们的测试方法:
// Example of JSON with explicit name (so we have to set it as null)
var personWithNameJson = "{ \"Name\" : null, \"Age\" : 24 }";
// Read the original value from the storage
var person = ReadPersonFromStorage();
Console.WriteLine(person); // We have the name
// Fills from JSON (it will replace the Name since it's in the JSON)
FillObjectFromJson(person, personWithNameJson);
Console.WriteLine(person); // The name is set to null
// Example of JSON without explicit name (so you have to leave it with the original value)
var personWithoutNameJson = "{ \"Age\" : 24 }";
// Read the original value from the storage
var otherPerson = ReadPersonFromStorage();
Console.WriteLine(otherPerson); // We have the name
// Fills from JSON (it won't replace the Name since it's NOT in the JSON)
FillObjectFromJson(otherPerson, personWithoutNameJson);
Console.WriteLine(otherPerson); // We still have the name since it's not in the JSON
我希望我的意思更清楚,我会帮助你
PS:对于这个示例,我使用Newtonsoft进行JSON反序列化。同意您的观点,但是我们有什么方法可以确定名称是显式传递的还是作为JSON中的空值传递的?
public static Person ReadPersonFromStorage()
{
return new Person
{
Name = "Name from storage",
Age = 44
};
}
// Example of JSON with explicit name (so we have to set it as null)
var personWithNameJson = "{ \"Name\" : null, \"Age\" : 24 }";
// Read the original value from the storage
var person = ReadPersonFromStorage();
Console.WriteLine(person); // We have the name
// Fills from JSON (it will replace the Name since it's in the JSON)
FillObjectFromJson(person, personWithNameJson);
Console.WriteLine(person); // The name is set to null
// Example of JSON without explicit name (so you have to leave it with the original value)
var personWithoutNameJson = "{ \"Age\" : 24 }";
// Read the original value from the storage
var otherPerson = ReadPersonFromStorage();
Console.WriteLine(otherPerson); // We have the name
// Fills from JSON (it won't replace the Name since it's NOT in the JSON)
FillObjectFromJson(otherPerson, personWithoutNameJson);
Console.WriteLine(otherPerson); // We still have the name since it's not in the JSON