Làm cách nào để thay đổi tên thuộc tính khi xê-ri hóa với Json.net?


434

Tôi có một số dữ liệu trong một đối tượng C # Dataset. Tôi có thể tuần tự hóa nó ngay bây giờ bằng cách sử dụng trình chuyển đổi Json.net như thế này

DataSet data = new DataSet();
// do some work here to populate 'data'
string output = JsonConvert.SerializeObject(data);

Tuy nhiên, điều này sử dụng tên thuộc tính từ datakhi in sang tệp .json. Tôi muốn thay đổi tên thuộc tính thành một cái gì đó khác biệt (giả sử thay đổi 'foo' thành 'bar').

Trong tài liệu của Json.net , trong phần 'Tuần tự hóa và giải tuần tự hóa' → 'Thuộc tính tuần tự hóa' có ghi "JsonPropertyAttribution ... cho phép tên được tùy chỉnh". Nhưng không có ví dụ. Có ai biết cách sử dụng JsonPropertyAttribution để thay đổi tên thuộc tính thành tên khác không?

( Liên kết trực tiếp đến tài liệu )

Tài liệu của Json.net dường như còn thưa thớt. Nếu bạn có một ví dụ tuyệt vời tôi sẽ cố gắng thêm nó vào tài liệu chính thức. Cảm ơn!


3
FYI, có một ví dụ về điều này trong tài liệu dưới Mẫu -> Tuần tự hóa JSON -> Tên JsonPropertyAttribution . Không chắc chắn tại điểm nó đã được thêm vào.
Brian Rogers

Câu trả lời:


791

Bạn có thể trang trí thuộc tính bạn muốn kiểm soát tên của nó bằng [JsonProperty]thuộc tính cho phép bạn chỉ định một tên khác:

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }

Tài liệu: Thuộc tính tuần tự hóa


1
Điều này có yêu cầu tôi đọc dữ liệu của mình vào một đối tượng tùy chỉnh mà tôi tạo chứ không phải là Bộ dữ liệu không?
kết hợp

3
@culix, vâng, nó yêu cầu sử dụng một mô hình. Một tập dữ liệu là một cấu trúc được gõ yếu, vì vậy nói về tên thuộc tính cho nó là không hợp lý.
Darin Dimitrov

76
Là một tốc ký, bạn cũng có thể làm[JsonProperty("FooBar")]
Bart Verkoeijen 16/2/2015

2
@DarinDimitrov có cách nào để làm điều này mà không cần Json .NET không?
CH81

12
Mặc dù vậy, việc sử dụng một mô hình rất dễ dàng, chỉ cần lấy một mẫu JSON của bạn và Dán nó vào một tệp .cs trống bằng cách sử dụng "Dán đặc biệt" -> "Dán JSON dưới dạng các lớp". - Nó được tích hợp vào Visual Studio. - Từ đó, về cơ bản, bạn chỉ cần thiết lập mọi thứ như trường hợp tiêu đề / đổi tên công cụ để sử dụng các quy ước đặt tên .NET, v.v. (sử dụng trình chuyển đổi trường hợp tiêu đề cho cái trước và thuộc tính JsonProperty cho cái sau).
BrainSlugs83

71

Nếu bạn không có quyền truy cập vào các lớp để thay đổi các thuộc tính hoặc không muốn luôn sử dụng cùng một thuộc tính đổi tên, việc đổi tên cũng có thể được thực hiện bằng cách tạo một trình phân giải tùy chỉnh.

Ví dụ: nếu bạn có một lớp được gọi MyCustomObject, có một thuộc tính được gọi LongPropertyName, bạn có thể sử dụng trình phân giải tùy chỉnh như thế này

public class CustomDataContractResolver : DefaultContractResolver
{
  public static readonly CustomDataContractResolver Instance = new CustomDataContractResolver ();

  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
  {
    var property = base.CreateProperty(member, memberSerialization);
    if (property.DeclaringType == typeof(MyCustomObject))
    {
      if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase))
      {
        property.PropertyName = "Short";
      }
    }
    return property;
  }
}

Sau đó gọi để tuần tự hóa và cung cấp trình phân giải:

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });

Và kết quả sẽ được rút ngắn thành {"Short": "prop value"} thay vì {"LongPropertyName": "prop value"}

Thông tin thêm về bộ giải quyết tùy chỉnh tại đây


1
Đây là một giải pháp tốt hơn nếu lớp của bạn để tuần tự hóa được khai báo trong một hội đồng khác bao gồm một phiên bản khác của gói Newtonsoft.Json. (nó thậm chí có thể không ném bất kỳ lỗi nào). Các DefaultContractResolverphải được đặt trong cùng một assembly mà phương pháp JsonConvert.Serialize () được sử dụng.
Khủng khiếp

6

Vẫn còn một cách khác để làm điều đó, đó là sử dụng một NamingStrargety cụ thể , có thể được áp dụng cho một lớp hoặc một thuộc tính bằng cách trang trí chúng bằng [JSonObject]hoặc [JsonProperty].

Có những chiến lược đặt tên được xác định trước như thế nào CamelCaseNamingStrategy, nhưng bạn có thể thực hiện những chiến lược của riêng mình.

Việc thực hiện các chiến lược đặt tên khác nhau có thể được tìm thấy ở đây: https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization


3
Nếu bạn có thể, vui lòng chia sẻ một ví dụ về cách triển khai NamingStrargety tùy chỉnh
user1007074

Dĩ nhiên là không. Bạn nên tự mình làm điều đó, nhưng tôi sẽ dành cho bạn thời gian để nói với bạn rằng bạn chỉ cần kế thừa newtonsoft.com/json/help/html/ Lỗi Bạn có thể thấy việc triển khai các lớp hiện có và tạo lớp của riêng bạn.
JotaBe

Cảm ơn - Tôi đã cập nhật nhận xét của mình: thực tế, nhờ vào vinh quang đó là GitHub, người ta có thể sử dụng một trong những triển khai của Newtonsoft làm ví dụ, ví dụ này
user1007074 11/12/18

8
@JotaBe, đó không phải là tinh thần của stackoverflow. Và với tư cách là một lập trình viên chỉ muốn hoàn thành công việc của tôi, thành thật mà nói, nó sẽ tốt hơn gấp ngàn lần đối với tôi để nâng mã mà bạn có thể đã cung cấp. Và bạn sẽ có được phiếu bầu của tôi là tốt. Tôi có 18 năm kinh nghiệm mã hóa và tôi được TripleByte xếp hạng là "chuyên gia" trong c #. Không phải MỌI vấn đề cần phải được để lại như một "bài tập cho người đọc". Đôi khi chúng tôi chỉ muốn làm công việc của mình và đi tiếp.
bboyle1234

2
Tôi đồng ý với bạn và tôi thường không viết loại bình luận này. Tuy nhiên, tôi có thể đảm bảo rằng, trong trường hợp này, nhìn vào mã được liên kết là cách tốt hơn bất kỳ lời giải thích nào tôi có thể đưa ra. Và json.net là một thư viện mã nguồn mở rất tốt. Bao gồm liên kết đến các triển khai (ví dụ hoàn hảo)
JotaBe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.