首页 > 解决方案 > 如何使用 asp.net 核心捕获 JSON Web api 请求中包含的属性名称?

问题描述

我正在构建一个 asp.net 核心 web 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" ]

我正在阅读 Microsoft 关于JSON 的自定义转换器的文档,但似乎我需要重写整个 json 转换器只是为了添加一些额外的功能。有什么方法可以“插入”现有的转换器,只是为了捕获包含的属性名称?

标签: c#jsonasp.net-corejsonconverter

解决方案


这可以通过反射和递归来解决。如果您不介意在每个控制器中再添加一行,则可以在模型绑定后调用此函数:

void PopulateIncludedProperties(IIncludedProperties obj)
{
    var properties = obj.GetType().GetProperties().ToList();
    obj.IncludedProperties = properties
        .Where(p => p.Name != "IncludedProperties" && p.GetValue(obj) != null)
        .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>


推荐阅读