GET method error when consuming WebApi

2

I created a project in AspNet WebApi, I added an ADO (DataBase-first) to connect with the Mysql database and created the controller using the 'Controller with read / write actions and views, using Entity Framework' / strong>, when I test in a table that has no relationships (foreign key) I can do all the operations (GET, POST, PUT, DELETE) without problems, however, when I use a table that has some relationship, the methods that use GET bring the errors:

{
   "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 'categoria1' on 'System.Data.Entity.DynamicProxies.categoria_AFADBC1AC82DEC74C8DC54EEEDBFC75EBDE4C72DE1B441D01DF364DCB962FD70'.",
      "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.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, 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.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, 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.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\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.ObjectQuery'1.<>c__DisplayClass7.<GetResults>b__6()\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.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func'1 operation)\r\n   em System.Data.Entity.Core.Objects.ObjectQuery'1.GetResults(Nullable'1 forMergeOption)\r\n   em System.Data.Entity.Core.Objects.ObjectQuery'1.Execute(MergeOption mergeOption)\r\n   em System.Data.Entity.Core.Objects.DataClasses.EntityCollection'1.Load(List'1 collection, MergeOption mergeOption)\r\n   em System.Data.Entity.Core.Objects.DataClasses.EntityCollection'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__1(TProxy proxy, TItem item)\r\n   em System.Data.Entity.DynamicProxies.categoria_AFADBC1AC82DEC74C8DC54EEEDBFC75EBDE4C72DE1B441D01DF364DCB962FD70.get_categoria1()\r\n   em Getcategoria1(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.MySqlConnection.Throw(Exception ex)\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.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n   em System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext'1 c)\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.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   em System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n   em System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)"
         }
      }
   }
}

The class created by database-first is:

namespace take5.Models
{
    using System;
    using System.Collections.Generic;

    public partial class categoria
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public categoria()
        {
            this.categoria1 = new HashSet<categoria>();
            this.produto_categoria = new HashSet<produto_categoria>();
        }

        public int id { get; set; }
        public string descricao { get; set; }
        public int categoria_id { get; set; }
        public Nullable<int> filial_id { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<categoria> categoria1 { get; set; }
        public virtual categoria categoria2 { get; set; }
        public virtual filial filial { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<produto_categoria> produto_categoria { get; set; }
    }
}

and the controller is:

namespace take5.Controllers
{
    public class categoriasController : ApiController
    {
        private MeuContexto db = new MeuContexto();

        // GET: api/categorias
        public IQueryable<categoria> Getcategoria()
        {
            return db.categoria;
        }

        // GET: api/categorias/5
        [ResponseType(typeof(categoria))]
        public IHttpActionResult Getcategoria(int id)
        {
            categoria categoria = db.categoria.Find(id);
            if (categoria == null)
            {
                return NotFound();
            }

            return Ok(categoria);
        }

        // PUT: api/categorias/5
        [ResponseType(typeof(void))]
        public IHttpActionResult Putcategoria(int id, categoria categoria)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != categoria.id)
            {
                return BadRequest();
            }

            db.Entry(categoria).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!categoriaExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        // POST: api/categorias
        [ResponseType(typeof(categoria))]
        public IHttpActionResult Postcategoria(categoria categoria)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.categoria.Add(categoria);

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

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

        // DELETE: api/categorias/5
        [ResponseType(typeof(categoria))]
        public IHttpActionResult Deletecategoria(int id)
        {
            categoria categoria = db.categoria.Find(id);
            if (categoria == null)
            {
                return NotFound();
            }

            db.categoria.Remove(categoria);
            db.SaveChanges();

            return Ok(categoria);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool categoriaExists(int id)
        {
            return db.categoria.Count(e => e.id == id) > 0;
        }
    }
}

Does anyone have an idea why this happens?

    
asked by anonymous 03.06.2017 / 07:45

2 answers

0

I was able to solve the problem by adding [JsonIgnore] to the virtual property of each field I wanted to ignore:

[JsonIgnore]
        public virtual ICollection<categoria> categoria1 { get; set; }
        [JsonIgnore]
        public virtual categoria categoria2 { get; set; }
        [JsonIgnore]
        public virtual filial filial { get; set; }
         [JsonIgnore]
        public virtual ICollection<produto_categoria> produto_categoria { get; set; }

I found this solution on the

03.06.2017 / 18:01
0

I believe this to occur because the categoria1 property is of the same type as the class in question.

Try adding the following attribute to the class:

[JsonObject(IsReference = true)]
    
03.06.2017 / 12:59