我正在构建一个asp.net核心网络api,并且我需要跟踪JSON主体中实际包含的属性,因为.NET没有像javascript一样具有未定义的概念,只是null。
我创建了一个所有模型都实现的接口,这只是一个名为IncludedProperties的字符串数组:
string[] IncludedProperties {get; set;}
我可能有其中嵌套了更多这些模型的模型。每当我反序列化其中一个模型时,我都希望它填充此IncludedProperties列表。
例如,在我的控制器中:
public async Task<ActionResult> PatchModel([FromRoute]Guid id, [FromBody] RootModel model) { ... }
并且类定义为:
public class RootModel : IIncludedProperties
{
public string Name { get; set;}
public string Description {get; set;}
public NestedModel SubEntity { get; set;}
public string[] IncludedProperties {get; set;}
}
public class NestedModel : IIncludedProperties
{
public string Name {get; set;}
public decimal Value {get; set;}
public string[] IncludedProperties {get; set;}
}
如果JSON主体如下:
{
"Name": "New Entity 01",
"SubEntity": {
"Name": "Child Entity 01",
"Value": 0.5
}
}
根的包含属性为[ "Name", "SubEntity"]
,嵌套模型的包含属性为[ "Name", "Value" ]
。
我正在阅读custom converters for JSON上来自Microsoft的文档,但似乎我将需要重写整个json转换器,以添加一些额外的功能。有什么办法可以“插入”现有的转换器,以捕获所包含的属性名称?
这可以通过反射和递归解决。如果您不介意在每个控制器内添加一行,则可以在模型绑定后调用此函数:
void PopulateIncludedProperties(IIncludedProperties obj)
{
var properties = obj.GetType().GetProperties().ToList();
obj.IncludedProperties = properties
.Where(p => p.Name != "IncludedProperties")
.Select(p => p.Name).ToArray();
foreach (var prop in properties)
{
var value = prop.GetValue(obj);
if (value is IIncludedProperties includedPropValue)
{
PopulateIncludedProperties(includedPropValue);
}
}
}
如果要填充IncludedProperties
中的IEnumerable<IIncludedProperties>
,请自定义您的个人名称>