2014-04-15 16 views
8

Speriamo che il titolo abbia senso, farò del mio meglio per descrivere il mio problema.Proprietà "caricate dal eager" scariche che causano problemi quando si restituiscono dati json

Attualmente sto sviluppando un'API Web ASP.NET. Nel mio controller "Azienda" ho un'azione GetCompany().

/// <summary> 
    /// Gets the 'Authorization-Token' request header and finds the company with the 
    /// matching decrypted token from the database, returns it; if null, returns 404 
    /// </summary> 
    /// <returns>Matching company for token passed in request or 404 if null</returns> 
    [HttpGet][ResponseType(typeof(Company))] 
    [Route("api/company/")] 
    public HttpResponseMessage GetCompany() { 
     string token = Request.Headers.GetValues("Authorization-Token").First(); 

     ICollection<Company> companies; 
     Company c; 
     using (BaseRepository r = new BaseRepository()) { 
      companies = r.Get<Company>(null, null, null); 
      c = companies.Where(cm => RSA.Decrypt(cm.Token) == token).FirstOrDefault<Company>(); 
     } 
     if (c == null) 
      return Request.CreateResponse(HttpStatusCode.NotFound, c); 

     return Request.CreateResponse(HttpStatusCode.OK, c); 
    } 

Questo lo trova e lo restituisce bene, ma quando sto testando questo, la risposta che vedo è

{ 
    "Message": "An error has occurred.", 
    "ExceptionMessage": "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.", 
    "ExceptionType": "System.InvalidOperationException", 
    "StackTrace": null, 
    "InnerException": { 
     "Message": "An error has occurred.", 
     "ExceptionMessage": "Error getting value from 'Locations' on 'System.Data.Entity.DynamicProxies.Company_40636FF93138F09772BEA689D3A3D3AB7DBB41AFF7FE3D0BEFF55FC7C1D10E0F'.", 
     "ExceptionType": "Newtonsoft.Json.JsonSerializationException", 
     "StackTrace": " at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__14.MoveNext()", 
     "InnerException": { 
      "Message": "An error has occurred.", 
      "ExceptionMessage": "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.", 
      "ExceptionType": "System.ObjectDisposedException", 
      "StackTrace": " at System.Data.Entity.Core.Objects.ObjectContext.get_Connection()\r\n at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)\r\n at System.Data.Entity.Core.Objects.ObjectQuery`1.Execute(MergeOption mergeOption)\r\n at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption)\r\n at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(MergeOption mergeOption)\r\n at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.Load()\r\n at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()\r\n at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)\r\n at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__1(TProxy proxy, TItem item)\r\n at System.Data.Entity.DynamicProxies.Company_40636FF93138F09772BEA689D3A3D3AB7DBB41AFF7FE3D0BEFF55FC7C1D10E0F.get_Locations()\r\n at GetLocations(Object)\r\n at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)" 
     } 
    } 
} 

Capisco il problema è che le mie proprietà sono ansioso-caricato e che non sono mai stati caricati Posso dire di caricare abbastanza facilmente le mie proprietà di navigazione all'interno dell'oggetto Company. Il problema che sto incontrando quando lo faccio è che sta dicendo che anche gli oggetti complessi all'interno di quelle proprietà di navigazione di cui sopra sono nulli e non posso caricarli così facilmente; né voglio. Quindi sta tentando di caricare l'intero "albero degli oggetti" per mancanza di un modo migliore per dirlo (che mi viene in mente).

Quindi la mia domanda è, qual è il modo migliore per aggirare questo?

risposta

11

Il proxy sta causando al serializzatore di tentare di accedere alle proprietà di navigazione che non sono più disponibili poiché il contesto è stato eliminato.

provare a rimuovere il proxy e eager loading dal contesto in cui si sta eseguendo la query per gli oggetti che verrà serializzato

context.Configuration.ProxyCreationEnabled = false; 
context.Configuration.LazyLoadingEnabled = false; 
+0

Grazie! Sto guidando verso casa al momento, ma controllerò su quando posso! –

+0

Ha funzionato come un incantesimo, lo stava facendo in OnModelCreating prima dicendo "base.Configuration. *" Prima ma spostandolo al costruttore del mio contesto lo ha risolto. –

+0

Volevo solo estenderlo, a volte non si desidera passare al caricamento ansioso a causa delle implicazioni sulle prestazioni che potrebbero avere se si utilizzano i propri oggetti (pesanti) altrove. In questo caso, considera di avvolgere l'oggetto lazy in un altro oggetto (ad esempio un ViewModel) e valutare solo le proprietà di cui hai bisogno. – Marcus

Problemi correlati