6

Tôi đã phương pháp sau đây trong api web của tôi

public void Put(string id, [FromBody]IContent value) { 
    //Do stuff 
} 

Tôi đang sử dụng đường trục js để gửi JSON sau vào máy chủ sử dụng cáy giá trị là null:

{ 
    "id": "articles/1", 
    "heading": "Bar", 
    "$type": "BrickPile.Samples.Models.Article, BrickPile.Samples" 
} 

nhưng nếu tôi thêm thuộc tính $ type đầu tiên trong đối tượng JSON deserialization hoạt động tốt, xem:

{ 
"$type": "BrickPile.Samples.Models.Article, BrickPile.Samples", 
    "id": "articles/1", 
    "heading": "Bar" 
} 

có thể định cấu hình newtonsoft để kiểm tra loại $ prope rty bất cứ nơi nào trong đối tượng thay vì tài sản đầu tiên hoặc tôi có thể cấu hình xương sống vì vậy nó luôn luôn thêm các tài sản $type đầu tiên trong đối tượng JSON?

+0

Nhìn vào phản ứng @ của Levi, anh ấy là anh chàng an ninh cho nhóm web. – RickAndMSFT

+1

Hoàn toàn điên rồ khi nó hoạt động theo cách này trong JSON.NET và Microsofts được tích hợp sẵn ... Trong nhiều thư viện JSON, như Jackson trong JAVA, KHÔNG được đảm bảo rằng bản đồ (mà u có thể xây dựng ở Jackson) được sắp xếp . Trên thực tế, bản đồ của nó, và do đó không có thứ tự được duy trì. Vì vậy, bạn không có quyền kiểm soát nơi $ type hoặc __type xuất hiện trong JSON. Đôi khi nó đầu tiên, và hoạt động, đôi khi nó không. Vì vậy, nó không thể truts chức năng này ... – Ted

Trả lời

1

Điều này sẽ hoạt động trong xương sống, nhưng tôi không biết liệu mọi trình duyệt có hoạt động giống nhau hay không. Không có bảo đảm, về cơ bản, mọi trình duyệt sẽ giữ các mục theo thứ tự mà chúng được thêm vào.


MyModel = Backbone.Model.extend({ 

    // ... 

    toJSON: function(){ 
    // build the "$type" as the first parameter 
    var json = {"$type": "BrickPile.Samples.Models.Article, BrickPile.Samples"}; 
    // get the rest of the data 
    _.extend(json, Backbone.Model.prototype.toJSON.call(this)); 
    // send it back, and hope it's in the right order 
    return json; 
    } 


}); 

Bạn nên sử dụng trình giải mã JSON của NewtonSoft để làm việc mà không cần ở vị trí cụ thể. Hy vọng rằng sẽ có thể.

+0

mà làm việc khá tốt, các $ loại tài sản đã tồn tại trong mô hình xương sống, do đó, nó có thể để có được "BrickPile.Samples.Models.Article, BrickPile.Samples" từ mô hình hiện tại thay vì mã cứng chuỗi? – Marcus

+1

Tôi đoán this.get ('$ type') sẽ làm thủ thuật – Marcus

+0

Borth DataContractSerializer (Microsoft) và json.net YÊU CẦU rằng loại $ (hoặc __type trong MS) là thuộc tính đầu tiên, nếu không nó sẽ sử thi thất bại. Tại sao nó là theo cách này là hoàn toàn không thể hiểu được, nhưng đó là cách nó là ... – Ted

3

Tôi rất khuyên bạn chống lại việc định cấu hình bất kỳ bộ nối tiếp nào (bao gồm JSON.NET) để đọc loại đối tượng từ tải trọng đến. Điều này trước đây là nguyên nhân của một số lượng lớn các lỗ hổng trong các ứng dụng web. Thay vào đó, thay đổi điểm vào công khai thành hành động của bạn để lấy kiểu thực tế làm tham số ràng buộc, sau đó ủy quyền cho một phương thức thử nghiệm nội bộ nếu muốn.

+0

Vấn đề của tôi là tôi không biết loại thực tế, điều duy nhất tôi biết là nó thực hiện giao diện IContent. Tôi cũng có thể nói rằng đây không phải là API công khai, nó đòi hỏi bạn phải được xác thực. – Marcus

3

Đầu tiên, AFAIK, mã của Json.NET được tối ưu hóa để tránh giữ toàn bộ đối tượng trong bộ nhớ chỉ để đọc loại của nó. Vì vậy, tốt hơn là đặt $type làm thuộc tính đầu tiên.

Thứ hai, bạn có thể viết riêng bạn JsonConverter mà lần đọc đầu tiên JObject (sử dụng phương pháp Load), tay lần đọc $type tài sản, được gõ từ serializer của SerializationBinder, tạo ra giá trị và populates nó từ JObject.

Thứ ba, liên quan đến bảo mật. Trong khi số $type của Json.NET có vẻ như là một ý tưởng hay, thường thì không. Nó cho phép Json.NET tạo ra bất kỳ loại đối tượng nào từ bất kỳ assembly nào chỉ bằng cách viết loại của nó trong tệp JSON. Tốt hơn là sử dụng tùy chỉnh SerializationBinder bằng từ điển chỉ cho phép các loại mà bạn chỉ định. Bạn có thể tìm thấy một ví dụ trong khuôn khổ riêng tư của tôi (nó cũng hỗ trợ nhận được giá trị cho $type từ JsonObjectAttribute):

https://github.com/Athari/Alba.Framework/blob/742ff1aeeb114179a16ca42667781944b26f3815/Alba.Framework/Serialization/DictionarySerializationBinder.cs

(Phiên bản này sử dụng một số phương pháp từ các lớp khác, nhưng chúng tầm thường Sau đó cam kết đưa ra. lớp phức tạp hơn.)

+0

Cảm ơn câu trả lời của bạn, tôi sẽ xem xét mã của bạn! – Marcus