代码之家  ›  专栏  ›  技术社区  ›  Mark Allison

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

  •  -1
  • Mark Allison  · 技术社区  · 7 年前

    Person 其中,在实例化时必须从RPC调用填充属性。

    我得到这个错误:

    Newtonsoft.Json.JsonReaderException
      HResult=0x80131500
      Message=Could not convert string to integer: getperson. Path 'id', line 1, position 103.
      Source=Newtonsoft.Json
    

    Id 财产 string 在 人

    我还听说它提到我应该使用静态工厂方法。这是什么?在这个例子中会是什么样子?非常感谢。

    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> ?

    public class RPCResponse<T>
    {
        public T result { get; set; }
        public string error { get; set; }
        public string id { get; set; }
    }
    
    4 回复  |  直到 7 年前
        1
  •  1
  •   Nkosi    7 年前

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

    您提到使用工厂方法。随你的便。

    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

        2
  •  0
  •   Vilsad P P    7 年前

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

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

        3
  •  0
  •   Mark Allison    7 年前

    我已经这样解决了它,但我不喜欢我的代码。如何改进?这似乎很冗长。

    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
        }
    }
    
        4
  •  0
  •   Westerlund.io    7 年前

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