[英]Exception when serializing polymorphic c# class with method hiding to json, ASP.NET core API
To get deep into the problem, here is a console app:为了深入研究这个问题,这里有一个控制台应用程序:
class Program
{
static void Main()
{
Console.WriteLine(JsonSerializer.Serialize(
new PolyMorphicClass { Data = new SomeData { N = 2} }));
}
class BaseClass
{
public virtual object Data { get; set; }
}
class PolyMorphicClass : BaseClass
{
public new SomeData Data { get; set; }
}
class SomeData
{
public int N { get; set; }
}
}
This code throw an invalid operation exception with this message:此代码使用以下消息引发无效操作异常:
The JSON property name for 'ConsoleApp_for_test.Program+PolyMorphicClass.Data' collides with another property.
“ConsoleApp_for_test.Program+PolyMorphicClass.Data”的 JSON 属性名称与另一个属性冲突。
I found that if I initializing BaseClass instead, like below, it works我发现如果我改为初始化BaseClass ,如下所示,它可以工作
static void Main()
{
Console.WriteLine(JsonSerializer.Serialize(
new BaseClass { Data = new SomeData { N = 2} }));
}
My actual problem is: in a WebAPI where PolymorphicClass is the response type of a controller action that is being serialized to json, and this same exception happens.我的实际问题是:在 WebAPI 中, PolymorphicClass是 controller 操作的响应类型,该操作被序列化为 json,并且会发生同样的异常。
extra note: In the API I use this polymorphic behavior to make the response consistent across endpoints ie similar data type.额外说明:在 API 中,我使用这种多态行为使响应在端点之间保持一致,即相似的数据类型。
My questions are: is it ok to use the BaseClass instead of the polymorphicClass like I said above in the context of initializing API response?我的问题是:在初始化 API 响应的上下文中,可以使用BaseClass而不是上面所说的polymorphicClass吗? Is there other solutions to serialize this?
还有其他解决方案可以序列化吗? Can someone explain why the exception is happening?
有人可以解释为什么会发生异常吗?
You can't change the return type with the new
keyword, all it does is hide it and requires the use of the same signature.您不能使用
new
关键字更改返回类型,它所做的只是隐藏它并需要使用相同的签名。
You could fix this in a couple of ways.您可以通过多种方式解决此问题。
Replacing object
with a generic type would allow for you to define PolyMorphicClass
with a specific type for Data
, which I believe is similar to what you're trying to do here.用泛型类型替换
object
将允许您使用Data
的特定类型定义PolyMorphicClass
,我相信这与您在此处尝试执行的操作类似。
class BaseClass<T>
{
public virtual T Data { get; set; }
}
class PolyMorphicClass : BaseClass<SomeData>
{
}
Properties are essentially 2 methods (a getter and a setter) and you use some default ones with { get; set; }
属性本质上是 2 种方法(一个 getter 和一个 setter),您可以使用一些默认方法
{ get; set; }
{ get; set; }
{ get; set; }
. { get; set; }
。 These defaults get and set, respectively, a private member underneath the hood.这些默认值分别获取和设置引擎盖下的私有成员。
virtual
properties are basically saying "You should override my getter and setter". virtual
属性基本上是在说“你应该覆盖我的 getter 和 setter”。 Just specify an underlying member with the type SomeData
to get and set.只需指定类型为
SomeData
的基础成员即可获取和设置。 Here's a basic example.这是一个基本的例子。
class BaseClass
{
public virtual object Data { get; set; }
}
class PolyMorphicClass : BaseClass
{
private SomeData data { get; set; }
public override object Data
{
get
{
return data;
}
set
{
data = (SomeData) value;
}
}
}
Note that if you deserialize some JSON that can't be casted to SomeData
you'll run into a runtime exception of System.InvalidCastException
, so you may want to add some additional type checking in your setter.请注意,如果您反序列化一些无法转换为 SomeData 的
SomeData
,您将遇到System.InvalidCastException
的运行时异常,因此您可能需要在设置器中添加一些额外的类型检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.