无法将'Newtonsoft.Json.Linq.JObject'强制转换为实际类型

时间:2018-01-04 11:19:15

标签: c# json linq deserialization

我有以下代码从我的服务器获取响应。我可以反序列化对我的ApiResponse对象类型的响应,但我不能将内部对象强制转换为它的真实类型。

以下是我从服务器获取响应的地方:

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    var result = streamReader.ReadToEnd();
    GlobalTestVariables.Response = JsonConvert.DeserializeObject<ApiResponse>(result);
    var a = GlobalTestVariables.Response.Result as TokenModel; // a = null
}

var result = streamReader.ReadToEnd();的值如下:

var result = "{\"IsSuccess\":true,\"Message\":\"Login Successful\",\"Result\":{\"id_token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6InBsaW10ZXN0aW5nIiwibmJmIjoxNTE1MDc5NzMyLCJleHAiOjE1MTUwODA5MzIsImlhdCI6MTUxNTA3OTczMn0.wcr5zndSwdrDL7huea_oWpAl8ohL0GL3NZOmc_VBduc\"},\"Status\":200}"

这是返回的内容:

return new ApiResponse(true, HttpStatusCode.OK, "Login Successful", new TokenModel(JwtManager.GenerateToken(user.Username)));

ApiResponse是:

[DataContract]
public class ApiResponse
{
    [DataMember]
    public bool IsSuccess { get; set; }
    [DataMember]
    public String Message { get; set; }
    [DataMember(EmitDefaultValue = false)]
    public Object Result { get; set; }
    [DataMember]
    public int Status { get; set; }

    public ApiResponse() { }

    public ApiResponse(bool isSuccess, HttpStatusCode statusCode, string message = null, object result = null)
    {
        IsSuccess = isSuccess;
        Status = (int)statusCode;
        Result = result;
        Message = message;
    }
}

TokenModel是:

public class TokenModel
{
    public string id_token { get; set; }
    public TokenModel(string token)
    {
        this.id_token = token;
    }
    public TokenModel() { }
}

有人知道如何将其反序列化为正确的类型吗?

2 个答案:

答案 0 :(得分:0)

有两种选择:

  1. 您将ApiResponse.Result的类型更改为TokenModel。然后,反序列化程序需要TokenModel并将其正确反序列化。

  2. 如果属性Result的类型是动态的,则需要在序列化的JSON字符串中包含类型信息。为此,请查看TypeNameHandling设置。

答案 1 :(得分:0)

只要Result在JSON中始终有id_token,就像将Result更改为TokenModel一样简单。

    [DataContract]
public class ApiResponse
{
    [DataMember]
    public bool IsSuccess { get; set; }
    [DataMember]
    public String Message { get; set; }
    [DataMember(EmitDefaultValue = false)]
    public TokenModel Result { get; set; }
    [DataMember]
    public int Status { get; set; }

    public ApiResponse() { }

    public ApiResponse(bool isSuccess, HttpStatusCode statusCode, string message = null, TokenModel result = null)
    {
        IsSuccess = isSuccess;
        Status = (int)statusCode;
        Result = result;
        Message = message;
    }
}