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

发布于 2024-11-07 03:24:59 字数 1036 浏览 1 评论 0原文

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

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

有没有人有一个好的建议作为最好的继续方式?我尝试过使用伊序列化,但它被忽略了。我尝试过使用 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 字段不匹配,因为它们是私有的。我也尝试过内部和保护,但这里也没有乐趣。

完整对象有一个构造函数,它接受 ID 和日期时间,以便在从数据库加载它们时设置它们。

任何帮助将不胜感激。

谢谢

I'm having an issue with JSON and de-serialisation. I've got a live production code which uses a message object to pass information around from one system to another. The ID of the message is very important as this is used to identify it. We also don't want anyone Setting the ID's and as such made it a private setter.

My problem comes when trying to deserialise the JSON object and the ID is not set. (obviously because it's private)

Does any one have a good suggestion as the best way to proceed? I've tried using Iserialisation and it's ignored. I've tried using DataContract but this fails because of the external system we are getting the data from.

My only option on the table at the moment is to make the ID and TimeCreated fields have public setters.

I have an object as such

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

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

}   

Now I'm using the following code:

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

The Id and Time created fields do not match because they are private. I've also tried internal and protected but no joy here either.

The full object has a constructor which accepts an ID and Date time to set these when loading them out of the DB.

Any help will be greatly appreciated.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

新人笑 2024-11-14 03:24:59

您可以使用 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);

You can use the DataContractJsonSerializer instead of the JavaScriptSerializer. You will need to decorate your class with some data contract attributes.

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

Generic serialization helper methods

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

In your case, you can deserialize using:

Message msg = ToObjectFromJson<Message>(jsonString);
浅紫色的梦幻 2024-11-14 03:24:59

我认为在 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);

I think having a new layer of abstraction in between your json and your Dto is your best bet.

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文