5

Tôi có biểu đồ đối tượng hình tròn trong mô hình của mình, nhưng điều đó là không thể tránh khỏi.Nhận mã trạng thái 500 http trống từ API Web

Theo lời khuyên được đưa ra trong this article, tôi đã sử dụng DataContractAttribute và đặt IsReference = true trên tất cả các thành viên. Tôi cũng đã cung cấp DataMemberAttribute trên tất cả các thuộc tính mà tôi muốn tuần tự hóa.

Để đảm bảo rằng bộ nối tiếp không gặp phải bất kỳ vấn đề nào một lần nữa, tôi chỉ chọn không để tuần tự hóa các thuộc tính điều hướng.

Tuy nhiên, tôi vẫn gặp phải ngoại lệ trong khối catch của mình. Các chi tiết của các ngoại lệ như sau:

 _innerException: {"Type 
'System.Data.Entity.DynamicProxies.Author_615FB9F8BB22B55A7CA168DA5ED29EC6A0B59F62FD79D1346045351BE2F163A4' with data contract name 
    'Author_615FB9F8BB22B55A7CA168DA5ED29EC6A0B59F62FD79D1346045351BE2F163A4: 
http://schemas.datacontract 
    .org/2004/07/System.Data.Entity.DynamicProxies' is not expected. 
Consider using a 
    DataContractResolver or add any types not known statically to 
the list of known types - for 
    example, by using the KnownTypeAttribute attribute or by adding them 
to the list of known types 
    passed to DataContractSerializer."} 

tôi có thể nhưng không muốn:

1) Vô hiệu hoá tạo proxy. Tôi có thể loại bỏ proxy tạo ra chỉ vì lợi ích của serialization, mà tôi có thể làm. Nhưng tôi cũng muốn tìm hiểu lý do tại sao tôi vẫn nhận được ngoại lệ và những gì tôi có thể làm về nó.

2) Xóa tham chiếu vòng tròn. Lý do: Các kiểu tham chiếu này rất phổ biến trong các mô hình tạo ra khung Entity Framework. Nếu tôi đang làm một dự án lớn với 800 - 1000 lớp học trong mô hình, đó là một cơn ác mộng để thực hiện nó bằng cách loại bỏ các tham chiếu vòng tròn.

Tôi đã mô tả các yếu tố kiến ​​trúc của giải pháp tăng đột biến nhỏ này bên dưới.

Database Schema

Id AuthorName 
------------------------------- 
1 Charles Dickens 
2 Charles Petzold 
3 Charles Darwin 
4 Charles Chaplin 
5 Leo Tolstoy 
6 Fydor Dostoevsky 
7 Ayn Rand 
8 Napolean Hill 
9 Claude M. Bristol 
10 Edward Dwight Easty 
11 O. Henry 
12 William Shakespeare 
13 Juwal Lowy 
14 Jeffrey Richter 
15 Chris Sells 
16 Don Box 
17 Steven Pinker 
18 Jim Rohn 
19 George Eliot 
20 Sathyaish Chakravarthy 



Id   Title            AuthorId 
----------- -------------------------------------------------- ----------- 
1   Nicholas Nickleby         1 


Id   BookId  Review 
----------- --------------------------------------------------------------- 
1   1   How do I know? I haven't read it. 

Mẫu

using System.Collections.Generic; 
using System.Runtime.Serialization; 

namespace BookReviewsModel 
{ 
    [DataContract(IsReference = true)] 
    public partial class Author 
    { 
     [DataMember] 
     public virtual int Id { get; set; } 

     [DataMember] 
     public virtual string AuthorName { get; set; } 

     public virtual ICollection<Book> Books { get; set; } 
    } 
} 


namespace BookReviewsModel 
{ 
    [DataContract(IsReference = true)] 
    public partial class Book 
    { 
     [DataMember] 
     public virtual int Id { get; set; } 

     [DataMember] 
     public virtual string Title { get; set; } 

     [DataMember] 
     public virtual int AuthorId { get; set; } 

     public virtual Author Author { get; set; } 

     public virtual ICollection<BookReview> BookReviews { get; set; } 
    } 
} 

namespace BookReviewsModel 
{ 
    [DataContract(IsReference = true)] 
    public partial class BookReview 
    { 
     [DataMember] 
     public virtual int Id { get; set; } 

