Introduce the Entity Framework Entity Set:
public class Country { public string CountryCode { get; set; } public string Name { get; set; } public string Flag { get; set; } } public class Market { public string CountryCode { get; set; } public virtual Country Country { get; set; } public int ProductID { get; set; } public virtual Product Product { get; set; } } public class Product { public int ProductID { get; set; } public string Name { get; set; } public virtual ICollection<Market> Markets{ get; set; } }
Imagine also that DOTNET 5 api GET
// GET api/product [HttpGet] public async Task<IActionResult> GetProduct([FromRoute] int id) { return Ok(await _context.Products .Include(p => p.Markets) .SingleAsync(m => m.ProductID == id)); }
If markets are not tied to an object, the data is returned without problems, but as soon as I have several related items, I get an error message:
HTTP Error 502.3 - Bad Gateway
The specified CGI application detected an error and the server terminated the process.
I vaguely recall the previous application in which each complex EF object had an object of type "only primitives" for sending and receiving this object to the client and back, but I wonder if there is a way to communicate without intermediary objects?
eg:
public class ProductViewModel { public int ProductID { get; set; } public string Name { get; set; } public List<MarketViewModel> Markets{ get; set; } } public class MarketViewModel { public int ProductID { get; set; } public Country Country { get; set; } }
My concern is the overhead of coding to translate each complex object back and forth from the client (which, I admit, I'm not sure if this is even bad, maybe it should be done anyway).
Since the forest APIs seem to take and return entities directly, I wonder if there is a way to handle the complex part of the object directly.
Edit # 1:
Per Noel's comment below if I change the code causing the error
[HttpGet("{id}", Name = "GetProduct")] public async Task<IActionResult> GetProduct([FromRoute] int id) { Product product = await _context.Products .Include(t => t.Markets) .SingleAsync(m => m.ProductID == id); throw new System.Exception("error sample"); return Ok(product); }
The stack trace is correctly selected. If I remove the exception, a 500 gateway error will appear. I agree that this seems like a serialization error, but it's hard to say.
EDIT 2 - for a comment from Oleg below:
The bad gateway solution should first explicitly update the newer version of NewtonSoft.Json in the dependencies in the project.json file:
"dependencies": { "Newtonsoft.Json": "8.0.1-beta3",
Next, you must modify the file Startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddMvc() .AddJsonOptions(options => { options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; });
with these two settings, the bad gateway no longer occurs, and the api call successfully returns the complex object as expected.