Json Web Api with error

Asked

Viewed 1,109 times

0

I have a REST service in WEB API, I use 2 related entities(person and user) relationships 1 = 1, the post to insert this ok, recover the data, searching for the user id as well, but when I try to search all the records I get the following error:

When consuming per api/people

{
   "Message": "Ocorreu um erro.",
   "ExceptionMessage": "O tipo 'ObjectContent`1' não pôde serializar o corpo da resposta para o tipo de conteúdo 'application/json; charset=utf-8'.",
   "ExceptionType": "System.InvalidOperationException",
   "StackTrace": null,
   "InnerException":    {
      "Message": "Ocorreu um erro.",
      "ExceptionMessage": "Error getting value from 'usuario' on 'System.Data.Entity.DynamicProxies.pessoa_10615507F71E197309A5BD844FC988C8C4AAC5B0982A9399E52FCCC43DBC112F'.",
      "ExceptionType": "Newtonsoft.Json.JsonSerializationException",
      "StackTrace": "   em Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)\r\n   em Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)\r\n   em Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   em Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   em Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n   em Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n   em System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   em System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   em System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---\r\n   em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   em System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()",
      "InnerException":       {
         "Message": "Ocorreu um erro.",
         "ExceptionMessage": "An error occurred while executing the command definition. See the inner exception for details.",
         "ExceptionType": "System.Data.Entity.Core.EntityCommandExecutionException",
         "StackTrace": "   em System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)\r\n   em System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)\r\n   em System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)\r\n   em System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()\r\n   em System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)\r\n   em System.Data.Entity.Core.Objects.DataClasses.EntityReference`1.Load(MergeOption mergeOption)\r\n   em System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()\r\n   em System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)\r\n   em System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__2(TProxy proxy, TItem item)\r\n   em System.Data.Entity.DynamicProxies.pessoa_10615507F71E197309A5BD844FC988C8C4AAC5B0982A9399E52FCCC43DBC112F.get_usuario()\r\n   em Getusuario(Object )\r\n   em Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)",
         "InnerException":          {
            "Message": "Ocorreu um erro.",
            "ExceptionMessage": "There is already an open DataReader associated with this Connection which must be closed first.",
            "ExceptionType": "MySql.Data.MySqlClient.MySqlException",
            "StackTrace": "   em MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)\r\n   em MySql.Data.MySqlClient.MySqlCommand.CheckState()\r\n   em MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)\r\n   em MySql.Data.Entity.EFMySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   em System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)\r\n   em System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)\r\n   em System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)"
         }
      }
   }
}

When consuming per api/people/5

{
   "usuario":    {
      "id": 3,
      "login": "gleyson",
      "senha": "123456",
      "ativo": "S"
   },
   "id": 3,
   "tipo": "J",
   "razao_social": "INTELIDER",
   "nome_fantasia": "INTELIDER",
   "cpf_cnpj": "0",
   "rg_insc_estadual": "0"
}

GET, Controller ,code of all records on people and related users:

// GET: api/pessoas
public IQueryable <pessoa> Getpessoa() {
    return db.pessoa;
}

GET, Controller, Unique Person and User Registration Code Related (Bringing Correct Return):

// GET: api/pessoas/5
[ResponseType(typeof(pessoa))]
public IHttpActionResult Getpessoa(int id)
{
    pessoa pessoa = db.pessoa.Find(id);
    if (pessoa == null)
    {
        return NotFound();
    }
    return Ok(pessoa);
}

Code of POST, Controller, entry of record in the table person and user(inserting correct):

// POST: api/pessoas
[ResponseType(typeof(pessoa))]
public IHttpActionResult Postpessoa(pessoa pessoa) {
    if (!ModelState.IsValid) {
        return BadRequest(ModelState);
    }

    db.pessoa.Add(pessoa);

    var usuario = new usuario {
        id = pessoa.id,
        login = pessoa.usuario.login,
        senha = pessoa.usuario.senha,
        ativo = pessoa.usuario.ativo
    };

    db.pessoa.Add(pessoa);
    usuario.pessoa = pessoa;
    db.usuario.Add(usuario);

    try {
        db.SaveChanges();
    }
    catch(DbUpdateException) {
        if (pessoaExists(pessoa.id)) {
            return Conflict();
        }
        else {
            throw;
        }
    }

    return CreatedAtRoute("DefaultApi", new { id = pessoa.id }, pessoa);
}

From what I understand the user object is not being serialized in the correct way, but after several attempts and changes I could not make change. This code posted is the initial.

2 answers

1


When you work with EF it is never a good practice to return a "Iqueryable". He is trying to serialize a Dynimicproxie that is generated by EF for query execution. I believe that the problem is there, it does the serialization on top of the 'promise' of the objects and not on the objects themselves. It does so

public IEnumerable<pessoa> Getpessoa()
{
    return db.pessoa.ToList();
}

'Tolist()' executes the query immediately. If it does not work, try to disable EF Lazyloading and run everything in Eagerloading

  • worked blz @Felipe , thanks for the help friend!

-2

Add in Context the following code:

        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
  • Even if the answer is correct, try to explain why this will solve the problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.