我有一个comms协议,其中我通过JSON使用公共" MessageType"发送多个不同的对象类型。字段以标识它们以反序列化到正确的类。我正在使用Json.NET.Schema从我的类生成模式,然后我将用它来生成POJO,以便在我正在与之通信的Android应用程序中使用。
为了轻松地为我的所有对象创建一个模式,我有一个虚拟的根类,它具有我将使用的每种类型的属性,所以我创建了一个模式并生成POJO并最终得到了类我想要,加上我可以忽略的假人。
问题我得到的是,在POJO中的每个类中都定义了枚举。因此,我最终只使用MessageType
,Class1.MessageType
等来代替单Class2.MessageType
枚举,而且它们是不同的类型,因此(我假设!)不具有可比性在switch语句等中。这可以在模式中看到,因此它是模式生成的问题,而不是POJO生成器的问题。
我可以通过使用数字而不是将枚举表示为JSON中的字符串来解决这个问题,但是字符串表示会使事情变得容易看到,如果事情发生变化则不那么脆弱,所以我认为值得在这里首先考虑我以及#39 ;做些蠢事!
作为参考,包含我的消息对象的代码的一部分是
public enum eCommandType
{
UNKNOWN,
PING,
GET_TIMINGS,
GET_EVENT_ID,
NEW_EVENT,
LOAD_PEOPLE,
LOAD_TAGS,
SET_LOCATION
}
public enum eMessageType
{
UNKNOWN,
COMMAND_BASE,
COMMAND_LOADPEOPLE,
RESPONSE_PING,
RESPONSE_GENERAL,
RESPONSE_TIMINGS_PEOPLE,
RESPONSE_TIMINGS_CLICKER
}
/* A wrapper class so we can put all our classes
* in one object for the JSON schema.
*/
public class DummyContainer
{
public eCommandType eCommandType { get; set; }
public eMessageType eMessageType { get; set; }
public CommandBase CommandBase { get; set; }
public CommandLoadPeople CommandLoadPeople { get; set; }
public ResponsePing ResponsePing { get; set; }
public ResponseGeneral ResponseGeneral { get; set; }
public ResponseTimingsPeople ResponseTimingsPeople { get; set; }
public ResponseTimingsClicker ResponseTimingsClicker { get; set; }
public DummyMessage DummyMessage { get; set; }
}
.
.
.
public class CommandBase : iMessage
{
eMessageType _messageType = eMessageType.COMMAND_BASE;
[JsonConverter(typeof(StringEnumConverter))]
public eCommandType CommandType { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public eMessageType MessageType { get { return _messageType;} private set {_messageType = value;} }
public CommandBase(eCommandType CommandType)
{
this.CommandType = CommandType;
}
}
生成架构的代码是
public static string GenerateSchema()
{
//Encode enums as strings, not integers.
JSchemaGenerator stringEnumGenerator = new JSchemaGenerator();
stringEnumGenerator.GenerationProviders.Add
(new StringEnumGenerationProvider());
stringEnumGenerator.ContractResolver = new ShouldSerializeContractResolver();
JSchema schema = stringEnumGenerator.Generate(typeof(DummyContainer));
string s = schema.ToString();
Console.WriteLine(s);
return s;
}
其中ShouldSerializeContractResolver是
/* Don't do anything with virtual fields- these are used for navigation properties in the
* entities and screw up serialization.
*/
public class ShouldSerializeContractResolver : DefaultContractResolver
{
public new static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
/* For some reason, MessageType is being identified as being virtual and gets dropped.
* So we explicitly allow anything with this name.
*/
if (member.Name == "MessageType") return property;
bool isVirtual = property.DeclaringType.GetProperty(member.Name).GetAccessors()[0].IsVirtual;
if (isVirtual)
return null;
return property;
}
}
,架构是
{
"type": "object",
"properties": {
"eCommandType": {
"type": "string",
"enum": [
"UNKNOWN",
"PING",
"GET_TIMINGS",
"GET_EVENT_ID",
"NEW_EVENT",
"LOAD_PEOPLE",
"LOAD_TAGS",
"SET_LOCATION"
]
},
"eMessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
},
"CommandBase": {
"type": [
"object",
"null"
],
"properties": {
"CommandType": {
"type": "string",
"enum": [
"UNKNOWN",
"PING",
"GET_TIMINGS",
"GET_EVENT_ID",
"NEW_EVENT",
"LOAD_PEOPLE",
"LOAD_TAGS",
"SET_LOCATION"
]
},
"MessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
}
},
"required": [
"CommandType",
"MessageType"
]
},
"CommandLoadPeople": {
"type": [
"object",
"null"
],
"properties": {
"People": {
"type": [
"array",
"null"
],
"items": {
"type": [
"object",
"null"
],
"properties": {
"Id": {
"type": "integer"
},
"Name": {
"type": [
"string",
"null"
]
},
"DOB": {
"type": "string"
},
"Gender": {
"type": [
"string",
"null"
]
},
"ContactDetails": {
"type": [
"string",
"null"
]
},
"NOKDetails": {
"type": [
"string",
"null"
]
},
"Notes": {
"type": [
"string",
"null"
]
}
},
"required": [
"Id",
"Name",
"DOB",
"Gender",
"ContactDetails",
"NOKDetails",
"Notes"
]
}
},
"CommandType": {
"type": "string",
"enum": [
"UNKNOWN",
"PING",
"GET_TIMINGS",
"GET_EVENT_ID",
"NEW_EVENT",
"LOAD_PEOPLE",
"LOAD_TAGS",
"SET_LOCATION"
]
},
"MessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
}
},
"required": [
"People",
"CommandType",
"MessageType"
]
},
"ResponsePing": {
"type": [
"object",
"null"
],
"properties": {
"MessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
},
"LastPeopleUpdate": {
"type": "string"
},
"LastTagsUpdate": {
"type": "string"
},
"EventID": {
"type": "string"
}
},
"required": [
"MessageType",
"LastPeopleUpdate",
"LastTagsUpdate",
"EventID"
]
},
"ResponseGeneral": {
"type": [
"object",
"null"
],
"properties": {
"MessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
},
"ErrorMessage": {
"type": [
"string",
"null"
]
},
"Result": {
"type": "integer"
}
},
"required": [
"MessageType",
"ErrorMessage",
"Result"
]
},
"ResponseTimingsPeople": {
"type": [
"object",
"null"
],
"properties": {
"MessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
},
"Timings": {
"type": [
"array",
"null"
],
"items": {
"type": [
"object",
"null"
],
"properties": {
"PersonID": {
"type": "integer"
},
"EventTimeMillis": {
"type": "integer"
}
},
"required": [
"PersonID",
"EventTimeMillis"
]
}
}
},
"required": [
"MessageType",
"Timings"
]
},
"ResponseTimingsClicker": {
"type": [
"object",
"null"
],
"properties": {
"MessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
},
"Timings": {
"type": [
"array",
"null"
],
"items": {
"type": "integer"
}
}
},
"required": [
"MessageType",
"Timings"
]
},
"DummyMessage": {
"type": [
"object",
"null"
],
"properties": {
"MessageType": {
"type": "string",
"enum": [
"UNKNOWN",
"COMMAND_BASE",
"COMMAND_LOADPEOPLE",
"RESPONSE_PING",
"RESPONSE_GENERAL",
"RESPONSE_TIMINGS_PEOPLE",
"RESPONSE_TIMINGS_CLICKER"
]
}
},
"required": [
"MessageType"
]
}
},
"required": [
"eCommandType",
"eMessageType",
"CommandBase",
"CommandLoadPeople",
"ResponsePing",
"ResponseGeneral",
"ResponseTimingsPeople",
"ResponseTimingsClicker",
"DummyMessage"
]
}