C#Newtonsoft使用声明反序列化自定义对象?

问题描述

对于C#和.NET来说是新手,但对此我一直不屑一顾,将不胜感激。

我有以下简单的POCO:

  public class ApiKey
  {
    public ApiKey(string key,string owner,List<Claim> claims = null)
    {
      Key = key;
      OwnerName = owner;
      Claims = claims ?? new List<Claim>();
    }

    public string Key { get; }
    public string OwnerName { get; }
    public IReadOnlyCollection<Claim> Claims { get; set; }
  }

我可以创建一个具有该声明的对象的实例,并使用Newtonsoft对其进行序列化:

JsonConvert.SerializeObject(key)

并获得如下序列化的ApiKey:

"{\"Key\":\"94a5b81f-9837-4c5f-9821-3ebaedc6435d\",\"OwnerName\":null,\"Claims\":[{\"Issuer\":\"LOCAL AUTHORITY\",\"OriginalIssuer\":\"LOCAL AUTHORITY\",\"Properties\":{},\"Subject\":null,\"Type\":\"AdminClaim\",\"Value\":\"AdminClaim\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"}]}"

但是,如果尝试像这样用Newtonsoft反序列化该字符串:

JsonConvert.DeserializeObject<ApiKey>(serialized_key);

我收到以下错误

Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type System.Security.Claims.Claim. A class should either have a default constructor,one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Claims[0].Issuer',line 1,position 83.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader,JsonObjectContract objectContract,JsonProperty containerMember,JsonProperty containerProperty,String id,Boolean& createdFromNonDefaultCreator)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader,Type objectType,JsonContract contract,JsonProperty member,JsonContainerContract containerContract,Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader,Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list,JsonReader reader,JsonArrayContract contract,String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader,Object existingValue,String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader,Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract contract,Type objectType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader,JsonObjectContract contract,ObjectConstructor`1 creator,String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader,Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader,Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader,Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value,Type type,JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value,JsonSerializerSettings settings)

当我希望取回原始对象时,我首先进行了序列化。我缺少能够反序列化此对象的什么内容

谢谢!

编辑:Claim对象来自System.Security.Claims.Claim

编辑2:我希望能够序列化/反序列化整个ApiKey类,而不仅仅是声明部分。

编辑3:我无法修改ApiKey类。

解决方法

问题在于Claim类没有任何公共构造函数。最简单的解决方法是创建您自己的Claim类并将其反序列化:

class MyClaim : Claim {
    public MyClaim(string type,string value,string valueType,string issuer,string originalIssuer):
        base(type,value,valueType,issuer,originalIssuer){}
}

Claim claim = JsonConvert.DeserializeObject<MyClaim>(json);
,

您将必须编写一个自定义转换器,此答案中有一个Claim类的示例:https://stackoverflow.com/a/28155770/6881299