C# JSON 反序列化程序只检查格式,不关心对象数据



我想在C#应用程序中反序列化从TCP/IP接收的JSON消息。我有一些非常简单的类,最多有一两个属性,但它们是派生的。例如:

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"}

第二个还创建了一个属性值设置为null的RequestCommand。

第一个问题:只有当我的messagetranslator函数接收到所有必需的属性时,我才能强制它使RequestCommand

第二个问题:如果我有多个从一个或多个祖先派生的命令类型,如果接收到的属性允许,如何从"最深"类自动反序列化它?

编辑:

我用这两个进行序列化/反序列化

    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);
    }

如果TrySerialize没有抛出异常,则try-catch中的中断应该结束循环,因此反序列化成功。

如果您实际使用了DataContractJsonSerializer,并且使用DataMember/DataContract修饰了有问题的成员/类型,那么您实际上可以实现这一点。为此,您可以用[IsRequired=true]修饰所有数据成员。如果成员不在场,这将引发异常。

您的另一个选择是使用IObjectReference,它允许您在序列化后将一个对象转换为另一个对象,并且您可以根据从连线反序列化的内容来执行此操作。

最新更新