希望标题有意义,我会尽力描述我的问题。
我目前正在开发一个ASP.NET Web API。在我的"公司"控制器中,我有一个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);
}
这找到它并返回它很好,但是当我测试它时,我看到的响应是
{
"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)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)rn at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)rn at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)rn at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)rn at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext)rn--- End of stack trace from previous location where exception was thrown ---rn at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn at System.Runtime.CompilerServices.TaskAwaiter.GetResult()rn 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()rn at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)rn at System.Data.Entity.Core.Objects.ObjectQuery`1.Execute(MergeOption mergeOption)rn at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption)rn at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(MergeOption mergeOption)rn at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.Load()rn at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()rn at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)rn at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__1(TProxy proxy, TItem item)rn at System.Data.Entity.DynamicProxies.Company_40636FF93138F09772BEA689D3A3D3AB7DBB41AFF7FE3D0BEFF55FC7C1D10E0F.get_Locations()rn at GetLocations(Object )rn at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
}
}
}
我知道问题是我的属性被急切地加载,而它们从来没有被加载过。我可以告诉它在我的Company
对象中很容易地加载我的导航属性。当我这样做时,我遇到的问题是,它说前面提到的导航属性中的复杂对象也是空的,我不能那么容易地加载它们;我也不想。所以它试图加载整个"对象树",因为没有更好的表达方式(我能想到)。
所以我的问题是,解决这个问题的最佳方法是什么?
代理导致序列化程序尝试访问导航属性,这些属性由于上下文已被释放而不再可用。
当您查询将被序列化的对象时,请尝试从上下文中删除代理和急切加载
context.Configuration.ProxyCreationEnabled = false;
context.Configuration.LazyLoadingEnabled = false;