尝试使用DataContractJsonSerializer反序列化JSON时出错

时间:2012-11-24 08:25:34

标签: c# .net json silverlight windows-phone-8

这个真让我难过。我正在尝试反序列化从ASP.NET Web服务获取的以下JSON字符串:

"{\"d\":{\"__type\":\"KPCServer.LogonResult\",\"User\":{\"UserId\":\"affaa328-5b53-430e-991a-22674ede6faf\",\"Email\":\"test@test.com\",\"Alias\":\"Mike\",\"FullName\":\"Mike Christensen\",\"Password\":\"secret\",\"Location\":\"Redmond, WA\",\"ImageUrl\":null,\"DateOfBirth\":\"\\/Date(-62135568000000)\\/\",\"LastLogon\":\"\\/Date(1350450228000)\\/\",\"UserSince\":\"\\/Date(1197980020000)\\/\",\"MailingList\":true,\"Bio\":\"Test\"},\"NewUser\":false,\"Ticket\":\"FJEjfje87fjef88fe8FAF8fA88fAjk+AFJ9fja9Fa9Ff99aJF9aFjfA99fjaBFJ7zqmlcHn9Dfw=\"}}"

我有以下类型:

public class User
{
   public Guid UserId { get; set; }
   public string Email { get; set; }
   public string Alias { get; set; }
   public string FullName { get; set; }
   public string Password { get; set; }
   public string Location { get; set; }
   public string ImageUrl { get; set; }
   public DateTime DateOfBirth { get; set; }
   public DateTime LastLogon { get; set; }
   public DateTime UserSince { get; set; }
   public bool MailingList { get; set; }
   public string Bio { get; set; }
}

[DataContract(Name="KPCServer.LogonResult")]
public class LogonResult
{
   [DataMember] public User User { get; set; }
   [DataMember] public bool NewUser { get; set; }
   [DataMember] public string Ticket { get; set; }
}

[DataContract]
[KnownType(typeof(LogonResult))]
public class Result<T>
{
   [DataMember]
   public T d { get; set; }
}

然后我尝试使用以下命令反序列化字符串:

using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
   DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Result<T>));
   Result<T> result = serializer.ReadObject(stream) as Result<T>;

   return result.d;
}

注意:在上述方法中,T的类型为LogonResult

但是,我在ReadObject上收到以下异常:

System.Runtime.Serialization.SerializationException was unhandled by user code
  HResult=-2146233076
  Message=JSON contains a '__type' member specifying the data contract name ':KPCServer.LogonResult'. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'KPCServer.LogonResult' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer. You can also often eliminate this error by avoiding the use of derived types where the JSON is produced.
  Source=System.ServiceModel.Web
  InnerException: 

如果我跑:

json = json.Replace("_type", "_blah");

然后一切正常。这是在Windows Phone 8上使用Silverlight。

1 个答案:

答案 0 :(得分:3)

这是因为:

"\"__type\":\"KPCServer.LogonResult\""

不包含数据协定命名空间。通过修改DataContractAttribute上的LogonResult来解决此问题:

[DataContract(Name = "KPCServer.LogonResult", Namespace="")]
public class LogonResult
{
    [DataMember]
    public User User { get; set; }
    [DataMember]
    public bool NewUser { get; set; }
    [DataMember]
    public string Ticket { get; set; }
}