【问题标题】:.Net Core API Response convert variables.Net Core API Response 转换变量
【发布时间】:2019-09-11 00:19:59
【问题描述】:

我正在调用一个以我不想要的方式返回属性的 API。所以 API 响应如下所示:

{
  "access_token": "sdfsdfsdfsdfsdfds",
  "expires_in": 3200
}

我想像这样退货:

{
  accessToken: "sdfsdfsdfsdfsdfds",
  expiresIn: 3200
}

这是模型

public class Token
{
  [JsonProperty("access_token")]
  public string accessToken { get; set; }

  [JsonProperty("expires_in")]
  public int expiresIn { get; set; }

  [JsonProperty("token_type")]
  public string tokenType { get; set; }
}

这是正在调用的控制器

var response = await client.SendAsync(request);

string tokenString = await response.Content.ReadAsStringAsync();
Token token = JsonConvert.DeserializeObject<Token>(tokenString);

return token;

问题是返回 json 对象,但键是 access_tokenexpires_in 而不是驼峰式。我做错了吗?

现在我还有其他调用会返回 FirstName,所以我也想转换它们。

【问题讨论】:

  • 我希望我的 API 返回类似 { accessToken: "sdfsdfsdfsdfsdfds", expiresIn: 3200 } 而不是 { "access_token": "sdfsdfsdfsdfsdfds", "expires_in": 3200 }
  • 为什么不删除JsonProperty 属性?
  • @StevenB.因为我认为这是转换它的原因,但也许这是错误的
  • 我投票决定关闭。我不清楚您需要什么,以及是什么导致您受到限制。

标签: c# .net-core json.net dotnet-httpclient


【解决方案1】:

解释:我相信开始应该是对问题的理解,如果你再次检查你的模型,你会发现它有两种工作方式。因此,当您从 JSON 反序列化为 C# 对象时,遵循的约定是将 access_Token 绑定到 accessToken 属性,序列化将遵循相同方式的 inverse

建议:

 - 理想的(1) 返回 C# 对象(通常称为 Data Transfer Model DTO )本身和 (2) 和然后使用遵循 camelCase 模型的通用自定义配置。

所以你将把这个配置添加到你的启动中[check this](如果你想要一个通用的配置):


 public void ConfigureServices(IServiceCollection services){
    // Add framework services.
    services.AddMvc()
        .AddMvcOptions(options =>
        {
            options.OutputFormatters.Add(new PascalCaseJsonProfileFormatter());
        });} 

然后返回对象本身,正如我之前所说,最好创建一个单独的 DTO 模型并使用 AutoMapper 执行转换

- less 是创建两个模型,一个用于反序列化,具有“access_token”属性值等,后者用于序列化,具有 accessToken 属性值(但我强烈推荐第一个,因为您将获得两件事,您将学习如何使用 DTO 方法,即 WebApi 构建中必不可少的东西,并且还可以节省重复工作的时间,特别是当您使用 AutoMapper Library 等自动转换器完成和美化您的工作时.


  

 public class Token // use this for Deserialization
    {
        [JsonProperty("access_token")]
        public string AccessToken { get; set; }
        [JsonProperty("expires_in")]
        public int ExpiresIn { get; set; }
        [JsonProperty("token_type")]
        public string TokenType { get; set; }
    }
    public class TokenDto // use this for Serialization
    {
        [JsonProperty("accessToken")]
        public string AccessToken { get; set; }
        [JsonProperty("expiresIn")]
        public int ExpiresIn { get; set; }
        [JsonProperty("tokenType")]
        public string TokenType { get; set; }
    }

// Note that it is highly recommended 
// to respect the C# programming convention 
// in classes and properties naming that follow the pascalCase format

【讨论】:

    【解决方案2】:

    这里的问题是您在这种特殊情况下使用JsonProperty 会导致您在序列化时出现问题。它可以很好地读取传入的 JSON,但在序列化同一对象时将应用相同的命名。

    Json.Net 有一个内置的SnakeCaseNamingStrategy,可以在合约解析器中使用它来处理蛇案例序列化的属性名称。

    以下测试演示了使用该命名策略来获得所需的行为

    [TestClass]
    public class SnakeCaseNamingTests {
        [TestMethod]
        public void SHould_Read_SnakeCase_Naming() {
            var tokenString = @"
            {
              ""access_token"": ""sdfsdfsdfsdfsdfds"",
              ""expires_in"": 3200
            }";
    
            var settings = new JsonSerializerSettings {
                ContractResolver = new DefaultContractResolver {
                    NamingStrategy = new SnakeCaseNamingStrategy()
                }
            };
    
            Token token = JsonConvert.DeserializeObject<Token>(tokenString, settings);
    
            token.Should().NotBeNull();
            token.accessToken.Should().NotBeNull();
            token.expiresIn.Should().Be(3200);
        }
    
        public class Token {
            public string accessToken { get; set; }
            public int expiresIn { get; set; }
            public string tokenType { get; set; }
        }
    }
    

    注意从Token 中删除了JsonProperty 属性

    public class Token {
        public string accessToken { get; set; }
        public int expiresIn { get; set; }
        public string tokenType { get; set; }
    }
    

    这应该允许类在默认情况下以所需的格式序列化

    【讨论】:

    • 感谢您提供建议的答案。但是,问题来自于尝试使用相同的模型来获得与 JsonProperties 属性中提到的不同的格式,并且没有使用任何额外的通用或本地配置。它不是来自框架转换器中的问题。简而言之,这是由于对框架的不正确利用。希望大家指正。
    猜你喜欢
    • 2019-01-09
    • 2021-06-17
    • 1970-01-01
    • 2021-09-08
    • 2017-07-26
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    相关资源
    最近更新 更多