2016-11-08 76 views
0

我有外键的模型非有效模式:ASP.net:如何处理与外键

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方法接收模式,但与外键空引用。

并且此方法返回模型以查看,但对外键对象的引用为空,并且视图无法使该对象正确显示。

那么,为什么编辑方法接收空引用模型?以及如何使用正确的引用返回无效的模型以查看?

回答

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操作中的实体。

+0

您如何看待$ .get()查询并将数据检索到页面元素中而不在模型内设置任何值?每次编辑页面加载时,我都会发送GET请求,并且效果很好。数据 - 是主键。我认为这看起来很棒。但你对此有何看法? – Evgeniy175

+1

如果我正确理解您的方法,这与第二种可能性类似:将发布的数据与来自数据库的新数据合并。你只需通过AJAX而不是在控制器中完成。只要确保您在发布错误的情况下保留发布的数据(即可编辑属性的新值),或者用户放弃了他刚才的输入。 –

+0

我将FK实体的Id从模型发送到控制器的某些动作并处理返回的数据:\t $ .get('@ Url.Action(“GetAircraft”,“Aircrafts”)',{id:“@ Model.AircraftId”} ,功能(数据,参数){ \t \t $('#airId').select2({data:JSON.parse(data)}); \t}); – Evgeniy175