.Net core 3.0 API 不使用连字符绑定属性

Posted

技术标签:

【中文标题】.Net core 3.0 API 不使用连字符绑定属性【英文标题】:.Net core 3.0 API doesn't bind properties with hyphen 【发布时间】:2020-05-24 04:33:54 【问题描述】:

由于上次没有收到很好的问题,因此重新审核了该问题。希望我已在下面提供了所有必需的信息。

我有一个基本的 API 控制器,但我的 Json 对象似乎没有正确绑定到模型。根对象已绑定,但名称中带有连字符的属性未绑定。不幸的是,我不能删除属性名称中的连字符。

如何让属性正确绑定?

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace TestCoreAPI.Controllers

    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    
        // POST: api/Test
        [HttpPost]
        public string Post([FromBody] TestPayload testPayload)
        
            if (testPayload == null)
            
                return "Test payload is empty";
            

            if (string.IsNullOrWhiteSpace(testPayload.TestProperty))
            
                return "Test property is empty";
            

            return "Valid input - " + testPayload.TestProperty;
        
    

    [JsonObject("test-payload")]
    public class TestPayload
    
        [JsonProperty(PropertyName = "test-property")]
        public string TestProperty  get; set; 
    

这是我对 API 的调用

POST /api/test HTTP/1.1
Content-Type: application/json

"test-property":"some string value"

【问题讨论】:

这通常是因为 JSON 与模型不匹配。如果没有看到您的模型,就无法确定这是否是您的问题。 之前有人问这里也是模型定义[JsonObject("test-payload")] public class TestPayload [JsonProperty("test-string")] public string TestString get; set; 然后,您的模型不匹配。 你的根对象,有一个属性"test-payload",它是一个子对象。该子对象具有属性"test-string",即string 属性。您需要在此处表示两个对象,而不仅仅是嵌套对象。 JSON 在 C# 中表示非常简单。任何时候你看到 你都有一个对象(在C#中用class表示),任何时候你看到[ ]你都有一个数组(用List<T>T[]等在C#中表示),以及其他一切是一个简单的属性,例如 stringint。如果您不确定,Visual Studio 有 Edit > Paste Special > Paste JSON as Classes 【参考方案1】:

Net Core 3.1 确实绑定了连字符。无论哪种方式,这两个选项都是 Newtonsoft.Json 或 new-in-core-3 System.Text.Json,它们使用的 Attribute 名称略有不同:

public class PostModel

    //This one if you are using Newtonsoft.Json
    //The Nuget dependency is Microsoft.AspNetCore.Mvc.NewtonsoftJson
    [JsonProperty(PropertyName = "kebab-case-json-field")]

    //This one of you are using the new System.Text.Json.Serialization
    [JsonPropertyName("kebab-case-json-field")]

    public string kebabCaseProperty  get; set; 

同时,在您的 Startup.cs 中,要使用 Newtonsoft,您需要 AddMvc(),而对于新的 System.Text.Json,您不需要。这些都对我有用:

public void ConfigureServices(IServiceCollection services)

    //if using NewtonSoft
    services.AddMvc().AddNewtonsoftJson();

    //if using System.Text.Json.
    //This is the code that core 3 `dotnet new webapi` generates
    services.AddControllers();

【讨论】:

【参考方案2】:

您是否将AddNewtonsoftJson() 添加到Startup.ConfigureServices 的服务中?如果不是,则使用的是新的System.Text.Json,而不是 Newtonsoft。我认为您需要执行AddNewtonSoftJson(),因为我很确定System.Text.Json 不支持“kebab case”绑定。

https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#newtonsoftjson-jsonnet-support

【讨论】:

newtonsoft需要services.AddMvc().AddNewtonsoftJson(),而新框架Json不需要mvc,只需AddControllers()

以上是关于.Net core 3.0 API 不使用连字符绑定属性的主要内容,如果未能解决你的问题,请参考以下文章

如何将 .NET Core 2.2 Web API 迁移到 .NET Core 3.0?

Linq 查询在 ASP.NET-Core 3.0 及更高版本中对数字等字符串进行排序

。NET Core 3.0 StringEnumConverter不作为字符串序列化

使用 ASP.NET Core 3.0 内置 API 从 .crt 和 .key 文件创建 X509Certificate2

gRPC in ASP.NET Core 3.0 -- 前言

.net core 3.0 Signalr - 09 待改进&交流