问题描述
对于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