为JSON数据编写具有多种可能类型的JSON数据的类
走出Python世界并进入C#,我在定义可以用于解码我的JSON有效载荷的课程时遇到了一些麻烦。
在Python中,我通常将Pydantic用于此类问题,因此我将说明:
from typing import Literal, Union
from pydantic import BaseModel
class Foo(BaseModel):
kind: Literal["foo"]
fizz: int
class Bar(BaseModel):
kind: Literal["bar"]
buzz: str
Payload = Union[Foo, Bar]
class Message(BaseModel):
payload: Payload
类消息遵循以下JSON Schema:
type: object
required: [payload]
properties:
payload:
anyOf:
- $ref: '#/definitions/Foo'
- $ref: '#/definitions/Bar'
definitions:
Foo:
type: object
required: [kind, fizz]
properties:
kind: {enum: [foo], type: string}
fizz: {type: integer}
Bar:
type: object
required: [kind, buzz]
properties:
kind: {enum: [bar], type: string}
buzz: {type: string}
研究后,我无法找到将这些概念映射到C#的最佳方法。据我了解,C#没有字符串类型,因此我无法使用这些字符串类型。我还不确定定义Union
类型的正确方法。
在C#中为此有效载荷建模类的最务实的方法是什么,以便我可以解码并将此数据编码为JSON?到目前为止,我一直在使用newtonsoft.json
,但是如果这使它更容易,我对其他工具开放。
我在C#版本中想象我会有这样的东西
interface Payload
{
public string kind { get; set; }
}
class Foo : Payload
{
public string kind { get; set; }
public int fizz { get; set; }
}
class Buzz : Payload
{
public string kind { get; set; }
public string buzz { get; set; }
}
class Message
{
public Payload Payload { get; set; }
}
:
Stepping out of the Python world and into C#, I'm having a bit of trouble defining a class which can be used for decoding my JSON payload.
In Python I usually use Pydantic for this type of problem, so I will illustrate with that:
from typing import Literal, Union
from pydantic import BaseModel
class Foo(BaseModel):
kind: Literal["foo"]
fizz: int
class Bar(BaseModel):
kind: Literal["bar"]
buzz: str
Payload = Union[Foo, Bar]
class Message(BaseModel):
payload: Payload
The class message adheres to the following JSON schema:
type: object
required: [payload]
properties:
payload:
anyOf:
- $ref: '#/definitions/Foo'
- $ref: '#/definitions/Bar'
definitions:
Foo:
type: object
required: [kind, fizz]
properties:
kind: {enum: [foo], type: string}
fizz: {type: integer}
Bar:
type: object
required: [kind, buzz]
properties:
kind: {enum: [bar], type: string}
buzz: {type: string}
After researching I can't figure out the best way to map these concepts to C#. From what I understand, C# does not have a literal string types, so I can't use those. I'm also unsure of the correct way to define the Union
type.
What would be the most pragmatic way to model a Class for this payload in C# such that I can decode and encode this data as JSON? So far I have been using Newtonsoft.Json
but I am open to other tooling if that makes this easier.
I'm imagining in the C# version I would have something like this:
interface Payload
{
public string kind { get; set; }
}
class Foo : Payload
{
public string kind { get; set; }
public int fizz { get; set; }
}
class Buzz : Payload
{
public string kind { get; set; }
public string buzz { get; set; }
}
class Message
{
public Payload Payload { get; set; }
}
(but I'm unsure of what the magic Newtonsoft code would look like to tie it all together)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,所以我最终得到了这一点,但是感觉超级尴尬...
也许有人可以提出改进:
然后定义一个自定义的jsonConverter以获取消息:
Okay, so this I what I ended up with, but it feels super awkward...
Maybe someone can suggest improvements:
And then defining a custom JsonConverter for message: