Json Web Api with error

0

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

When consumed by 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 consumed by 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, all records in people and related users:

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

GET, Controller, single person and user related record (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);
}

POST, Controller code, record entry into person and user table (entering 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);
}

So I understand the user object is not being serialized correctly, but after several attempts and changes I could not make change. This code posted is the initial one.

    
asked by anonymous 14.06.2017 / 12:46

1 answer

1

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

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

'ToList ()' executes the query immediately. If it does not work, try disabling EF's LazyLoading and running everything on EagerLoading

    
14.06.2017 / 13:17