【问题标题】:Json.NET serialize property on the same levelJson.NET 序列化同级属性
【发布时间】:2021-06-14 13:07:19
【问题描述】:

我有一个非常长且复杂的 JSON 发送到外部 Web 服务。
JSON 具有同一级别的所有属性:

public class Request
{
    [JsonProperty(PropertyName = "prop1a")]
    public string Prop1A;

    [JsonProperty(PropertyName = "prop2a")]
    public string Prop2A;
    
    [JsonProperty(PropertyName = "prop3a")]
    public string Prop3A;
    
    [JsonProperty(PropertyName = "prop1b")]
    public string Prop1B;

    [JsonProperty(PropertyName = "prop2b")]
    public string Prop2B;
    
    [JsonProperty(PropertyName = "prop3b")]
    public string Prop3B;
    
    // [...]
}

生成的 JSON:

// valid JSON
{ prop1a: "", prop2a: "", prop3a: "", prop1b: "", prop2b: "", prop3b: "" }

为了更好地工作,我在逻辑上将相似的属性分成了更小的类:

public class Request
{
    public AggregatedPropsA MyAggregatedPropsA;
    
    public AggregatedPropsB MyAggregatedPropsB;
}

public class AggregatedPropsA
{
    [JsonProperty(PropertyName = "prop1a")]
    public string Prop1A;

    [JsonProperty(PropertyName = "prop2a")]
    public string Prop2A;
    
    [JsonProperty(PropertyName = "prop3a")]
    public string Prop3A;
}

问题是json字符串现在是无效字符串,因为属性是在不同级别上序列化的:

// invalid JSON
{ MyAggregatedPropsA: { prop1a: "", prop2a: "", prop3a: ""}, MyAggregatedPropsB: { prop1b: "", prop2b: "", prop3b: "" } }

是否有可能使用第二个类结构获得像第一个这样的 JSON?

【问题讨论】:

标签: c# json json.net


【解决方案1】:
var obj = new { x = new { a = 1, b = 2 }, y = new { c = 3, d = 4 } };

Func<JToken, IEnumerable<JProperty>> flatten = null;

flatten = token => token.Concat(token.SelectMany(t => t.Children().SelectMany(y => flatten(y))))
                    .OfType<JProperty>()
                    .Where(p => p.Value is JValue || p.Value is JArray);


var dict = flatten(JToken.FromObject(obj))
           .ToDictionary(p => p.Name, p => p.Value);


var json = JsonConvert.SerializeObject(dict);

【讨论】:

  • 感谢 I4V,不幸的是这种方法不是很灵活,并且不允许我区分不同的属性。最好有一个属性来标记需要展平的属性。
  • @StockBreak 如果您解释问题中不清楚的flexible 部分,我可以发布另一个替代方案。
  • 我认为您误解了我的评论。我当然已经测试了您的解决方案(并且它有效),但它不适合,因为我的 all 我的内部对象都会被展平(我有需要照常嵌套的内部类)。正如我所说,拥有可以仅使用属性启用/禁用的东西会很好。谢谢!
  • @StockBreak 这是我的最终报价 :)
最近更新 更多