问题
I'm experiencing a problem using TableController on AzureMobileApps. I've created a new Azure Mobile App TableController in visual studio using scaffolding. In post I modified the resulting code adding an attach on the dbContext to avoid creating referenced item during insert on the child table. That's the resulting code:
public async Task<IHttpActionResult> PostLocation(Location item)
{
_context.Accounts.Attach(item.LocationAccount);
_context.Categories.Attach(item.PrimaryCategory);
Location current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
The problem is that each time I invoke the post method I get a 500 internal server error on the "CreatedAtRoute" event even if the entity has been correctly inserted.
Any idea on what is the problem ?!
UPDATE: Entity Model
public class Account : EntityData
{
public Account()
{
this.Locations = new HashSet<Location>();
}
[Required]
public string Username { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public virtual ICollection<Location> Locations { get; private set; }
}
public class Location : EntityData
{
[Required]
public Account LocationAccount { get; set; }
........
}
Thanks everyone.
回答1:
AFAIK, before you adding Attach
related code, if the LocationAccount
,PrimaryCategory
are the new items, then they would be created automatically. If any of them (LocationAccount
,PrimaryCategory
) exists in the database table, then you would retrieve the 409 status code.
Based on my test, after added Attach
related code, if LocationAccount
and PrimaryCategory
exist, then you could create new Location
item successfully. But if any of them does not exist, then you may get the error as follows:
Per my understanding, you need to check if the navigation properties of Location
exist. For the existing navigation property item you could use the DbSet.Attach
method to stop the attached entity from inserting, while the new navigation property item, you need to use DbSet.Add
or do nothing.
Moreover, you could add the following code in the ConfigureMobileApp
method of your Startup.MobileApp.cs
file for including error details and return to your client side.
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
UPDATE:
By default, the referenced Entities (LocationAccount
,PrimaryCategory
) would be inserted, if any entity exists, then you would receive the 409 as follows:
After added _context.Accounts.Attach(item.LocationAccount);
, you could create the Location
entity which has relationships with the existing referenced Entities (LocationAccount
,PrimaryCategory
), if the referenced Entities (LocationAccount
,PrimaryCategory
) do not exist, you would receive the following error:
For your scenario, you post the existing referenced Entities (LocationAccount
,PrimaryCategory
) for location. Even though the location item could be successfully created, based on your entity models, you may encounter the 500 error as follows:
You may mark the Locations
property in Account
entity model as JsonIgnore
. Or you need to modify your entity model to ignore the reference Loops when handling serialization.
Moreover, you could leverage the following code snippet instead of CreatedAtRoute
.
return Json(current, new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
I also tried to set the global setting for SerializerSettings under Startup.MobileApp.cs
as follows, but it does not work as expected.
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
Additionally, you could follow Loop Reference handling in Web API for more detailed approaches.
来源:https://stackoverflow.com/questions/48891640/error-500-on-post-new-entity-with-tablecontroller-and-azuremobileapps