【问题标题】:Response Serialization Issue响应序列化问题
【发布时间】:2019-04-19 15:35:51
【问题描述】:

我面临一个奇怪的问题,也许我在这里做错了什么。所以我正在使用 .Net Core 2.2 开发 WebApi 项目。并且我正在从另一台服务器调用 Api,并将响应解析到此模型中。

 public class LoginResponseModel
{
    [JsonProperty(PropertyName = "token_type")]
    public string tokenType { get; set; }

    [JsonProperty(PropertyName = "access_token")]
    public string accessToken { get; set; }

    [JsonProperty(PropertyName = "expires_in")]
    public string expiresIn { get; set; }

    [JsonProperty(PropertyName = "refresh_token")]
    public string refreshtToken { get; set; }
}

从上面的模型可以看出,我在 SnakeCase 中得到响应,并且我的模型参数在 CamelCase 中。当我反序列化我的 Api 响应时:

 T1 responseModel = JsonConvert.DeserializeObject<T1>(await response.Content.ReadAsStringAsync());

这里 T1LoginResponseModel 它成功地解析了我模型中的 Api 响应,请参见随附的屏幕截图,

但是当我调用我的 Api 时,它正在调用另一个我刚刚解析了其响应的 api(上例),返回的响应在 SnakeCase 中。见截图

澄清 只是为了澄清移动应用调用我的 Api 即 Login() 而我的 Login 方法从另一台服务器调用另一个 Api 即 AuthenticateUser(...)。所以 AuthenticateUser 的响应是 SnakeCase ,我将其解析为我的 LoginResponseModel 并且该响应作为 Login api 响应返回。但我得到的回应是 SnakeCase

有人可以告诉我我在这里缺少什么或者可以做些什么来解决这个问题。我不想使用另一个模型来转换为我想要的响应。

更新 @Darkonekt Answer 帮助了我,但现在我在序列化和反序列化方面面临另一个问题。所以这是我的 PostAsync

通用方法
private async Task<object> PostAsync<T1,T2>(string uri, T2 content)
    {
        using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri))
        {
            var json = JsonConvert.SerializeObject(content);
            using (var stringContent = new StringContent(json, Encoding.UTF8, "application/json"))
            {
                requestMessage.Content = stringContent;

                HttpResponseMessage response = await _client.SendAsync(requestMessage);
                if (response.IsSuccessStatusCode)
                {
                    _logger.LogInformation("Request Succeeded");
                    var dezerializerSettings = new JsonSerializerSettings
                    {
                        ContractResolver = new DefaultContractResolver
                        {
                            NamingStrategy = new SnakeCaseNamingStrategy()
                        }
                    };
                    T1 responseModel = JsonConvert.DeserializeObject<T1>(await response.Content.ReadAsStringAsync(), dezerializerSettings);
                    return  responseModel;
                }
                else
                {
                    return await GetFailureResponseModel(response);

                }
            }
        }
    }

由于此方法是通用的,将用于任何其他 Post 请求,但在这里我将 Deserializer 设置为 SnakeCase,并且当 api 响应在 SnakeCase 中时它工作正常,但是当我的其他 Post 请求以 CamelCase 返回响应时会出现问题.由于解析失败,我得到 Null 值。我该如何解决这个问题。

【问题讨论】:

  • 您可以尝试从这篇帖子stackoverflow.com/a/31484563/9448191创建映射类的方法
  • 您需要一个没有属性的新模型,以便它使用属性名称。并在返回结果之前映射到该模型。
  • 正如我在问题中提到的,不想使用其他模型来转换响应。
  • @Shabirjan 您只有两个选择:1 在返回之前重新映射或 2 合同序列化程序。除此之外,您无能为力。
  • @Shabirjan 至于你问题的第二部分。您可以使用多个合约解析器和设置......然后根据您调用的 API,您可以选择其中一个。

标签: c# asp.net-core


【解决方案1】:

[JsonProperty(PropertyName = "refresh_token")] 属性是一条双向街道。

在序列化和反序列化时应用。

如果您想在序列化时使用不同的名称,您将需要 ContractResolver 和您自己的设置。

查看这个 stackoverflow 问题,详细了解如何操作:Serialize and Deserialize with different property names

或者您将需要创建两个模型,一个用于序列化,一个用于反序列化并在它们之间进行映射,然后返回没有属性的模型。

【讨论】:

  • 谢谢。但对我来说,反序列化工作正常。问题是当我返回该响应时。这就是驼峰值转换为蛇形的时候。
  • @Shabirjan 我更正了我的答案。关键是当您“返回”该响应时,Json 序列化程序使用相同的属性来序列化响应。我的回答是正确的。看看我提供的链接。
  • @Shabirjan 您正在使用的该属性在反序列化和序列化时应用!这就是您的 API 返回该 json 的原因;因为它必须在返回之前序列化类。因此,如果您想返回不同的东西,您必须执行我在回答中提供的两个选项之一。在返回对象或使用合同解析器之前“映射”到新类。
  • 好的,您提供的链接确实帮助了我,我在使用反序列化时使用了 SnakeCase 策略,并删除了 JSONProperty 注释。现在我有另一个困惑,这个 api 在 SnakeCase 返回响应,但所有其他 Api 返回 camelCase 响应。我已经编写了用于 api 解析的通用方法。所以如果我将反序列化设置为 SnakeCase 并且 My Api 返回 CamelCase 会有什么问题吗?
  • 请检查我的问题中的更新部分。
猜你喜欢
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
相关资源
最近更新 更多