You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#解析JSON查找属性:ASP.Net Web API可变Payload提取PersonId最优方案

ASP.NET Web API 跨结构Payload提取PersonId的优化方案

你当前使用SelectToken指定路径的方案本身可以满足需求,以下是3种适配不同场景的更优选择,可根据你的项目约束选用:

方案1:标记接口+显式实现(优先推荐)

这是性能最高、可维护性最好的方案,适合可以修改现有ViewModel代码的场景:

  • 定义统一标记接口 IHasPersonId:
public interface IHasPersonId
{
    int PersonId { get; }
}
  • 所有包含PersonId的ViewModel实现该接口,不管PersonId在结构的哪一层,都可以直接映射到该属性:
// 嵌套结构的ViewModel示例
public class CreateOrderViewModel : IHasPersonId
{
    public UserInfo User { get; set; }
    // 直接映射嵌套的PersonId
    public int PersonId => User.Person.Id;
}
  • 在日志中间件/Action过滤器中,拿到模型绑定完成的对象后,直接判断是否实现IHasPersonId接口即可取值,无需解析JSON,性能远高于字符串路径匹配,且修改ViewModel结构时编译器会自动校验取值逻辑。

方案2:递归JSON属性匹配(无侵入推荐)

如果不能修改现有ViewModel,且Payload中PersonId不会出现重名场景,可以用递归遍历JToken的方式自动查找取值,完全不需要维护任何路径配置:

public static bool TryExtractPersonId(JToken payload, out int personId)
{
    personId = default;
    if (payload is JObject jObj)
    {
        foreach (var prop in jObj.Properties())
        {
            if (prop.Name.Equals(nameof(PersonId), StringComparison.OrdinalIgnoreCase))
            {
                return prop.Value.Type == JTokenType.Integer && int.TryParse(prop.Value.ToString(), out personId);
            }
            if (TryExtractPersonId(prop.Value, out personId))
            {
                return true;
            }
        }
    }
    else if (payload is JArray jArr)
    {
        foreach (var item in jArr)
        {
            if (TryExtractPersonId(item, out personId))
            {
                return true;
            }
        }
    }
    return false;
}

该方案适配任意结构的Payload,只要存在符合命名要求的PersonId就可以自动提取,仅在单个Payload存在多个同名PersonId时可能出现取值偏差。

方案3:Action级路径标记

如果存在PersonId重名场景,不想在全局维护路径映射表,可以用自定义Attribute把路径和接口绑定在一起,降低维护成本:

  • 定义路径标记Attribute:
[AttributeUsage(AttributeTargets.Method)]
public class PersonIdPathAttribute : Attribute
{
    public string Path { get; }
    public PersonIdPathAttribute(string path) => Path = path;
}
  • 在对应Action上标记路径:[PersonIdPath("Order.SubmitUser.PersonId")]
  • 日志阶段先从当前Action的元数据中拿到路径,再调用SelectToken取值即可。

内容的提问来源于stack exchange,提问作者Raghul Raman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 10:24:02