Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception on GET call on a table using Entity Framework in WebAPI [duplicate]

I'm trying to create a WebApi to read a data from the DB using Entity Framework.

My data model design looks like this:

enter image description here

I have added a WebApi controller named SportsController like this:

public class SportsController : ApiController
{
    public HttpResponseMessage Get()
    {
        try
        {
            using (MyLeagueDBEntities dbEntity = new MyLeagueDBEntities())
            {
                return Request.CreateResponse(HttpStatusCode.OK, dbEntity.tbl_Sports.ToList());
            }
        }
        catch (Exception ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
        }
    }
}

On invoking a request from browser to my WebApi controller GET method, I'm getting the exception shown below. But in debug mode, I can see that it is able to get the data from database without any error but once the control moves out of the method, it does throw the below exception.

Exception details:

"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 'tbl_Tournament' on 'System.Data.Entity.DynamicProxies.tbl_Sports_7461105FEAC4FCCBDED534FCE44707AF9C7DFE1E4AD69B1E7E3777FBB953F184'.",
"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.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract 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 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n
at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n

End of stack trace from previous location where exception was thrown

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at System.Web.Http.WebHost.HttpControllerHandler.d__1b.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.ObjectQuery1.GetResults(Nullable1 forMergeOption)\r\n
at System.Data.Entity.Core.Objects.ObjectQuery1.Execute(MergeOption mergeOption)\r\n
at System.Data.Entity.Core.Objects.DataClasses.EntityCollection
1.Load(List1 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.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.tbl_Sports_7461105FEAC4FCCBDED534FCE44707AF9C7DFE1E4AD69B1E7E3777FBB953F184.get_tbl_Tournament()\r\n
at Gettbl_Tournament(Object )\r\n
at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"}}}

I'm new to Entity Framework and WebApi, requesting one to help me out resolving this issue.

PFB the snapshot with the error message logged on fiddler. Currently getting Http 500 internal server error,

enter image description here

like image 890
Manju Avatar asked Dec 23 '22 19:12

Manju


1 Answers

It is because you have lazy loading enabled and you are serializing the object graph after you dispose of the DbContext instance. So what is happening

  • You create a DbContext
  • You retrieve the data from the DbContext for that one type
  • You pass the data to the Result method
  • Your DbContext is closed and disposed
  • Your method exists
  • Asp.Net mvc pipeline now tries to serialize the result's content
  • Relationships in your type are now attempted to be retrieved in the serialization process
  • The relationships are attempted to be retrieved from the DbContext because you have Lazy Loading enabled
  • The DbContext is disposed so access is not possible, an Exception is thrown

To fix it do one of the following

  • Move the DbContext to the class scope and dispose of it in the Disposing method (override the existing method from the ApiController)
  • (Recommended!) Turn off loazy loading and specify which properties you want to retrieve from the returned type using Include. This will enable more fine grained control over what is retrieved and is more performant because everything is retrieved in a single DB call instead of on access.
like image 139
Igor Avatar answered Dec 28 '22 05:12

Igor