使用TableController和AzureMobileApps发布新实体时出现错误500

时间:2018-02-20 18:08:55

标签: azure asp.net-web-api2 azure-mobile-services

我在AzureMobileApps上使用TableController时遇到问题。我使用脚手架在visual studio中创建了一个新的Azure Mobile App TableController。在帖子中,我修改了生成的代码,在dbContext上添加了一个attach,以避免在子表上插入期间创建引用的项。这是结果代码:

 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方法时,我都会在&#34; CreatedAtRoute&#34;上获得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; }

    ........
}   

谢谢大家。

1 个答案:

答案 0 :(得分:0)

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

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

enter image description here

根据我的理解,您需要检查Location的导航属性是否存在。对于现有的导航属性项,您可以使用DbSet.Attach方法停止附加的实体插入,而在新的导航属性项中,您需要使用DbSet.Add或不执行任何操作。

此外,您可以在ConfigureMobileApp文件的Startup.MobileApp.cs方法中添加以下代码,以包含错误详情并返回到您的客户端。

config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

<强>更新

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

enter image description here

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

enter image description here

对于您的方案,您发布现有的引用实体(PrimaryCategoryLocationAccount)以获取位置。即使可以根据您的实体模型成功创建位置项,您也可能会遇到500错误,如下所示:

enter image description here

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

此外,您可以利用以下代码段而不是JsonIgnore

CreatedAtRoute

我还尝试在return Json(current, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); 下设置SerializerSettings的全局设置,如下所示,但它没有按预期工作。

Startup.MobileApp.cs

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