如何在C#中使用JSON使用构造函数填充对象属性?

时间:2019-01-06 13:30:34

标签: c# json

我今天早些时候问过,但仍在努力。我想创建一个对象idx = 1,在实例化时必须从RPC调用中填充属性。

我收到此错误:

Person

下面是我的示例,我尝试将Newtonsoft.Json.JsonReaderException HResult=0x80131500 Message=Could not convert string to integer: getperson. Path 'id', line 1, position 103. Source=Newtonsoft.Json 对象中的Id属性更改为string,但是没有一个属性未设置(空或零)。

我也听说它提到我应该使用静态工厂方法。那是什么,在这个例子中看起来如何?非常感谢。

Person

编辑:在我的实际代码中,我有另一个这样的类,我可以利用它并以某种方式用using Newtonsoft.Json; class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Version { get; set; } public Person(int Id) { // here would be an RPC call to get the FirstName,LastName,Version. result is JSON string response = "{\"result\": {\"version\":1,\"Id\": 1, \"FirstName\": \"Bob\", \"LastName\": \"Jones\"},\"error\":null,\"id\":\"getperson\"}"; JsonConvert.PopulateObject(response, this); } } class Program { static void Main(string[] args) { var p = new Person(1); var f = p.FirstName; // p.FirstName should be Bob but is null } } 进行反序列化吗?

RPCResponse<Person>

4 个答案:

答案 0 :(得分:1)

根据当前示例,构造函数承担了太多的责任。

您提到使用工厂方法。顺其自然。

class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Version { get; set; }

    public Person()    { 
    }

    public static Person Get(int id) {
        // here would be an RPC call to get the FirstName,LastName,Version. result is JSON

        string json = "{\"result\": {\"version\":1,\"Id\": 1, \"FirstName\": \"Bob\", \"LastName\": \"Jones\"},\"error\":null,\"id\":\"getperson\"}";

        dynamic jObject = JObject.Parse(json);  

        var person = jObject.result.ToObject<Person>();

        return person;
    }
}

static Get(int Id)工厂方法将负责解析服务的响应。可能也可以将其重构为服务,但是这里的要点是构造函数应保持所需的简单性。

public class Program
{
    public static void Main(string[] args)
    {
        var p = Person.Get(1);

        var f = p.FirstName;
        var l = p.LastName;

        Console.WriteLine("FirstName: "+ f);
        Console.WriteLine("LastName: "+ l);
    }
}

//Produces:
//  FirstName: Bob
//  LastName: Jones

.Net Fiddle of above code

答案 1 :(得分:0)

您要填充的类在json字符串的内部属性中。尝试创建这样的类

public class Response{
  public Response(
    string response = "{\"result\": {\"version\":1,\"Id\": 1, \"FirstName\": \"Bob\", \"LastName\": \"Jones\"},\"error\":null,\"id\":\"getperson\"}";
    JsonConvert.PopulateObject(response, this);
  ){}
  public Person result{get;set;}

}
public class Person{
  public Person(){}
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Version { get; set; }
}

这是未经测试的代码,但我希望您能理解。

答案 2 :(得分:0)

我已经这样解决了,但是我不喜欢我的代码。如何改善?看起来很冗长。

using Newtonsoft.Json;

class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Version { get; set; }

    public Person(int Id)
    {
        // here would be an RPC call to get the FirstName,LastName,Version. result is JSON    
        string response = "{\"result\": {\"version\":1,\"Id\": 1, \"FirstName\": \"Bob\", \"LastName\": \"Jones\"},\"error\":null,\"id\":\"getperson\"}";             
        var o = JsonConvert.DeserializeObject<RPCResponse<PersonDetails>>(response).result;
        this.Id = Id;
        FirstName = o.FirstName;
        LastName = o.LastName;
        Version = o.Version;
    }

    private class PersonDetails
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Version { get; set; }
    }
}

public class RPCResponse<T>
{
    public T result { get; set; }
    public string error { get; set; }
    public string id { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        var p = new Person(1);
        var f = p.FirstName;
        // p.FirstName should be Bob but is null
    }
}

答案 3 :(得分:0)

不确定您的代码是什么问题,但是此代码将JSON直接映射到PersonDetails类中,并且其属性正确: 使用系统; 使用Newtonsoft.Json;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string json = "{\"result\": {\"version\":1,\"Id\": 1, \"FirstName\": \"Bob\", \"LastName\": \"Jones\"},\"error\":null,\"id\":\"getperson\"}";
            var personDetails = new PersonDetails(json);

            Console.WriteLine(personDetails.ToString());        
            Console.ReadLine();
        }
    }

    public class RPCResponse<T>
    {
        public T Result { get; set; }
        public string Error { get; set; }
        public string Id { get; set; }
    }

    public class PersonDetails
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Version { get; set; }

        public PersonDetails() {}

        public PersonDetails(string json)
        {
            var result = JsonConvert.DeserializeObject<RPCResponse<PersonDetails>>(json).Result;

            foreach (var prop in typeof(PersonDetails).GetProperties())
            {
                var value = prop.GetValue(result);
                prop.SetValue(this, value);
            }
        }

        public override string ToString()
        {
            var str = "Id: " + this.Id + Environment.NewLine;
            str += "FirstName: " + this.FirstName + Environment.NewLine;
            str += "LastName: " + this.LastName + Environment.NewLine;
            str += "Version: " + this.Version + Environment.NewLine;
            return str;
        }
    }
}