繁体   English   中英

尝试将ICollection添加到ASP.NET中的ViewModel

[英]Trying to add a ICollection to a ViewModel in ASP.NET

我看了这篇文章 ,那里的小伙子似乎想做我要达到的目标。 我继承了此应用程序,尽管我是.NET开发人员,但与我喜欢的其他语言的其他MVC框架相比,MVC的东西似乎很神奇。 我的主要代码如下:

public class PurchaseOrderViewModel
{
    public PurchaseOrderViewModel()
    {
        this.PurchaseOrder = new PurchaseOrder();
    }
    // Some other fields here....
    public PurchaseOrder PurchaseOrder { get; set; }

    public IList<PurchaseOrderItem> OrderItems { get; set; }
 }

控制器:

    [HttpPost]
    public ActionResult Details(PurchaseOrderViewModel viewModel)
    {
       // bunch of stuff. the viewModels.OrderItems here is null. 
    }

模型中的OrderItems是一个ICollection <>,出于迭代的性质,我正在将其转换为IList。 该视图的相关部分如下:

 @model PurchaseOrderViewModel
 @for (var i = 0; i < this.Model.OrderItems.Count; i++)
 {                
    @Html.EditorFor(m => m.OrderItems[i].Quantity);
 }

那我为什么不让OrderItems通过呢? 这与它们是IList而不是ICollection有关吗? 如果是这样,解决方法是什么?

编辑:我更改了视图代码,因为我在尝试之前留下了一些东西。

编辑2:我考虑了当前的评论/答案,所以现在我做了以下更改:

视图模型:

    public ICollection<PurchaseOrderItem> PurchaseOrderItems { get; set; }

PurchaseOrderItem.cshtml :(为了防万一,我实际上已经保留了它的位置):

@model Downland.Model.PurchaseOrderItem

<tr style="background-color: #fff; padding: 8px;">
<td style="text-align: left; width: 210px;">
    @if (this.Model.ProductID == null)
    {
        <img class="viewproduct" src="~/Images/GetThumbnail/-1" alt="Product Image" style="padding: 8px;" />
    }
    else
    {
        <img class="viewproduct" src="~/Images/GetProductImage?productId=@(this.Model.ProductID)" alt="Product Image" style="padding: 8px;" />
    }
</td>
<td>
    @(string.IsNullOrEmpty(this.Model.SKU) ? this.Model.NonDownlandSKU : this.Model.SKU)
</td>
<td>@this.Model.ProductName</td>
<td>
    @this.Model.Quantity
    @Html.EditorFor(m => m.Quantity)
</td>
<td>
    @string.Format("{0:C}", this.Model.PriceExVAT)
    @Html.EditorFor(m => m.PriceExVAT)
</td>
<td>@string.Format("{0:C}", this.Model.VATTotal)</td>
<td>
    @string.Format("{0:C}", this.Model.ItemTotal)
</td>
</tr>

查看代码:

@Html.EditorFor(m => m.PurchaseOrderItems);

只是另一个有趣的观点。 在GET上,根据数据库数据在视图模型中设置PurchaseOrder,然后设置PurchaseOrderItems。 在“发布”上,似乎我们再次使用来自数据库的数据在视图模型中设置了purchaseOrder。 根据传递到帖子的内容,在视图模型中还可以正确设置其他一些字段,但是PurchaseOrderItems仍然为null。

您不应该在视图中进行此转换,因为以下表达式太复杂了,标准编辑器模板不支持以下表达式:

m => m.PurchaseOrder.PurchaseOrderItems.ToList()[i].Quantity

因此,您显然应该使用一个真实的视图模型,在该模型中,您不仅要将EF对象作为属性填充,并用ViewModel后缀(这就是PurchaseOrderViewModel样子)进行命名。 因此,一旦有了真实的视图模型,就可以轻松访问相应的属性,因为它将是IList<T>类型:

@Html.EditorFor(m => m.PurchaseOrder.PurchaseOrderItems[i].Quantity);

话虽这么说,但是如果您出于某种原因继承了一些旧的废话,那么仍然有解决方法。 您可以使用编辑器模板。

因此,您首先需要在~/Shared/EditorTemplates/PurchaseOrderItem.cshtml添加以下模板:

@model PurchaseOrderItem
@Html.EditorFor(x => x.Quantity)

该模板的名称非常重要,因为所有模板均按惯例工作。 应该将其命名为您拥有的ICollection<>的类型,该类型位于~/Shared/EditorTemplates

然后像这样简单地调整您的视图:

@Html.EditorFor(m => m.PurchaseOrder.PurchaseOrderItems);

在这种情况下, EditorFor帮助程序将推断PurchaseOrderItemsICollection<T> ,它将自动循环浏览此集合的元素并呈现您可以自定义的对应~/Shared/EditorTemplates/T.cshtml模板。


更新:

看来我需要发布一个简单的示例来说明如何使用编辑器模板。

与往常一样,让我们​​从视图模型开始:

public class PurchaseOrderViewModel
{
    public ICollection<PurchaseOrderItem> PurchaseOrderItems { get; set; }
}

public class PurchaseOrderItem
{
    public int Quantity { get; set; }
}

然后是一个控制器,执行以下2个操作(一个用于显示表单,一个用于处理从该表单提交的数据):

public ActionResult Index()
{
    var model = new PurchaseOrderViewModel();
    // This information will probably come from querying some data store. 
    // That could be a SQL database for example. But for the purpose
    // of this sample we are just hardcoding some values to illustrate 
    // the concept without any dependencies
    model.PurchaseOrderItems = new[]
    {
        new PurchaseOrderItem
        {
            Quantity = 5,
        }
    };
    return View(model);
}

[HttpPost]
public ActionResult Index(PurchaseOrderViewModel model)
{
    // ... everything gets bound correctly here
}

然后是强类型视图:

@model PurchaseOrderViewModel
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.PurchaseOrderItems)
    <input type="submit" value="OK" />
}

最后是相应的编辑器模板( ~/Shared/EditorTemapltes/PurchaseOrderItem.cshtml ):

@model PurchaseOrderItem
@Html.EditorFor(x => x.Quantity)

暂无
暂无

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

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