简体   繁体   English

MVC Razor编辑器用于列表中的最后一个对象

[英]MVC Razor EditorFor Last Object in List

I'm trying to display EditorFor for the last child Object in an collection. 我正在尝试为集合中的最后一个子对象显示EditorFor。 Below are the POCOs for the Order (Parent) and Hold (child collection): 以下是订单(父母)和保留(子代)的POCO:

public class Order
{
    public int ID {get;set;}
    public string Name {get;set;}
    ....
    public virtual List<Hold> Holds { get; set; }
}

public class Hold
{
    public int ID { get; set; }
    public int OrderID { get; set; }
    public virtual Order Order { get; set; }
    public DateTime? When { get; set; }
    public string Reason { get; set; }
}

Here's my attempt at creating an Order view that shows an Order and the last Hold if there is one present. 这是我尝试创建一个Order视图,该视图显示一个Order和一个存在的最后一个Hold。 I've commented out the last Hold attempt that doesn't work. 我已注释掉最后一次无效的尝试。

@model Order

@using (Html.BeginForm("Update", "Order", FormMethod.Post, new {}))
{
   <div class="form-group row">
      @Html.LabelFor(x => x.Name, new { @class = "col-xs-2" })
      <div class="col-xs-10">
         @Html.EditorFor(x => x.Name, new { @class = "form-control"})
      </div>
   </div>

   <div class="form-group row">
      <label class="col-xs-2">When</label>
      <div class="col-xs-10">
         @*@Html.EditorFor(x => x.Holds.Last().When, new {})*@
      </div>
   </div>
}

The Holds collection can also be null so doing Last() in that case will case an null exception even if that did work. Holds集合也可以为null,因此在这种情况下执行Last()会产生null异常,即使这样做确实可行。

This seems like something simple and I have this pattern in a couple places in my database. 这似乎很简单,我在数据库中的几个地方都有这种模式。 Can anyone recommend a good way to handle this situation? 谁能推荐一种处理这种情况的好方法?

Thanks! 谢谢!

You should use a view model for this because you wont get a very good response in your HttpPost action when you post this back 您应该为此使用视图模型,因为当您将其发布回去时,您在HttpPost操作中不会得到很好的响应

public class OrderViewModel
{
    public OrderViewModel()
    {
        Order = new Order();
        Hold = new Hold();
    }
    public Order Order { get; set; }
    public Hold Hold { get; set; }
}

public ActionResult Edit(int id)
{

    var o = from o context.Order.Include("Holds").Single(id);
    var model = new OrderViewModel()
    {
        Order = o
    }
    if (o.Holds.Count() > 0)
        model.Hold = o.Holds.Last();
    return View(model);
}

then just use EditorFors 然后只需使用EditorFors

@model OrderViewModel

@using (Html.BeginForm("Update", "Order", FormMethod.Post, new {}))
{
   <div class="form-group row">
      @Html.LabelFor(x => x.Order.Name, new { @class = "col-xs-2" })
      <div class="col-xs-10">
         @Html.EditorFor(x => x.Order.Name, new { @class = "form-control"})
      </div>
   </div>

   <div class="form-group row">
      <label class="col-xs-2>When</label>
      <div class="col-xs-10">
         @Html.EditorFor(x => x.Hold.When)
      </div>
   </div>
}

First, instead of using Last() you should use LastOrDefault() and then do proper null-checking. 首先,应该使用LastOrDefault()而不是使用Last() LastOrDefault() ,然后进行适当的空检查。 Last() raises an exception is nothing is found, while LastOrDefault simply returns null in that case. Last()引发一个异常,即找不到任何东西,而在这种情况下LastOrDefault只是返回null。

Second, using Last() or LastOrDefault() will not generate the proper input names via EditorFor , so once you post, the modelbinder won't know what to do with the value. 其次,使用Last()LastOrDefault()不会通过EditorFor生成正确的输入名称,因此一旦发布,modelbinder将不知道如何处理该值。 Instead, you need to use indexing: 相反,您需要使用索引:

@if (Model.Holds.Any())
{
    var lastIndex = Model.Holds.Count() - 1;

    <div class="form-group row">
        <label class="col-xs-2">When</label>
        <div class="col-xs-10">
            @Html.EditorFor(x => x.Holds[lastIndex].When, new {})
        </div>
    </div>
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM