C# Newtonsoft.JSON条件属性源

C# Newtonsoft.JSON条件属性源,c#,.net,json,serialization,json.net,C#,.net,Json,Serialization,Json.net,我正在使用Newtonsoft JSON进行序列化和反序列化。 我有json表示字段,其中title属性表示显示名称: { "ID": { "type": "integer", "title": "ID Display Name" }, "TITLE": { "type": "string", "title": "Title Display name" }, "NAME": { "type": "string", "title"

我正在使用Newtonsoft JSON进行序列化和反序列化。 我有json表示字段,其中title属性表示显示名称:

{
  "ID": {
    "type": "integer",
    "title": "ID Display Name"
  },
  "TITLE": {
    "type": "string",
    "title": "Title Display name"
  },
  "NAME": {
    "type": "string",
    "title": "Name"
  },
  "CUSTOM_123": {
    "type": "string",
    "title": "CUSTOM_123",
    "formLabel": "CUSTOM_123 Display Name"
  }
  // ... etc
}
我有课:

public class Field
{
    public string Title { get; set; }
    public string Type { get; set; }
}
现在一切正常。但当字段名以“CUSTOM_”开头时,我需要从属性“formLabel”序列化“Title”


如何实现条件属性源?

如果JSON中的属性名称以
自定义
字符串开头,您可以将JSON解析为,然后枚举所有属性,将它们逐个反序列化为
字段
实例,并更新
标题

var json=JObject.Parse(jsonString); foreach(json.Properties()中的var属性) { var field=property.Value.ToObject(); if(property.Name.StartsWith(“自定义”)和&property.Value为JObject propertyObject) { field.Title=propertyObject[“formLabel”]?.Value(); } }
这种方法比编写自定义转换器更简单,我相信您可以使用Newtonsoft和custom
JsonConverter对对象进行反序列化

您的JSON结构是一个JSON对象,它包含多个子JSON对象(字段)。因此,当将其反序列化到.NET时,您可以为父级创建一个单独的类,该类将有一个
字段列表
。您还可以将JSON更改为数组而不是对象,并反序列化为
列表

IList fields=JsonConvert.DeserializeObject(json,new CustomJsonConverter());
公共类CustomJsonConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
IList字段=新列表();
JObject obj=JObject.Load(读卡器);
foreach(对象Children()中的JToken子对象)
{
字段=新字段();
JProperty fieldProp=(JProperty)子级;
JObject fieldValue=(JObject)fieldProp.Value;
字符串fieldName=fieldProp.Name;
if(fieldName.StartsWith(“自定义”)
{
field.Title=(字符串)fieldValue[“formLabel”];
field.Type=(字符串)fieldValue[“Type”];
}
其他的
{
field.Title=(字符串)fieldValue[“Title”];
field.Type=(字符串)fieldValue[“Type”];
}
字段。添加(字段);
}
返回字段;
}
公共覆盖布尔CanConvert(类型objectType)
{
返回true;
}
}
公共类字段
{
公共字符串标题{get;set;}
公共字符串类型{get;set;}
}

使用自定义JsonConverter就可以做到这一点,因此您将分离反序列化业务,并可以根据需要在Convert方法中包含更多业务。因此,在第一行中,牛顿软件通常将我们的对象序列化到字段中,然后为“custom_u2;”定制业务,工作小提琴

代码如下:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;

namespace testapp
{
    class Program
    {
        static void Main(string[] args)
        {
            string json = @"
        {
            ""ID"": {
                ""type"": ""integer"",
                ""title"": ""ID Display Name""
            },
            ""TITLE"": {
                ""type"": ""string"",
                ""title"": ""Title Display name""
            },
            ""NAME"": {
                ""type"": ""string"",
                ""title"": ""Name""
            },
            ""CUSTOM_123"": {
                ""type"": ""string"",
                ""title"": ""CUSTOM_123"",
                ""formLabel"": ""CUSTOM_123 Display Name""
            }
        }";
            List<Field> result = JsonConvert.DeserializeObject<List<Field>>(json, new JobInfoConverter());
        }



        public class Field
        {
            public string title { get; set; }
            public string type { get; set; }
        }

        public class JobInfoConverter : JsonConverter
        {
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                try
                {
                    List<Field> result = new List<Field>();
                    var content = JObject.Load(reader);
                    foreach (var prop in content.Properties())
                    {
                        var parsedValue = prop.Value.ToObject<Field>();
                        if (prop.Name.StartsWith("CUSTOM_"))
                        {
                            parsedValue.title = prop.Value["formLabel"].ToString();
                        }
                        result.Add(parsedValue);

                    }
                    return result;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }

            public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) => throw new NotImplementedException();

            public override bool CanConvert(Type objectType)
            {
                return true;
            }

            public override bool CanWrite => true;

        }
    }
使用Newtonsoft.Json;
使用Newtonsoft.Json.Linq;
使用制度;
使用System.Collections.Generic;
使用System.Collections.Specialized;
使用System.IO;
命名空间testapp
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串json=@”
{
“ID”:{
“”类型“”:“”整数“”,
“”标题“”:“”ID显示名称“”
},
“标题”:{
“”类型“”:“”字符串“”,
“标题”:“标题显示名称”
},
“姓名”:{
“”类型“”:“”字符串“”,
“标题”:“名称”
},
“海关”123“:{
“”类型“”:“”字符串“”,
“标题”:“自定义名称”,
“formLabel”“:”“自定义显示名称”
}
}";
List result=JsonConvert.DeserializeObject(json,new JobInfoConverter());
}
公共类字段
{
公共字符串标题{get;set;}
公共字符串类型{get;set;}
}
公共类JobInfoConverter:JsonConverter
{
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
尝试
{
列表结果=新列表();
var content=JObject.Load(读卡器);
foreach(content.Properties()中的var prop)
{
var parsedValue=prop.Value.ToObject();
if(prop.Name.StartsWith(“自定义”))
{
parsedValue.title=prop.Value[“formLabel”].ToString();
}
结果.Add(parsedValue);
}
返回结果;
}
捕获(例外情况除外)
{
返回null;
}
}
public override void WriteJson(JsonWriter writer,对象值,Newtonsoft.Json.JsonSerializer serializer)=>抛出新的NotImplementedException();
公共覆盖布尔CanConvert(类型objectType)
{
返回true;
}
public override bool CanWrite=>true;
}
}

}

如果同时提供标题和fromLable,会发生什么情况?@Gleb它是否回答了您的问题,您需要更多详细信息或信息?