2013-08-29 26 views
10

tôi nhận được câu trả lời sau đây từ một webservice:Làm thế nào để thực hiện một C# đối tượng từ json

{ 
    "data":{ 
    "foo.hugo.info": { 
     "path": "logon.cgi", 
     "minVersion": 1, 
     "maxVersion": 2 
    }, 
    "foo.Fritz.Task": { 
     "path": "Fritz/process.cgi", 
     "minVersion": 1, 
     "maxVersion": 1 
    } 
    }, 
    "success": true 
} 

Làm thế nào phải các json-đối tượng nhìn muốn deserialize này?

Hoặc có cách nào khác để nhận giá trị của thuộc tính không?

+0

Bạn có muốn deserialize nó không? – Shaharyar

+0

Bạn muốn làm gì với thông tin sau khi bạn đã nhập thông tin vào chương trình của mình? Trong khi bạn có thể deserialize nó vào một đối tượng, đó có thể là công việc bạn có thể tránh, tùy thuộc vào mục tiêu của bạn. –

+0

Bạn đã có đối tượng JSON. Bạn có nghĩa là làm thế nào để dịch nó thành một đối tượng C#? Nếu vậy hãy tạo một lớp với thuộc tính 'path',' minVersion', 'maxVersion' và sử dụng một cái gì đó như JSON.NET để deserialize. –

Trả lời

7

Với thư viện JSON.NET nó khá tầm thường:

public class Root 
{ 
    public Dictionary<string, Data> Data { get; set; } 
    public bool Success { get; set; } 
} 

public class Data 
{ 
    public string Path { get; set; } 
    public int MinVersion { get; set; } 
    public int MaxVersion { get; set; } 
} 

và sau đó:

string json = 
@"{ 
    ""data"":{ 
    ""foo.hugo.info"": { 
     ""path"": ""logon.cgi"", 
     ""minVersion"": 1, 
     ""maxVersion"": 2 
    }, 
    ""foo.Fritz.Task"": { 
     ""path"": ""Fritz/process.cgi"", 
     ""minVersion"": 1, 
     ""maxVersion"": 1 
    } 
    }, 
    ""success"": true 
}"; 
Root root = JsonConvert.DeserializeObject<Root>(json); 

Trong ví dụ này tôi đã sử dụng một đối tượng Dictionary<string, Data> để mô hình hóa các phím phức tạp 2 (foo.hugo.infofoo.Fritz.Task) vì chúng chứa các tên không thể được sử dụng trong một thành viên .NET.

+0

Bất kỳ lý do nào cho downvote? Xin vui lòng để lại một bình luận khi downvoting giải thích lý do tại sao câu trả lời này là sai. –

+0

Nó thực hiện chính xác những gì tôi cần! Ngoài ra nó sử dụng một từ điển và có thể xử lý nhiều hơn hai mục dữ liệu. Cảm ơn bạn! – GreenEyedAndy

1

Kiểm tra trang web này: http://json2csharp.com/

Paste trong chuỗi json và nó sẽ tạo ra các lớp học dành cho bạn. Tôi thường sử dụng điều này trong tay với JSON.NET để deserialize một thể hiện của đối tượng gốc.

+1

Trang chủ JSON.NET: http://json.codeplex.com/ – valverij

+1

Vui lòng xem JSON cẩn thận hơn và chú ý đến các phím 'foo.hugo.info' và' foo.Fritz.Task'. Bây giờ hãy xem trang web bạn đề xuất được tạo ra cho lớp 'Data' - khá vô ích. –

+0

Điểm tốt. Tôi chưa gặp sự cố khi sử dụng trang web trước đây. 1 cho câu trả lời của bạn tốt hơn. – stevepkr84

5

Nếu bạn đang sử dụng VS2012 hoặc cao hơn bạn có thể làm như sau:

Edit > Paste Special > Paste JSON As Classes 

Với ví dụ của bạn, điều này dẫn đến:

public class Rootobject 
{ 
    public Data data { get; set; } 
    public bool success { get; set; } 
} 

public class Data 
{ 
    public FooHugoInfo foohugoinfo { get; set; } 
    public FooFritzTask fooFritzTask { get; set; } 
} 

public class FooHugoInfo 
{ 
    public string path { get; set; } 
    public int minVersion { get; set; } 
    public int maxVersion { get; set; } 
} 

public class FooFritzTask 
{ 
    public string path { get; set; } 
    public int minVersion { get; set; } 
    public int maxVersion { get; set; } 
} 
+1

Bất kỳ ví dụ mã nào về serializer bạn sẽ sử dụng để deserialize JSON được hiển thị trong OP cho các lớp đó? Tôi đặc biệt quan tâm đến các thuộc tính 'foohugoinfo' và' fooFritzTask'. –

+0

Điều này có thể không trả lời đầy đủ câu hỏi của OP, nhưng tôi phải nói ... mind = blown. Tôi không biết cái gì ẩn nấp trong menu chỉnh sửa cho đến bây giờ. –

+2

Điều này không linh hoạt, nếu một biến thể thứ ba được thêm vào, bạn sẽ cần tạo một lớp khác và thêm lớp này vào lớp 'Dữ liệu' làm thuộc tính. – christiandev

1

Bạn có thể sử dụng DataContractJsonSerializer

[DataContract] 
    public class DetailedData 
    { 
     [DataMember(Name="path")] 
     public string Path { get; set; } 
     [DataMember(Name = "minVersion")] 
     public int MinVersion { get; set; } 
     [DataMember(Name = "maxVersion")] 
     public int MaxVersion { get; set; } 
    } 

    [DataContract] 
    public class Data 
    { 
     [DataMember(Name = "foo.hugo.info")] 
     public DetailedData Info { get; set; } 
     [DataMember(Name = "foo.Fritz.Task")] 
     public DetailedData Task { get; set; } 
    } 

    [DataContract] 
    public class RootObject 
    { 
     [DataMember(Name = "data")] 
     public Data Data { get; set; } 
     [DataMember(Name = "success")] 
     public bool Success { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     string json = "..."; 
     DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(RootObject)); 

     RootObject obj = (RootObject)js.ReadObject(new MemoryStream(Encoding.Unicode.GetBytes(json))); 
     Console.WriteLine(obj.Data.Task.MaxVersion); 
    } 

Chỉnh sửa: cùng một lớp cho InfoTask

+0

Bạn có thể đã sử dụng cùng một lớp cho 'Info' và' Task'. Khác hơn thế, câu trả lời tốt và đầy đủ, +1. –

+0

Tôi vừa hoàn thành chỉnh sửa :) –

+0

Điều này hoạt động tốt, nhưng những gì tôi quên viết là dữ liệu: là động. Nó có thể là bất kỳ đếm các mục khác nhau, nhưng mọi lúc với đường dẫn, minVersion và maxVersion thành viên. Chỉ các tên (foo.hugo.info/foo.fritz.task) mới có thể thay đổi. – GreenEyedAndy

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