C # JSON deserializer только проверяет формат, он не заботится о данных объекта - PullRequest
0 голосов
/ 20 января 2012

Я хочу десериализовать сообщение JSON, полученное от TCP / IP, в моем приложении C #.У меня есть действительно простые классы с одним или двумя свойствами максимум, но они являются производными.Например:

public class SemiCommand
{
    public SemiCommand()
    {
        UID = string.Empty;
    }

    public SemiCommand(string uid)
    {
        UID = uid;
    }

    public string UID
    {
        get;
        set;
    }

    public new string ToString()
    {
        return new JavaScriptSerializer().Serialize(this);
    }
}

public class ResponseCommand : SemiCommand
{
    protected const string DEFAULT_INFO = "OK";

    public ResponseCommand()
    {
        UID = string.Empty;
        Info = DEFAULT_INFO;
    }

    public ResponseCommand(string uid)
    {
        UID = uid;
        Info = DEFAULT_INFO;
    }

    public string Response
    {
        get;
        set;
    }

    public string Info
    {
        get;
        set;
    }


public class GetInfoResponseCommand : ResponseCommand
{
    public GetInfoResponseCommand()
        : base()
    {
        Response = "GetInfoResponse";
    }

    public List<ClientProcess> Processes
    {
        get;
        set;
    }
}

Я предпринял несколько попыток с атрибутами DataMember и DataContract, чтобы решить мою проблему, но она не устранилась.

Проблема заключается в следующем:

private Type[] _deserializationTypes = new Type[] { typeof(StartProcessesRequestCommand), typeof(RequestCommand) };

public RequestCommand TranslateTCPMessageToCommand(string messageInString)
{
     RequestCommand requestCommand = null;

     for (int i = 0; i < _deserializationTypes.Length; i++)
     {
         try
         {
             requestCommand = TryDeserialize(_deserializationTypes[i], messageInString);
             break;
         }
         catch
         {
         }
     }

     if (requestCommand == null || (requestCommand != null && requestCommand.Command == string.Empty))
     {
         throw new System.Runtime.Serialization.SerializationException("Unable to deserialize received message");
     }
     else
     {
         return requestCommand;
     }
}

Если я хочу десериализовать с правильным форматом, содержащим все необходимые свойства, он работает:

Это работает: {"Response":"SomeResponse","Info":"Information","UID":"123"}

Однако это также работает: {"nonexistingProperty":"value"}

Второй также создает RequestCommand со значениями свойства, установленными в нуль.

1-й вопрос: Как я могу заставить мою функцию переводчика сообщений сделать RequestCommand, только если он получает все необходимые свойства

2-й вопрос: Если у меня есть несколько типов команд, которые получены от одного или нескольких предков, как это возможно, чтобы десериализовать его автоматически из «самого глубокого» класса, если полученные свойства позволяют это.

РЕДАКТИРОВАТЬ:

Я сериализую / десериализовать с этими двумя

    private RequestCommand TryDeserialize(Type type, string messageInString)
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        return (RequestCommand)js.Deserialize(messageInString, type);
    }

    public string TranslateCommandToTCPMessage(ResponseCommand command)
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        return js.Serialize(command);
    }

Прерывание в ловушке try должно завершить цикл, если TrySerialize не выбрасываетn исключение, поэтому десериализация прошла успешно.

1 Ответ

0 голосов
/ 26 апреля 2012

Если вы на самом деле использовали DataContractJsonSerializer и украсили соответствующие элементы / типы с помощью DataMember / DataContract, вы действительно можете добиться этого. Для этого вы можете украсить ВСЕ члены данных с помощью [IsRequired = true]. Это вызвало бы исключение, если бы участники не присутствовали на проводе.

Другой вариант, который у вас есть, - это использовать IObjectReference, который позволяет переводить один объект в другой после сериализации, и вы можете делать это в зависимости от того, что десериализовано из провода.

...