首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C# Newtonsoft反序列化带有声明的自定义对象?

C# Newtonsoft反序列化带有声明的自定义对象?
EN

Stack Overflow用户
提问于 2020-08-28 21:24:13
回答 2查看 1.9K关注 0票数 3

我有以下简单的POCO:

代码语言:javascript
复制
  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序列化它:

代码语言:javascript
复制
JsonConvert.SerializeObject(key)

并获得一个序列化的ApiKey,如下所示:

代码语言:javascript
复制
"{\"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对该字符串进行反序列化,如下所示:

代码语言:javascript
复制
JsonConvert.DeserializeObject<ApiKey>(serialized_key);

我得到以下错误:

代码语言:javascript
复制
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, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, 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)

当我希望取回原来的对象时,我首先序列化了它。为了能够反序列化这个对象,我遗漏了什么?

谢谢!

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

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

编辑3:我不能修改ApiKey类。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-28 22:01:00

你必须编写一个自定义的转换器,在这个答案中有一个Claim类的例子:https://stackoverflow.com/a/28155770/6881299

票数 3
EN

Stack Overflow用户

发布于 2020-08-28 21:29:37

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

代码语言:javascript
复制
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);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63634652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档