在返回json’d数据时卸载“急切加载”属性导致问题

希望标题有意义,我会尽力描述我的问题。

我目前正在开发ASP.NET Web API。 在我的“公司”控制器中,我有一个GetCompany()动作。

///  /// Gets the 'Authorization-Token' request header and finds the company with the /// matching decrypted token from the database, returns it; if null, returns 404 ///  /// Matching company for token passed in request or 404 if null [HttpGet][ResponseType(typeof(Company))] [Route("api/company/")] public HttpResponseMessage GetCompany() { string token = Request.Headers.GetValues("Authorization-Token").First(); ICollection companies; Company c; using (BaseRepository r = new BaseRepository()) { companies = r.Get(null, null, null); c = companies.Where(cm => RSA.Decrypt(cm.Token) == token).FirstOrDefault(); } if (c == null) return Request.CreateResponse(HttpStatusCode.NotFound, c); return Request.CreateResponse(HttpStatusCode.OK, c); } 

这找到它并返回它就好了,但是当我测试它时,我看到的响应是

 { "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.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.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)" } } } 

我理解问题是我的属性是急切加载的,并且它们从未加载过。 我可以告诉它很容易在我的Company对象中加载我的导航属性。 当我这样做时遇到的问题是,它说上述导航属性中的复杂对象也是空的,我不能那么容易地加载它们; 我也不想。 所以它试图加载整个“对象树”,因为缺乏更好的说法(我能想到)。

所以我的问题是,解决这个问题的最佳方法是什么?

代理导致序列化程序尝试访问自上下文处理后不再可用的导航属性。

在查询要序列化的对象时,请尝试从上下文中删除代理和急切加载

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