Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按属性名和JsonProperty将JSON反序列化为对象_C#_.net_Json.net - Fatal编程技术网

C# 按属性名和JsonProperty将JSON反序列化为对象

C# 按属性名和JsonProperty将JSON反序列化为对象,c#,.net,json.net,C#,.net,Json.net,我在数据库中存储了大量JSON数据。 为了减小此数据的大小,我们使用[JsonProperty(“”)标记。 但是,传统属性仍然使用全名,将其更改为基于标记的系统需要大量的变通方法,以便在访问数据时缓慢地重建数据 是否有一种设置或简单的方法可以根据属性名称和JsonProperty标记反序列化到属性中 或者我必须编写一个自定义反序列化程序 例如: 这个JSON { "coins": { "Total": 1004 } } 将不会反序列化到此对象中 [JsonPr

我在数据库中存储了大量JSON数据。 为了减小此数据的大小,我们使用[JsonProperty(“”)标记。 但是,传统属性仍然使用全名,将其更改为基于标记的系统需要大量的变通方法,以便在访问数据时缓慢地重建数据

是否有一种设置或简单的方法可以根据属性名称和JsonProperty标记反序列化到属性中

或者我必须编写一个自定义反序列化程序

例如:

这个JSON

{
    "coins": {
        "Total": 1004
    }
}
将不会反序列化到此对象中

[JsonProperty("c")]
public Coins coins { get; set;}

public Class Coins
{
    public int Total { get; set;}
}
删除
[JsonProperty(“c”)]
允许它再次反序列化。
然而,要将现有数据转换为更节省空间的方法,我需要能够在JsonProperty标记处于打开状态时通过属性名读取现有数据。这里有一个通用反序列化类,可用于任何对象

public class JsonHelper
 {         
     public static string JsonSerializer<T> (T t)
     {
         DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
         MemoryStream ms = new MemoryStream();
         ser.WriteObject(ms, t);
         string jsonString = Encoding.UTF8.GetString(ms.ToArray());
         ms.Close();
         return jsonString;
     }  

     public static T JsonDeserialize<T> (string jsonString)
     {
         DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
         MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
         T obj = (T)ser.ReadObject(ms);
         return obj;
     }
 }
public类JsonHelper
{         
公共静态字符串JsonSerializer(T)
{
DataContractJsonSerializer ser=新的DataContractJsonSerializer(类型(T));
MemoryStream ms=新的MemoryStream();
ser.WriteObject(ms,t);
字符串jsonString=Encoding.UTF8.GetString(ms.ToArray());
Close女士();
返回jsonString;
}  
公共静态T JsonDeserialize(字符串jsonString)
{
DataContractJsonSerializer ser=新的DataContractJsonSerializer(类型(T));
MemoryStream ms=新的MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj=(T)ser.ReadObject(ms);
返回obj;
}
}
通过使用它,您可以将任何数据反序列化到任何类

Student student = JsonHelper.JsonDeserialize<Student>(jsonStudent);
Student-Student=JsonHelper.JsonDeserialize(jsonStudent);

有关示例的更多详细信息,我不确定我将遵循,但我认为发生的是您有以下JSON:

{
    "coins": {
        "Total": 1004
    }
}

像这样的模型:

公共类CoinsWrapper
{
[JsonProperty(“c”)]
公共硬币{get;set;}
}
公营硬币
{
公共整数总计{get;set;}
}
解决方案1-创建辅助属性

公共类CoinsWrapper
{
[JsonProperty(“c”)]
公共硬币{get;set;}
[JsonProperty(“硬币”)]
私人硬币legacyCoins{set{Coins=value;}}
}
然后,当您反序列化时,它会将值分配给硬币,当您序列化时,它会忽略legacyCoins


解决方案2-使用
JsonExtensionData
和反射自动“映射”

我决定从中得到一些乐趣。。。显然,你需要小心,因为如果你的名字有任何重叠,你可能会导致事情很容易爆发

void Main()
{
字符串json=@”{
“硬币”:{
总数:1004
}
}";
var wrapper=JsonConvert.DeserializeObject(json);
wrapper.Dump();
}
公共类CoinsWrapper:LegacyAutoMap
{
[JsonProperty(“c”)]
公共硬币{get;set;}
}
公共抽象类LegacyAutoMap
{
[JsonExtensionData]
专用词典_附加数据;
[已序列化]
私有void已序列化(StreamingContext上下文)
{
if(_additionalData==null)返回;
var properties=this.GetType().GetProperties();
foreach(附加数据中的var条目)
{
var prop=properties.FirstOrDefault(p=>p.Name.ToLowerInvariant()==entry.Key.ToLowerInvariant());
如果(prop==null)继续;
JToken token=entry.Value;
MethodInfo ifn=typeof(JToken).GetMethod(“ToObject”,新类型[0]).MakeGenericMethod(新[]{prop.PropertyType});
prop.SetValue(this,ifn.Invoke(token,null));
}
_additionalData=null;
}
}

解决方案3-引入与解决方案2相结合的新自定义属性

这是最灵活、可能也是最安全的解决方案。灵活,因为您可以提供多个备用名称,最安全的是,只有您指定的字段才会“自动映射”

void Main()
{
字符串json=@”
[
{
“硬币”:
{
总数:1004
}
},
{
“c”:
{
总数:1004
}
},
{
“coinz”:
{
总数:1004
}
}
]";
var wrapper=JsonConvert.DeserializeObject(json);
wrapper.Dump();
}
公共类CoinsWrapper:LegacyAutoMap
{
[JsonProperty(“c”)]
[货币名称(“硬币”)]
[AlternateJSONName(“coinz”)]
公共硬币{get;set;}
}
公营硬币
{
公共整数总计{get;set;}
}
公共抽象类LegacyAutoMap
{
[JsonExtensionData]
专用词典_附加数据;
[已序列化]
私有void已序列化(StreamingContext上下文)
{
if(_additionalData==null)返回;
var mappableProps=this.GetType()
.GetProperties()
.Where(p=>Attribute.IsDefined(p,typeof(AlternateJSONNameAttribute)))
.选择(p=>
{
var attrs=p.GetCustomAttributes(typeof(AlternateJSONNameAttribute)).Cast();
返回attrs.Select(attr=>new{AlternateName=attr.JSONKey.ToLowerInvariant(),Property=p});
})
.SelectMany(attrs=>attrs);
foreach(附加数据中的var条目)
{
var prop=mappableProps.FirstOrDefault(p=>p.AlternateName==entry.Key.ToLowerInvariant());
如果(prop==null)继续;
JToken token=entry.Value;
MethodInfo ifn=typeof(JToken).GetMethod(“ToObject”,新类型[0]).MakeGenericMethod(新[]{prop.Property.PropertyType});
SetValue(this,ifn.Invoke(token,null));
}
_additionalData=null;
}
}
[AttributeUsage(AttributeTargets.Pr
{
    "c": {
        "Total": 1004
    }
}