2014-06-16 30 views
7

Tôi cần deserialize json cho lớp sau.Deserialize json thành đối tượng C# đối với lớp có hàm tạo riêng mặc định

public class Test 
{ 
    public string Property { get; set; } 

    private Test() 
    { 
     //NOTHING TO INITIALIZE 
    } 

    public Test(string prop) 
    { 
     Property = prop; 
    } 
} 

tôi có thể tạo ra một thể hiện của thử nghiệm như

var instance = new Test("Instance"); 

xem xét một cái gì đó json tôi như

"{ "Property":"Instance" }" 

Làm thế nào tôi có trách nhiệm tạo một đối tượng của class Test như constructor mặc định của tôi là tư nhân và Tôi nhận được đối tượng ở nơi Thuộc tính là NULL

Tôi đang sử dụng trình phân tích cú pháp Newtonsoft Json.

+0

bạn đang sử dụng thư viện nào? làm thế nào để bạn có được một ví dụ của 'Test'? –

+0

Nếu không có bất kỳ nhà máy nào tạo ra một đối tượng 'Test', làm thế nào để bạn mong muốn deserialize một JSON thành một thể hiện của nó? –

Trả lời

22

Bạn có thể làm Json.Net gọi các nhà xây dựng tư nhân bằng cách đánh dấu nó với một thuộc tính [JsonConstructor]:

[JsonConstructor] 
private Test() 
{ 
    //NOTHING TO INITIALIZE 
} 

Lưu ý rằng các serializer vẫn sẽ sử dụng setters nào để cư các đối tượng sau khi gọi các nhà xây dựng.

EDIT

Một tùy chọn khác có thể là sử dụng các thiết lập ConstructorHandling:

JsonSerializerSettings settings = new JsonSerializerSettings 
{ 
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor 
}; 

Test t = JsonConvert.DeserializeObject<Test>(json, settings); 
+2

Tùy chọn thứ hai là tốt nhất nếu đối tượng bạn muốn tuần tự hóa nằm trong thư viện/lắp ráp nơi bạn không muốn giới thiệu các phụ thuộc bên thứ 3 (bao gồm cả phụ thuộc vào Json.Net ...) –

2

Nó không có vẻ như bạn cần phải thực hiện bất kỳ bước mở rộng.

Sử dụng Json.NET v6.0.8, chương trình C#: sẽ khởi động bên trong LINQPad:

void Main() 
{ 
    var o = JsonConvert.DeserializeObject<Test>("{\"Property\":\"Instance\"}"); 

    Debug.Assert(o.Property == "Instance", 
     "Property value not set when deserializing."); 
} 

public class Test 
{ 
    public string Property { get; set; } 

    private Test() 
    { 
    } 

    public Test(string propertyValue) 
    { 
     Property = propertyValue; 
    } 
} 
+0

Ví dụ về một ví dụ sửa đổi bit trực tuyến: https://dotnetfiddle.net/4qFumV – Maxim

0

Không cần phải tạo ra một khung cảnh Serializer và cung cấp cho assign ConstructorHandling đây. Hãy nhớ xác định thuộc tính [JsonConstructor] cho hàm tạo riêng. Tôi có trường hợp tương tự với BaseNode.cs trừu tượng và triển khai ComputerNode.cs cụ thể của nó. Bạn có thể tạo các lớp, sao chép/dán mã bên dưới và thực hiện một số thử nghiệm.

public abstract class BaseNode 
{ 
    [JsonConstructor] // ctor used when Json Deserializing 
    protected BaseNode(string Owner, string Name, string Identifier) 
    { 
     this.Name = Name; 
     this.Identifier = Identifier; 
    } 

    // ctor called by concrete class. 
    protected BaseNode(string [] specifications) 
    { 
     if (specifications == null) 
     { 
      throw new ArgumentNullException(); 
     } 
     if (specifications.Length == 0) 
     { 
      throw new ArgumentException(); 
     } 

     Name = specifications[0]; 
     Identifier = specifications[1]; 

    } 

    public string Name{ get; protected set; } 
    public string Identifier { get; protected set; } 

} 


public class ComputerNode: BaseNode 
{ 
    public string Owner { get; private set; } 

    [JsonConstructor] // not visible while creating object from outside and only used during Json Deserialization. 
    private ComputerNode(string Owner, string Name, string Identifier):base(Owner, Name, Identifier) 
    { 
     this.Owner = Owner; 
    } 

    public ComputerNode(string[] specifications):base(specifications) 
    { 
     Owner = specifications[2]; 
    } 
} 

Đối với JSON Đọc và Viết mã sau đây giúp -

public class Operation<T> 
{ 
    public string path; 

    public Operation() 
    { 
     var path = Path.Combine(Directory.GetCurrentDirectory(), "nodes.txt"); 

     if (File.Exists(path) == false) 
     { 
      using (File.Create(path)) 
      { 
      } 
     } 
     this.path = path; 
    } 

    public void Write(string path, List<T> nodes) 
    { 
     var ser = JsonConvert.SerializeObject(nodes, Formatting.Indented); 

     File.WriteAllText(path, ser); 
    } 

    public List<T> Read(string path) 
    { 
     var text = File.ReadAllText(path); 

     var res = JsonConvert.DeserializeObject<List<T>>(text); 
     return res; 
    } 

} 

Tất cả là tốt nhất!

Các vấn đề liên quan