JSON反序列化为具有私有setter的对象

时间:2011-05-11 07:59:38

标签: c# json serialization

我遇到了JSON和反序列化的问题。我有一个实时生产代码,它使用消息对象将信息从一个系统传递到另一个系统。消息的ID非常重要,因为它用于识别它。我们也不希望任何人设置ID,因此使其成为私人制定者。

尝试反序列化JSON对象并且未设置ID时出现问题。 (显然是因为它是私人的)

有没有人有好的建议作为最好的方法?我尝试过使用Iserialisation,但它被忽略了。我尝试过使用DataContract,但由于我们从外部系统获取数据,因此失败了。

目前我唯一的选择是让ID和TimeCreated字段具有公共设置器。

我有一个这样的对象

Message
{
  public Message()
  {
    ID = Guid.NewGuid();
    TimeCreated = DateTime.Now();
  }

  Guid ID { get; private set; } 
  DateTime TimeCreated { get; private set; } 
  String Content {get; set;}

}   

现在我使用以下代码:

        var message = new Message() { Content = "hi" };
        JavaScriptSerializer jss = new JavaScriptSerializer();

        var msg = jss.Serialize(message);
        var msg2 = jss.Deserialize<Message>(msg);

        Assert.IsNotNull(msg2);
        Assert.AreEqual(message.ID, msg2.ID);

Id和Time创建的字段不匹配,因为它们是私有的。我也试过内部和保护,但也没有喜欢。

完整对象有一个构造函数,它接受一个I​​D和Date时间来设置它们从DB中加载它们。

非常感谢任何帮助。

谢谢

2 个答案:

答案 0 :(得分:5)

您可以使用DataContractJsonSerializer代替JavaScriptSerializer。您需要使用一些数据协定属性来装饰您的类。

    [DataContractAttribute()]
    public class Message
    {  
        public Message()  
        {
            ID = Guid.NewGuid();
            TimeCreated = DateTime.Now;
        }

        [DataMemberAttribute()]
        Guid ID { get; private set; }

        [DataMemberAttribute()]
        DateTime TimeCreated { get; private set; }

        [DataMemberAttribute()]
        String Content {get; set;}
    } 

通用序列化帮助方法

public static string ToJsonString(object obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    using (MemoryStream ms = new MemoryStream())
    {
        serializer.WriteObject(ms, obj);
        StringBuilder sb = new StringBuilder();
        sb.Append(Encoding.UTF8.GetString(ms.ToArray()));
        return sb.ToString();
    }
}

public static T ToObjectFromJson<T>(string json)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));

    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
    {
        return (T) serializer.ReadObject(ms);
    }
}

在您的情况下,您可以使用以下命令反序列化:

Message msg = ToObjectFromJson<Message>(jsonString);

答案 1 :(得分:3)

我认为在你的json和你的Dto之间有一个新的抽象层是你最好的选择。

MessageViewModel
{
    public MessageViewModel()
    {
    }

    Guid ID { get; set; } 
    DateTime TimeCreated { get; set; } 
    String Content {get; set;}
} 


static MessageFactory
{
    public static Message Build(MessageViewModel viewModel)
    {
        var result = new Message(viewModel.ID, viewModel.TimeCreated);
        result.Content .... 
        etc etc

        return result;
    }

} 


    JavaScriptSerializer jss = new JavaScriptSerializer();

    MessageViewModel viewModel = jss.Deserialize<MessageViewModel>(jsonString);

    var message = MessageFactory.Build(viewModel);