Post 带有 TableController 和 AzureMobileApps 的新实体出现错误 500

Error 500 on Post new entity with TableController and AzureMobileApps

我在 AzureMobileApps 上使用 TableController 时遇到问题。我使用脚手架在 visual studio 中创建了一个新的 Azure 移动应用程序 TableController。在 post 中,我修改了生成的代码,在 dbContext 上添加了一个附件,以避免在子 table 上插入期间创建引用项。这是结果代码:

 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);
    }

问题是每次我调用 post 方法时,我都会在 "CreatedAtRoute" 事件上收到 500 内部服务器错误,即使实体已正确插入也是如此。

知道问题出在哪里吗?!

更新:实体模型

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; }

    ........
}   

谢谢大家

AFAIK,在添加Attach相关代码之前,如果LocationAccountPrimaryCategory是新项目,那么它们会自动创建。如果它们中的任何一个 (LocationAccount,PrimaryCategory) 存在于数据库 table 中,那么您将检索 409 状态代码。

根据我的测试,添加Attach相关代码后,如果LocationAccountPrimaryCategory存在,则可以成功创建新的Location项。但是如果其中任何一个不存在,那么你可能会得到如下错误:

据我了解,您需要检查 Location 的导航属性是否存在。对于现有的导航 属性 项目,您可以使用 DbSet.Attach 方法来阻止附加实体的插入,而新的导航 属性 项目,您需要使用 DbSet.Add 或执行没什么。

此外,您可以在 Startup.MobileApp.cs 文件的 ConfigureMobileApp 方法中添加以下代码,以将错误详细信息和 return 添加到您的客户端。

config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

更新:

默认情况下,将插入引用的实体(LocationAccountPrimaryCategory),如果存在任何实体,那么您将收到如下 409:

添加 _context.Accounts.Attach(item.LocationAccount); 后,您可以创建与现有引用实体(LocationAccountPrimaryCategory)有关系的 Location 实体,如果引用的实体 ( LocationAccount,PrimaryCategory) 不存在,您将收到以下错误:

对于您的场景,您 post 现有引用实体(LocationAccountPrimaryCategory)作为位置。即使可以成功创建位置项,根据您的实体模型,您可能会遇到如下 500 错误:

您可以将 Account 实体模型中的 Locations 属性 标记为 JsonIgnore。或者您需要修改实体模型以在处理序列化时忽略引用循环。

此外,您可以利用以下代码片段代替 CreatedAtRoute

return Json(current, new JsonSerializerSettings()
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

我也试过在 Startup.MobileApp.cs 下设置 SerializerSettings 的全局设置如下,但它没有按预期工作。

config.Formatters.JsonFormatter.SerializerSettings.Re‌​ferenceLoopHandling = ReferenceLoopHandling.Ignore;

此外,您可以按照 Loop Reference handling in Web API 了解更详细的方法。