     [DataMember] 
     public virtual int BookId { get; set; } 

     [DataMember] 
     [AllowHtml] 
     public virtual string Review { get; set; } 

     public virtual Book Book { get; set; } 
    } 
} 

điều khiển Mã

namespace BookReviews.Controllers 
{ 
    public class AuthorController : ApiController 
    { 
     [HttpGet] 
     public IEnumerable<Author> Index() 
     { 
      try 
      { 
       using (var context = new BookReviewEntities()) 
       { 
        var authors = context.Authors.ToList(); 

        var str = Serialize(new XmlMediaTypeFormatter(), authors); 

        System.Diagnostics.Debugger.Break(); 
        System.Diagnostics.Debug.Print(str); 

        return authors; 
       } 
      } 
      catch (Exception ex) 
      { 
       var responseMessage = new HttpResponseMessage 
       { 
        Content = new StringContent("Couldn't retreive the list of authors."), 
        ReasonPhrase = ex.Message.Replace('\n', ' ') 
       }; 

       throw new HttpResponseException(responseMessage); 
      } 
     } 

     string Serialize<T>(MediaTypeFormatter formatter, T value) 
     { 
      Stream stream = new MemoryStream(); 
      var content = new StreamContent(stream); 

      formatter.WriteToStreamAsync(typeof(T), value, stream, content, null).Wait(); 

      stream.Position = 0; 
      return content.ReadAsStringAsync().Result; 
     } 
    } 
} 
+0

tất cả các lớp học của bạn là một phần - có thể gây ra bất kỳ vấn đề bổ sung? Các phần khác của lớp học có được đánh dấu bằng thuộc tính hoặc không bắt buộc phải không? –

+0

Tôi có thể xác nhận điều này xảy ra mà không có các lớp học một phần, tuy nhiên, trong trường hợp của tôi nguyên nhân gốc có vẻ là việc sử dụng thuộc tính điều hướng ảo (không được đánh dấu để tuần tự hóa). Cần phải có một giải pháp thay thế cho điều này tương tự như giải pháp ProxyDataContractResolver + IObjectBehavior có sẵn cho các dịch vụ WCF. –

+0

Bạn đã thử tìm cách này: http://stackoverflow.com/questions/11851207/prevent-property-from-being-serialized-in-web-api hoặc http://stackoverflow.com/questions/1411577/ bỏ qua-a-field-trong-net-json-serialization-tương tự-to-xmlignore –

Trả lời

2

Giải pháp:

Vấn đề này được giải quyết trong AspNetWebStack đêm xây dựng.

Tôi chưa theo dõi việc đăng ký nào sửa chữa hành vi khi tôi theo dõi nhiều vấn đề.

Bạn có thể cập nhật giải pháp của mình để sử dụng các gói hàng đêm mới nhất bằng cách thêm http://www.myget.org/F/aspnetwebstacknightly/ vào cấu hình Trình quản lý gói của bạn và sau đó cập nhật rõ ràng từ kho lưu trữ bổ sung này.

Theo như tôi có thể nói, các 1/18 đêm là ổn định trong giải pháp của tôi (truy vấn OData trở MUCH nhanh là tốt.)

Cách giải quyết:

Nếu bạn không thể sử dụng aspnetwebstack mới nhất được xây dựng, có một cách giải quyết tiềm ẩn nếu bạn không yêu cầu nguồn cấp dữ liệu định dạng XML.

http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

Tài liệu này cho thấy làm thế nào để cấu hình và định dạng được sử dụng bởi các bộ điều khiển web-api, nó cũng cho thấy làm thế nào để đối phó với tham chiếu vòng tròn, và làm thế nào để cấu hình lại/thay thế các định dạng xml mặc định.

Là một workaround bạn có thể loại bỏ các định dạng xml trong Application_Start:

var xmlFormatter = config.Formatters.XmlFormatter; 
if (xmlFormatter != null) 
{ 
    config.Formatters.Remove(xmlFormatter); 
} 
0

Tôi không biết WebAP Tôi rất tốt, nhưng bạn giải quyết vấn đề tương tự trong WCF bằng cách sử dụng ProxyDataContractResolver. Hy vọng rằng, có một cái móc tương tự trong WebAPI?

+0

Điều này dường như không áp dụng cho một ApiController cùng một cách nó làm WCF dịch vụ (chỉ cần thử nghiệm.) –

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