5

Modelimde dairesel bir nesne grafiğim var, ancak bu kaçınılmaz.Web API'sından boş bir 500 http durum kodu alma

this article numaralı belgede verilen tavsiyelere göre, tüm üyelere DataContractAttribute'u kullandım ve IsReference = true'u ayarlayın. Serileştirmek istediğim tüm özelliklerde DataMemberAttribute'u da sağladım.

Diziselleştiricinin tekrar bir sorunla karşılaşmadığından emin olmak için gezinme özelliklerini serileştirmek üzere yalnızca değil seçtim. Bununla birlikte, yine de benim catch bloğumda bir istisna ile karşılaşıyorum. istisna detayları aşağıdaki gibidir:

 _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."} 

elimden ancak istemeyen:

1) devre dışı bırakın vekil yaratılması. Proxy oluşturmayı sadece serileştirme uğruna kaldırabilirim, yapabilirim. Ama yine de neden hala istisna alıyorum ve bunun hakkında neler yapabileceğimi öğrenmek istiyorum.

2) Dairesel referansları kaldırın. Nedeni: Bu tür referanslar Entity Framework tarafından oluşturulan modellerde çok yaygındır. Modelde 800 - 1000 sınıflı büyük bir proje yapıyor olsaydım, dairesel referansları kaldırarak bunu uygulamak bir kabus olurdu.

Bu küçük başak çözümünün mimari elemanlarını aşağıda tarif ettim.

Veritabanı Şeması

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. 

Modeli

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; } 
    } 
} 

Kontrolör Kod

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üm sınıfları kısmi şunlardır: Eğer Application_Start sırasında xml biçimlendirici kaldırabilir Çözüm olarak

? Sınıfların diğer bölümleri de öznitelikle işaretlenmiş mi yoksa gerekli değil mi? –

+0

Bunun kısmen kısmi sınıflar olmadan gerçekleştiğini onaylayabilirim, ancak benim durumumda, temel neden sanal gezinme özelliğinin (serileştirme için işaretlenmemiş) kullanılması gibi görünüyor. WCF hizmetleri için mevcut olan ProxyDataContractResolver + IObjectBehavior özümüne benzer bir çözüm için temiz bir çözüm olması gerekir. –

+0

Bunu denediniz mi: http://stackoverflow.com/questions/11851207/prevent-property-from-being-serialized-in-web-api veya bu bir http://stackoverflow.com/questions/1411577/ net-json-serialization-benzeri-xmlignore –

cevap

2

Çözüm:

Bu sorun AspNetWebStack Gecelik Build'a çözümlenir.

Birden çok soruna yanıt verirken hangi check-inin davranışı düzelttiğini takip etmedim.

Paket Yöneticisi yapılandırmanıza http://www.myget.org/F/aspnetwebstacknightly/ ekleyerek ve sonra bu ek depodan açıkça güncelleştirerek en son gece paketlerini kullanmak için çözümünüzü güncelleyebilirsiniz.

Bildiğim kadarıyla söyleyebilirim, 1/18 gece benim çözüm içinde kararlıdır

(OData sorguları Çok hızlı de döner.)

Geçici çözüm:

sen kullanamıyorsanız En son aspnetwebstack oluşturur, XML formatlı bir besleme gerektirmezseniz, olası bir geçici çözüm vardır.

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

Bu belge web api kontrolörleri tarafından kullanılan biçemleyicileri nasıl yapılandırılacağı gösterilmektedir, aynı zamanda dairesel referanslarla nasıl başa ve/yeniden varsayılan xml biçimlendirici nasıl değiştirileceği gösterilmektedir. - herhangi bir ek sorunlara neden olabilir

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

Bilmiyorum WebAP Çok iyi, ama aynı sorunu WCF'de ProxyDataContractResolver'u kullanarak çözüyorsunuz. Umarım, WebAPI'de benzer bir kanca var mı?

+0

Bu, bir ApiController uygulamasında geçerli değildir. Aynı şekilde WCF servislerini de (sadece test edilmiştir.) –

İlgili konular