当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - Need to pass a List<model> to the Http Post in a Controller

问题描述:

I am passing a List to the view. In the view I need to pass back that list. It includes an editable check box, which are the items I really need. All of the other fields displayed are for read only purposes. If the user wants to designate the item as a clearance, then they check the isClearance checkbox. So when they hit the save button it hits the HttpPost Index(). However, it passes back a null. If I change it to be just a modelObject, not List, it works just fine.

Here is the controller Index:

 public ActionResult Index()

{

List<ClearanceViewModel> cc = new List<ClearanceViewModel>();

ClearanceViewModel c = new ClearanceViewModel();

c.sku = "123";

c.title = "Test1";

c.includeOnSite = true;

c.productID = 123;

c.salePrice = Convert.ToDecimal(2.99);

c.RetailPrice = Convert.ToDecimal(4.99);

c.isClearance = false;

cc.Add(c);

c.sku = "123";

c.title = "Test1";

c.includeOnSite = true;

c.productID = 123;

c.salePrice = Convert.ToDecimal(2.99);

c.RetailPrice = Convert.ToDecimal(4.99);

c.isClearance = false;

cc.Add(c);

return View(cc);

}

Here is the View:

@model List<PMS.Models.ClearanceViewModel>

@{

ViewBag.title = "Clearance List";

}

<fieldset>

<legend><span>Clearance List</span></legend>

@using (Html.BeginForm())

{

if (Model.Count() > 0)

{

<table class="list">

<tr>

<th>Sku</th>

<th>Title</th>

<th>Include On Site</th>

<th>Sale price</th>

<th>Retail Price</th>

<th>Quantity</th>

<th>Clearance</th>

</tr>

@foreach(var item in Model)

{

@Html.HiddenFor(modelItem => item.productID);

<tr>

<td>@Html.DisplayFor(modelItem => item.sku)</td>

<td>@Html.DisplayFor(modelItem => item.title)</td>

<td>@Html.DisplayFor(modelItem => item.includeOnSite)</td>

<td>@Html.DisplayFor(modelItem => item.salePrice)</td>

<td>@Html.DisplayFor(modelItem => item.RetailPrice)</td>

<td>@Html.DisplayFor(modelItem => item.quantity)</td>

<td>@Html.EditorFor(modelItem => item.isClearance)</td>

</tr>

}

</table>

<p>

<input type="submit" value="Save" />

</p>

}

}

</fieldset>

Here is the HttpPost in the Controller (clearanceModel is null when it hits the foreach loop, when it should have a list of the items):

 [HttpPost]

public ActionResult Index(List<ClearanceViewModel> clearanceModel)

{

foreach (ClearanceViewModel item in clearanceModel)

{

if (item.isClearance == true)

{

// get the product object, so we can add it to the product Promotion of clearance

var product = _unitOfWork.ProductRepository.Get(filter: p => p.productID == item.productID).FirstOrDefault();

// Make sure that it isn't already in the product promotion for clearance

var productPromotion = _unitOfWork.ProductPromotionRepository.Get(filter: pp => pp.productID == product.productID && pp.promotion.Name == "Clearance").FirstOrDefault();

//add the product promotion

if (productPromotion == null)

{

// get the clearance promotion

var promotion = _unitOfWork.PromotionRepository.Get(filter: pr => pr.Name == "Clearance").FirstOrDefault();

if (promotion != null)

{

ProductPromotion promo = new ProductPromotion();

promo.productID = product.productID;

promo.promotionID = promotion.promotionID;

promo.onDate = DateTime.Now;

promo.offDate = null;

promo.canOverwrite = true;

_unitOfWork.ProductPromotionRepository.Create(promo);

_unitOfWork.SaveChanges();

}

}

}

}

网友答案:

Model binding does not work with foreach loops. You have to use a for loop. That way the indexer [i] is used to create unique name properties for each input element in the generated html.

@for (int i = 0; i < Model.Count; i++)
        {
            @Html.HiddenFor(modelItem => modelItem[i].productID);
            <tr>    
                <td>@Html.DisplayFor(modelItem => modelItem[i].sku)</td>
                <td>@Html.DisplayFor(modelItem => modelItem[i].title)</td>
                <td>@Html.DisplayFor(modelItem => modelItem[i].includeOnSite)</td>
                <td>@Html.DisplayFor(modelItem => modelItem[i].salePrice)</td>
                <td>@Html.DisplayFor(modelItem => modelItem[i].RetailPrice)</td>
                <td>@Html.DisplayFor(modelItem => modelItem[i].quantity)</td>
                <td>@Html.EditorFor(modelItem => modelItem[i].isClearance)</td>        
            </tr>
        }

For a nice explanation of model binding collections, check out this article

网友答案:

You need a modelbinder to bind the list, or a displayTemplate.. RIght now the generated names for the list items is: item.sku, item.title etc.. The standard modelbinder cannot bind that to a list..

分享给朋友:
您可能感兴趣的文章:
随机阅读: