Json.NET在模式中复制枚举定义

时间:2015-07-08 16:39:16

标签: c# json enums json.net

我有一个comms协议,其中我通过JSON使用公共" MessageType"发送多个不同的对象类型。字段以标识它们以反序列化到正确的类。我正在使用Json.NET.Schema从我的类生成模式,然后我将用它来生成POJO,以便在我正在与之通信的Android应用程序中使用。

为了轻松地为我的所有对象创建一个模式,我有一个虚拟的根类,它具有我将使用的每种类型的属性,所以我创建了一个模式并生成POJO并最终得到了类我想要,加上我可以忽略的假人。

问题我得到的是,在POJO中的每个类中都定义了枚举。因此,我最终只使用MessageTypeClass1.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"
  ]
}

0 个答案:

没有答案