ASP.net:如何使用外键处理无效模型

时间:2016-11-08 08:11:26

标签: c# asp.net validation

我有一个带外键的模型:

public class Route : IDbEntity
{
    [Key]
    public int Id { get; set; }

    [Display(Name = "Flight number")]
    [Required(ErrorMessage = "Flight number is required")]
    public string FlightNumber { get; set; }

    [Display(Name = "Aircraft")]
    [Required(ErrorMessage = "Aircraft is required")]
    public int? AircraftId { get; set; }

    [ForeignKey("AircraftId")]
    public virtual Aircraft Aircraft { get; set; }
}

在调用Show视图或Edit视图时,我使用它来检索对象:

public new async Task<Route> Get(int id)
{
    return await Context
        .Set<Route>()
        .Where(e => e.Id == id)
        .Include(e => e.Aircraft)
        .FirstOrDefaultAsync();
}

效果很好。

但如果Edit方法收到无效模型,我会尝试将模型返回View

[HttpPost]
public async Task<IActionResult> Edit(TEntity e)
{
    if (!ModelState.IsValid) return View(e);

    var isSuccessfull = await service.Update(e);

    if (!isSuccessfull) return StatusCode(500);

    return RedirectToAction("Index");
}

Edit方法接收模型,但对外键的引用为空。

此方法返回要查看的模型,但对外键对象的引用为null,视图无法呈现此对象。

那么,为什么Edit方法接收带有空引用的模型?以及如何使用正确的引用返回非有效模型?

1 个答案:

答案 0 :(得分:1)

在回发时,ViewModel将只包含您在HTML中呈现<input>的属性。

有两种可能性来解决这个问题:

  • 发布渲染视图所需的所有属性。然后,ViewModel将始终包含这些值,并且在错误情况下也可以使用它们。
  • 从数据库重新加载数据,并在错误情况下将其与发布的模型合并。

我更喜欢第一种方法。让我们假设您需要渲染视图的飞机的ID和名称,但在此视图中它们不可编辑。然后在Edit.cshtml中,渲染一个隐藏字段以往返这些属性:

@Html.HiddenFor(m => m.Aircraft.Id)
@Html.HiddenFor(m => m.Aircraft.Name) // property of related object

PS:因为您使用实体模型渲染视图,所以如果您选择第一种方法,飞机也会更新。您可以通过使用ViewModel进行渲染来防止这种情况,并且只在POST Edit操作中将实际可编辑的属性映射到实体。