发布ViewModel返回null属性

时间:2013-07-12 05:20:21

标签: asp.net-mvc-3 razor

我遇到的问题是视图模型在帖子后不断返回null属性。下面是我的代码(它可能是一个语法问题或两个调用类和我在其他帖子中看到的同名的类或属性,但我在代码中看不到任何此类问题):

查看模特:

public class ProductItem
    {
        public int ProductID { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string LongDescription { get; set; }
        public int SupplierID { get; set; }
        public string Dimensions { get; set; }
        public double Price { get; set; }
        public bool On_Sale { get; set; }
        public double DiscountedPrice { get; set; }
        public string Thumbnail { get; set; }
        public string LargeImage { get; set; }
        public string LargeImage2 { get; set; }
        public string LargeImage3 { get; set; }
        public string CrossRef { get; set; }
        public byte Available { get; set; }
        public double Weight { get; set; }
        public byte Important { get; set; }
        public virtual ICollection<ProductCategory> ProductCategories { get; set; }

        // this is required on the page to allow products to be marked for deletion
        public bool IsForDelete { get; set; }
    }

    public class ProductListViewModel
    {
        public IEnumerable<ProductItem> ProductItems { get; set; }
        public IEnumerable<Category> CategoryItems { get; set; }
    }

控制器:

public ActionResult ProductList()
        {
            var productList = new ProductListViewModel();
            productList.ProductItems = productRepository.GetProductsWithDeleteOption().ToList();
            productList.CategoryItems = categoryRepository.GetCategories().ToList();
            return View(productList);
        }

        [HttpPost]
        public ActionResult ProductList(ProductListViewModel productViewModel, FormCollection formCollection, string submit)
        {            
            if (ModelState.IsValid)
            {
                // Check for submit action
                if (submit == "Change Sort")
                {
                    if (formCollection["Sortby"] == "ProductID")
                    {
                        OrderBy(productViewModel, formCollection, "m.ProductID");
                    }
                    else if (formCollection["Sortby"] == "Code")
                    {
                        OrderBy(productViewModel, formCollection, "m.Code");
                    }
                    else if (formCollection["Sortby"] == "Name")
                    {
                        OrderBy(productViewModel, formCollection, "m.Name");
                    }
                    else if (formCollection["Sortby"] == "Price")
                    {
                        OrderBy(productViewModel, formCollection, "m.Price");
                    }
                }
                else if (submit == "Delete all selected")
                {

                }
                else if (submit == "Update All")
                {

                }
                else if (submit == "Restrict Display")
                {

                }
            }
            return View(productViewModel);
        }

查看:

@model Admin.Models.ViewModels.ProductListViewModel

@{
    ViewBag.Title = "View Products";
}

@using (Html.BeginForm())
{
<h2>Product List as at @DateTime.Now.ToString("dd/MM/yyyy")</h2>
<table>
    <tr>
        <td>Sort by:</td>
        <td>
            <select name="Sortby">
                <option value="ProductID">ProductID</option>
                <option value="Code">Code</option>
                <option value="Name">Name</option>
                <option value="Price">Price</option>
            </select>
        </td>
        <td>
            <input type="radio" name="sortDirection" checked="checked" value="Asc" /> Ascending
            <input type="radio" name="sortDirection" value="Desc" /> Descending
        </td>
        <td>
            <input type="submit" name="submit" value="Change Sort" />
        </td>
    </tr>
    <tr>
        <td>Display only : (category)</td>
        <td>@Html.DropDownList("CategoryID", new SelectList(Model.CategoryItems, "CategoryID", "Name"), "All Categories")</td>
        <td colspan="2"><input type="submit" name="submit" value="Restrict Display" /></td>
    </tr>
    <tr>
        <td colspan="4"><br />Total Number of products: @Model.ProductItems.Count()</td>
    </tr>
</table>
<table>
    <tr>
        <th>
            Edit
        </th>
        <th>
            Code
        </th>
        <th>
            Name
        </th>
        <th>
            Price
        </th>
        <th>
            On_Sale
        </th>
        <th>
            DiscountedPrice
        </th>
        <th>
            Weight
        </th>
        <th>
            Delete
        </th>
        <th></th>
    </tr>

@for (var i = 0; i < Model.ProductItems.ToList().Count; i++)
{
    <tr>
        <td>
            @Html.HiddenFor(m => m.ProductItems.ToList()[i].ProductID)            
            @Html.ActionLink(Model.ProductItems.ToList()[i].ProductID.ToString(), "ProductEdit", new { id = Model.ProductItems.ToList()[i].ProductID })
        </td>
        <td>
            @Html.DisplayFor(m => m.ProductItems.ToList()[i].Code)
        </td>
        <td>
            @Html.DisplayFor(m => m.ProductItems.ToList()[i].Name)
        </td>
        <td>
            @Html.EditorFor(m => m.ProductItems.ToList()[i].Price)
        </td>
        <td>
            @Html.CheckBoxFor(m => m.ProductItems.ToList()[i].On_Sale, new { id = "On_Sale_" + Model.ProductItems.ToList()[i].ProductID })
        </td>
        <td>
            @Html.EditorFor(m => m.ProductItems.ToList()[i].DiscountedPrice)
        </td>
        <td>
            @Html.EditorFor(m => m.ProductItems.ToList()[i].Weight)
        </td>
        <td>
            @Html.CheckBoxFor(m => m.ProductItems.ToList()[i].IsForDelete, new { id = Model.ProductItems.ToList()[i].ProductID }) 
        </td>
        <td>
            @Html.ActionLink("Edit", "ProductEdit", new { id = Model.ProductItems.ToList()[i].ProductID }) |
            @Html.ActionLink("Details", "Details", new { id = Model.ProductItems.ToList()[i].ProductID }) |
            @Html.ActionLink("Delete", "Delete", new { id = Model.ProductItems.ToList()[i].ProductID })
        </td>
    </tr>
}

</table>
<p>
    <input name="submit" type="submit" value="Delete all selected" />
</p>
<p>
    <input name="submit" type="submit" value="Update All" />
</p>

<p>
    @Html.ActionLink("Add a new product", "ProductAdd")
</p>

}

在post操作中,productViewModel参数将ProductItems和CategoryItems属性设置为null。

2 个答案:

答案 0 :(得分:3)

好的,所以有两个问题。

  1. 我不明白你为什么要发布CategoryItems的列表你应该只期望所选类别而不是列表

  2. ProductItems的问题是为<input>代码生成的名称。目前,生成的名称为name="[0].Price",而应该是name="ProductItems[0].Price"

  3. 我更改了以下代码

    @Html.EditorFor(m => m.ProductItems.ToList()[i].Price)
    

    @Html.EditorFor(m => m.ProductItems[i].Price)
    

    它有效。

    注意:我在IEnumerable<ProductItem> ProductItems

    中将List<ProductItem> ProductItems更改为ProductListViewModel

答案 1 :(得分:1)

是的,在回发后它将为空。我在我的一个项目中有一个类似的表格,这就是我根据自己的情况做的事情。

您可以将视图模型更改为这样,然后您不必在视图中进行如此多的转换为列表:

public class ProductListViewModel
{
     public List<ProductItem> ProductItems { get; set; }

     public List<Category> CategoryItems { get; set; }
}

现在在你看来它看起来像这样(这只是它的一部分,然后休息,你可以去添加):

@for (int i = 0; i < Model.ProductItems.Count(); i++)
{
     <tr>
          <td>
               @Html.DisplayFor(m => m.ProductItems[i].Name)
               @Html.HiddenFor(m => m.ProductItems[i].Name)
          </td>
     </tr>
     <tr>
          <td>
               @Html.CheckBoxFor(m => m.ProductItems[i].IsForDelete)
          </td>
     </tr>
}

添加代码并进行一些调试,以查看在提交

时如何返回值

我希望这会有所帮助。