RestSharp不能正确反序列化JSON

5
我正在使用RestSharp来调用REST Web服务。我已经实现了自己的响应对象类,用于与RestSharp集成的自动序列化/反序列化一起使用。
我还添加了一个枚举映射,它可以正常工作。
这个类的问题是,当我发送一个正确的请求时,我会收到一个正确的响应,所以Response.Content包含我期望的内容,但反序列化过程不起作用。
Response.Content:
{
    "resultCode": "SUCCESS",
    "hub.sessionId": "95864537-4a92-4fb7-8f6e-7880ce655d86"
}
ResultCode属性正确映射到ResultCode.SUCCESS枚举值,但HubSessionId属性始终为null,似乎没有被反序列化。
我唯一可能看到的问题是JSON PropertyName中包含'.'。这可能是问题吗?这与不再是Newtonsoft.Json的新JSON Serializer有关吗?如何解决它? 更新 我发现Json Attributes完全被忽略了,因此也忽略了[JsonConverter(typeof(StringEnumConverter))]。因此,我认为默认Serializer自动执行枚举映射而不需要任何属性。 "hub.sessionId"属性的问题仍然存在。 这是我的代码
public class LoginResponse
{
    [JsonProperty(PropertyName = "resultCode")]
    [JsonConverter(typeof(StringEnumConverter))]
    public ResultCode ResultCode { get; set; }

    [JsonProperty(PropertyName = "hub.sessionId")]
    public string HubSessionId { get; set; }
}

public enum ResultCode
{
    SUCCESS,
    FAILURE
}

// Executes the request and deserialize the JSON to the corresponding
// Response object type.
private T Execute<T>(RestRequest request) where T : new()
{
    RestClient client = new RestClient(BaseUrl);

    request.RequestFormat = DataFormat.Json;

    IRestResponse<T> response = client.Execute<T>(request);

    if (response.ErrorException != null)
    {
        const string message = "Error!";
        throw new ApplicationException(message, response.ErrorException);
    }

    return response.Data;
}

public LoginResponse Login()
{
    RestRequest request = new RestRequest(Method.POST);
    request.Resource = "login";
    request.AddParameter("username", Username, ParameterType.GetOrPost);
    request.AddParameter("password", Password, ParameterType.GetOrPost);
    LoginResponse response = Execute<LoginResponse>(request);
    HubSessionId = response.HubSessionId; // Always null!
    return response;
}

在 newtonsoft json 中,“.” 在属性名称中从来不是问题。我可以这么说,因为最旧和最新的版本都可以很好地处理你的 JSON 示例。请参见 fiddle。https://dotnetfiddle.net/i0zmc0 它使用的是 v3.5.x 版本。您也可以尝试 8.x 版本。 - Nikhil Vartak
我会在我的代码中添加更多细节。 - Cheshire Cat
JsonProperty是一个Json.NET属性。如果序列化程序不是Json.NET,则JsonProperty属性将被忽略。那么新的序列化程序中等效的属性是什么? - Panagiotis Kanavos
我也有同样的想法,但是:1)我还使用了[JsonConverter(typeof(StringEnumConverter))]属性,它可以正常工作,因为映射到我的枚举类是正确的。2)我尝试使用[DeserializeAs(Name = "hub.sessionId")]属性,就像在RestSharp Wiki中建议的那样,但它也不起作用。 - Cheshire Cat
2个回答

9
使用自定义JSON序列化程序和反序列化程序解决了这个问题,使用的是Newtonsoft的JSON.NET。 我按照Philipp Wagner在这篇文章中所述的步骤进行操作。 我还注意到,使用默认的序列化程序对Request进行序列化时,枚举类型并没有按预期工作。它不是序列化枚举字符串值,而是将枚举int值放在其中,该值是从我的枚举定义中取出的。 现在,使用JSON.NET正确地进行序列化和反序列化过程。

0

现在,RestSharp 中默认的 JSON 序列化器使用的是 System.Text.Json,它是自 .NET 6 以来的一部分。因此,您现在可以简单地使用属性 JsonPropertyName 来装饰 DTO 类中的属性。

以下是 DTO 类的示例:

using System.Text.Json.Serialization;

public class FacebookAuthResponse
{
    [JsonPropertyName("access_token")]
    public string AccessToken { get; set; } = null!;
    [JsonPropertyName("token_type")]
    public string TokenType { get; set; } = null!;
    [JsonPropertyName("expires_in")]
    public int ExpiresIn { get; set; }
}

这里是一个关于如何发送请求并进行反序列化的示例:

using RestSharp;

public class FacebookAuthService : IFacebookAuthService
{
    readonly string _clientId;
    readonly string _clientSecret;
    readonly string _redirectUri;
    readonly RestClient _client;

    public FacebookAuthService(string clientId, string clientSecret, string redirectUri)
    {
        _clientId = clientId;
        _clientSecret = clientSecret;
        _redirectUri = redirectUri;
        _client = new RestClient("https://graph.facebook.com/v16.0");
    }

    public FacebookAuthResponse? GetAccessToken(string code)
    {
        var request = new RestRequest("oauth/access_token", Method.Get);
        request.AddParameter("client_id", _clientId);
        request.AddParameter("client_secret", _clientSecret);
        request.AddParameter("redirect_uri", _redirectUri);
        request.AddParameter("code", code);
        var response = _client.Execute<FacebookAuthResponse>(request);
        return response.Data;
    }
}

请注意,客户端只需像这样实例化:
new RestClient("https://graph.facebook.com/v16.0")

在上面的代码中,请求是这样发出的:

_client.Execute<FacebookAuthResponse>(request);

无需定义任何自定义序列化程序/反序列化程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接