DataMember 属性在 dotnet core 3.0 中不受尊重
DataMember Attribute is not honored in dotnet core 3.0
我创建了一个示例 dotnet core 3.0 Web API 项目并进行了以下更改,
- 创建模型class测试数据
using System.Runtime.Serialization;
namespace WebApplication17.Models
{
[DataContract]
public class TestData
{
[DataMember(Name = "testaction")]
public string Action { get; set; }
}
}
然后我在控制器 WeatherForecastController
中进行了更改,以添加一个 post 端点
[HttpPost("package/{packageName}/version/{version}")]
public void Post(string packageName, string version, [FromBody] TestData activityPayload)
{
Console.WriteLine(activityPayload.Action);
}
现在我用 postman 或 curl with body
打了个电话
{
"testaction": "action"
}
还是在WeatherForecastController
的Post
方法中,activityPayload.Action
是null。
我原以为是 'action'
将 [JsonPropertyName("testaction")]
属性添加到 Action
属性。这应该可以解决您的问题。
更多信息请看这里:
https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/
Asp.Net Core 3 默认不支持 [DataContract]
,[DataMember]
,基于此 Github 看来他们不会很快添加它问题
System.Text.Json support to System.Runtime.Serialization
如果您想切换回以前使用 Newtonsoft.Json
的默认设置,它确实尊重这些属性,那么您必须执行以下操作:
安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 包。
在ConfigureServices()
中添加对AddNewtonsoftJson()
的调用
public void ConfigureServices(IServiceCollection services) {
//...
services.AddControllers()
.AddNewtonsoftJson(); //<--
//...
}
自 .NET Core 3.0 RC1 起,System.Text.Json
库不支持 System.Runtime.Serialization
属性。您可以在 GitHub 上找到一个跟踪此遗漏的问题,但现在似乎没有任何改变它的意图。
选项 1:Newtonsoft.Json
在此期间你可以做的是切换到使用 Newtonsoft.Json
作为 ASP.NET Core 3.0 的 JSON 序列化程序,它应该恢复此功能(代价是不利用System.Text.Json
解析器,速度要快一些)。
首先,在您的项目中添加对 Microsoft.AspNetCore.Mvc.NewtonsoftJson
包的引用:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
</ItemGroup>
</Project>
然后在您的服务集合上调用分机。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson();
}
选项 2:使用 System.Text.Json.Serialization
另一方面,如果您愿意在没有 System.Runtime.Serialization
属性的情况下定义您的模型并改用 System.Text.Json.Serialization
属性,那么您可以执行以下操作:
using System.Text.Json.Serialization;
namespace WebApplication17.Models
{
public class TestData
{
[JsonPropertyName("testaction")]
public string Action { get; set; }
}
}
您可以在此处找到支持的属性的完整列表:https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonpropertynameattribute?view=netcore-3.0
我的两分钱。
以下示例应该有所帮助。
以下是我从 OData Api 得到的响应 json。
{
"@odata.context": "http://localhost/odata/$metadata#GadgetsOdata(Id,ProductName,Cost,Brand,Type)",
"@odata.count": 3,
"value": [
{
"Id": 1,
"ProductName": "Pen Drive",
"Brand": "Sony",
"Cost": 600,
"Type": "Accessories"
},
{
"Id": 2,
"ProductName": "Head Phone",
"Brand": "Sony",
"Cost": 3000,
"Type": "Computer Accessories"
},
{
"Id": 3,
"ProductName": "Key board",
"Brand": "Hp",
"Cost": 1000,
"Type": "Computer Accessories"
}
]
}
以下是我用来反序列化的类
public class ExpectedODataGadgetModel
{
[JsonPropertyName("@odata.count")]
public int ODataCount { get; set; } = default!;
[JsonPropertyName("@odata.context")]
public string ODataContext { get; set; } = default!;
public List<ExpectedGadgetModel> value { get; set; } = default!;
}
public class ExpectedGadgetModel
{
public int Id { get; set; }
public string ProductName { get; set; } = default!;
public string Brand { get; set; } = default!;
public decimal Cost { get; set; } = default!;
public string Type { get; set; } = default!;
}
注意 JsonPropertyName
属性。
最后这就是我对它进行消毒的方法。
var responseStream = await _httpClient.GetStreamAsync(url);
var gadgets = await JsonSerializer.DeserializeAsync<ExpectedODataGadgetModel>(responseStream);
这里的_httpClient是我们在.net core中使用的System.Net.Http.HttpClient
对象。
并且 JsonSerializer
来自 System.Text.Json
而不是 NewtonsoftJson。
我创建了一个示例 dotnet core 3.0 Web API 项目并进行了以下更改,
- 创建模型class测试数据
using System.Runtime.Serialization;
namespace WebApplication17.Models
{
[DataContract]
public class TestData
{
[DataMember(Name = "testaction")]
public string Action { get; set; }
}
}
然后我在控制器 WeatherForecastController
中进行了更改,以添加一个 post 端点
[HttpPost("package/{packageName}/version/{version}")]
public void Post(string packageName, string version, [FromBody] TestData activityPayload)
{
Console.WriteLine(activityPayload.Action);
}
现在我用 postman 或 curl with body
打了个电话{
"testaction": "action"
}
还是在WeatherForecastController
的Post
方法中,activityPayload.Action
是null。
我原以为是 'action'
将 [JsonPropertyName("testaction")]
属性添加到 Action
属性。这应该可以解决您的问题。
更多信息请看这里: https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/
Asp.Net Core 3 默认不支持 [DataContract]
,[DataMember]
,基于此 Github 看来他们不会很快添加它问题
System.Text.Json support to System.Runtime.Serialization
如果您想切换回以前使用 Newtonsoft.Json
的默认设置,它确实尊重这些属性,那么您必须执行以下操作:
安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 包。
在
的调用ConfigureServices()
中添加对AddNewtonsoftJson()
public void ConfigureServices(IServiceCollection services) {
//...
services.AddControllers()
.AddNewtonsoftJson(); //<--
//...
}
自 .NET Core 3.0 RC1 起,System.Text.Json
库不支持 System.Runtime.Serialization
属性。您可以在 GitHub 上找到一个跟踪此遗漏的问题,但现在似乎没有任何改变它的意图。
选项 1:Newtonsoft.Json
在此期间你可以做的是切换到使用 Newtonsoft.Json
作为 ASP.NET Core 3.0 的 JSON 序列化程序,它应该恢复此功能(代价是不利用System.Text.Json
解析器,速度要快一些)。
首先,在您的项目中添加对 Microsoft.AspNetCore.Mvc.NewtonsoftJson
包的引用:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
</ItemGroup>
</Project>
然后在您的服务集合上调用分机。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson();
}
选项 2:使用 System.Text.Json.Serialization
另一方面,如果您愿意在没有 System.Runtime.Serialization
属性的情况下定义您的模型并改用 System.Text.Json.Serialization
属性,那么您可以执行以下操作:
using System.Text.Json.Serialization;
namespace WebApplication17.Models
{
public class TestData
{
[JsonPropertyName("testaction")]
public string Action { get; set; }
}
}
您可以在此处找到支持的属性的完整列表:https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonpropertynameattribute?view=netcore-3.0
我的两分钱。
以下示例应该有所帮助。
以下是我从 OData Api 得到的响应 json。
{
"@odata.context": "http://localhost/odata/$metadata#GadgetsOdata(Id,ProductName,Cost,Brand,Type)",
"@odata.count": 3,
"value": [
{
"Id": 1,
"ProductName": "Pen Drive",
"Brand": "Sony",
"Cost": 600,
"Type": "Accessories"
},
{
"Id": 2,
"ProductName": "Head Phone",
"Brand": "Sony",
"Cost": 3000,
"Type": "Computer Accessories"
},
{
"Id": 3,
"ProductName": "Key board",
"Brand": "Hp",
"Cost": 1000,
"Type": "Computer Accessories"
}
]
}
以下是我用来反序列化的类
public class ExpectedODataGadgetModel
{
[JsonPropertyName("@odata.count")]
public int ODataCount { get; set; } = default!;
[JsonPropertyName("@odata.context")]
public string ODataContext { get; set; } = default!;
public List<ExpectedGadgetModel> value { get; set; } = default!;
}
public class ExpectedGadgetModel
{
public int Id { get; set; }
public string ProductName { get; set; } = default!;
public string Brand { get; set; } = default!;
public decimal Cost { get; set; } = default!;
public string Type { get; set; } = default!;
}
注意 JsonPropertyName
属性。
最后这就是我对它进行消毒的方法。
var responseStream = await _httpClient.GetStreamAsync(url);
var gadgets = await JsonSerializer.DeserializeAsync<ExpectedODataGadgetModel>(responseStream);
这里的_httpClient是我们在.net core中使用的System.Net.Http.HttpClient
对象。
并且 JsonSerializer
来自 System.Text.Json
而不是 NewtonsoftJson。