无法在 WebApi 中使用 .NET 5 中的 Json 子类型反序列化 Json,尽管能够在控制台应用程序中反序列化
Unable to Deserialize Json in WebApi with JsonSubTypes in .NET 5, although able to in Console App
我正在尝试在我的项目的 Web 中实现多态反序列化 api。我有以下基础和派生 class.
基地class
[JsonConverter(typeof(JsonSubtypes), "PointType")]
public abstract class BasePointRule
{
public abstract string PointType { get; }
}
派生Class
public class DayOfWeekPointRule : BasePointRule
{
public int Id { get; set; }
public decimal Mon { get; set; } = 0;
public decimal Tue { get; set; } = 0;
public decimal Wed { get; set; } = 0;
public decimal Thu { get; set; } = 0;
public decimal Fri { get; set; } = 0;
public decimal Sat { get; set; } = 0;
public decimal Sun { get; set; } = 0;
public int GroupId { get; set; }
public Group Group { get; set; }
public override string PointType { get;} = "DayOfWeekPointRule";
public DayOfWeekPointRule()
{
}
}
将子类型的 json 发布到我的 Web Api 控制器时出现错误。这是带双引号转义的 json:
{
"PointType":"DayOfWeekPointRule",
"Mon":0,
"Tue":0,
"Wed":0,
"Thu":0,
"Fri":0,
"Sat":0,
"Sun":0
}
这是网络 api 控制器方法:
[HttpPost("AddPointRule")]
public IActionResult AddPointRule(BasePointRule rule)
{
ConfigurationService.AddPointRule(rule);
return Ok();
}
我收到的错误信息是:
System.InvalidOperationException: 无法创建类型 'RosterCharm.Models.Rules.BasePointRule' 的实例。模型绑定的复杂类型不能是抽象类型或值类型,并且必须具有无参数构造函数。记录类型必须有一个主构造函数。或者,给 'rule' 参数一个非空的默认值。
在 Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinder.CreateModel(ModelBindingContext bindingContext)
在 Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinder.BindModelCoreAsync(ModelBindingContext bindingContext,Int32 propertyData)
在 Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext、IModelBinder modelBinder、IValueProvider valueProvider、ParameterDescriptor 参数、ModelMetadata 元数据、对象值、对象容器)
在 Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.d.MoveNext()
--- 从上一个位置开始的堆栈跟踪结束 ---
如果我将控制器路由中的参数从基础 class 更改为派生的 class,则 json 被正确反序列化。
如果我在控制台应用程序中实现上述内容并调用以下内容,那么 json 也会毫无问题地反序列化为派生类型:
var derivedType = JsonConvert.DeserializeObject<BasePointRule>(json);
这让我认为这个问题是 .Net 特有的(我使用的是 .Net 5),并尝试确保我使用的是 Json.NET(我认为是 Newtonsoft.Json) System.Text.Json 通过在我的 startup.cs
中调用以下内容
services.AddControllers().AddNewtonsoftJson();
如有任何提示,我们将不胜感激。我正在考虑接下来尝试实现我自己的 Json 转换器,但希望能够轻松利用 json 子类型库。
public IActionResult AddPointRule([FromBody] BasePointRule rule)
{
}
我正在尝试在我的项目的 Web 中实现多态反序列化 api。我有以下基础和派生 class.
基地class
[JsonConverter(typeof(JsonSubtypes), "PointType")]
public abstract class BasePointRule
{
public abstract string PointType { get; }
}
派生Class
public class DayOfWeekPointRule : BasePointRule
{
public int Id { get; set; }
public decimal Mon { get; set; } = 0;
public decimal Tue { get; set; } = 0;
public decimal Wed { get; set; } = 0;
public decimal Thu { get; set; } = 0;
public decimal Fri { get; set; } = 0;
public decimal Sat { get; set; } = 0;
public decimal Sun { get; set; } = 0;
public int GroupId { get; set; }
public Group Group { get; set; }
public override string PointType { get;} = "DayOfWeekPointRule";
public DayOfWeekPointRule()
{
}
}
将子类型的 json 发布到我的 Web Api 控制器时出现错误。这是带双引号转义的 json:
{
"PointType":"DayOfWeekPointRule",
"Mon":0,
"Tue":0,
"Wed":0,
"Thu":0,
"Fri":0,
"Sat":0,
"Sun":0
}
这是网络 api 控制器方法:
[HttpPost("AddPointRule")]
public IActionResult AddPointRule(BasePointRule rule)
{
ConfigurationService.AddPointRule(rule);
return Ok();
}
我收到的错误信息是:
System.InvalidOperationException: 无法创建类型 'RosterCharm.Models.Rules.BasePointRule' 的实例。模型绑定的复杂类型不能是抽象类型或值类型,并且必须具有无参数构造函数。记录类型必须有一个主构造函数。或者,给 'rule' 参数一个非空的默认值。
在 Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinder.CreateModel(ModelBindingContext bindingContext)
在 Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinder.BindModelCoreAsync(ModelBindingContext bindingContext,Int32 propertyData)
在 Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext、IModelBinder modelBinder、IValueProvider valueProvider、ParameterDescriptor 参数、ModelMetadata 元数据、对象值、对象容器)
在 Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.
如果我将控制器路由中的参数从基础 class 更改为派生的 class,则 json 被正确反序列化。
如果我在控制台应用程序中实现上述内容并调用以下内容,那么 json 也会毫无问题地反序列化为派生类型:
var derivedType = JsonConvert.DeserializeObject<BasePointRule>(json);
这让我认为这个问题是 .Net 特有的(我使用的是 .Net 5),并尝试确保我使用的是 Json.NET(我认为是 Newtonsoft.Json) System.Text.Json 通过在我的 startup.cs
中调用以下内容services.AddControllers().AddNewtonsoftJson();
如有任何提示,我们将不胜感激。我正在考虑接下来尝试实现我自己的 Json 转换器,但希望能够轻松利用 json 子类型库。
public IActionResult AddPointRule([FromBody] BasePointRule rule)
{
}