2012-05-17 59 views
0

空我有以下ViewModel视图模型上添加[HttpPost]方法

public class CategoryViewModel 
{ 
    public Category Category { get; set; } 
    public IList<Category> Categories { get; set; } 
    public IList<Product> Products { get; set; } 

    public IEnumerable<SelectListItem> CategorySelectItems 
    { 
     get { var ret = new List<SelectListItem>(); 
     if(Categories==null) 
      return ret; 

      ret.AddRange(Categories.Where(x => (Category == null || x.Id != 
         Category.Id)).Select(category => new SelectListItem 
            { Text = category.Name, Value = 
             category.Id.ToString()})); 
      return ret; 
     } 
    } 

    public CategoryViewModel(){} 
} 

以下是控制器:

namespace mysite.com.Controllers{ 
    public class CategoryController : Controller{ 
     private IRepository<Category> _repository; 
     private IRepository<Product> _productRepo; 
     private CategoryViewModel _categoryViewModel; 

     public CategoryController(){ 
      _repository = new CategoryRepository(); 
      _productRepo = new ProductRepository(); 
     } 

     [HttpGet] 
     public ActionResult Index(){ 
      return View(new CategoryViewModel{Categories=_repository.GetAll()}); 
     } 

     [HttpGet] 
     public ActionResult Add(){ 
      return View(new CategoryViewModel{ 
      Category = new Category(), Categories= _repository.GetAll()}); 
     } 

     [HttpPost] 
     public ActionResult Add(CategoryViewModel category){ 
      if (ModelState.IsValid){ 
       _repository.Save(category.Category); 
       return RedirectToAction("Index"); 
      } 
      return View(category); 
     } 
    } 
} 

这是代码在我看来:

@model mysite.com.ViewModels.CategoryViewModel 

@using (Html.BeginForm("Add", "Category", FormMethod.Post)) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Add Category</legend> 
     @Html.HiddenFor(x => x.Category.Id) 
     <div class="editor-label"> 
      @Html.LabelFor(x => x.Category.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(x => x.Category.Name) 
      @Html.ValidationMessageFor(x => x.Category.Name) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(x => x.Category.ParentCategory) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("ParentCategory", 
        Model.CategorySelectItems,"--select parent category--") 
      @Html.ValidationMessageFor(x => x.Category.Name) 
     </div> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 
<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

但在我的控制器的[HttpPost] Add方法中category对象(类型为CategoryViewModel )是空的:(

我在做什么错?

+1

您的模型不应该有与之相关的复杂对象......在这些情况下,序列化器/反序列化器不能正常工作。你的'Category'对象应该被压平,或者让你的模型实现'ICategory'。 –

回答

1

我觉得你太迅速返回值:

if(Categories==null) 
     **return ret;** 

     ret.AddRange(Categories.Where(x => (Category == null || x.Id != 
        Category.Id)).Select(category => new SelectListItem 
           { Text = category.Name, Value = 
            category.Id.ToString()})); 
     return ret; 
    } 
1

你的模式是不deserializable。您的模型只能反序列化原始属性和原始属性的集合,没有太多帮助,而且帮助通常不值得。

你的模型应该是这个样子:

public class CategoryAddModel 
{ 
    //these values are used to populate the view, but will not deserialize 
    public IList<Category> AvailableCategories { get; set; } 

    //these values are deserializable 
    public int CategoryId {get;set;} 
    public string CategoryName {get;set;} 
    public int ParentCategory {get;set;} 
} 

public class CategoryIndexModel 
{ 
    public IList<Category> Categories { get; set; } 
} 

Add.cshtml看法会是这个样子:

@model mysite.com.ViewModels.CategoryAddModel 

@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Add Category</legend> 
     @Html.HiddenFor(x => x.CategoryId) 
     <div class="editor-label"> 
      @Html.LabelFor(x => x.CategoryName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(x => x.CategoryName) 
      @Html.ValidationMessageFor(x => x.CategoryName) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(x => x.Category.ParentCategory) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("ParentCategory", 
       new SelectList(Model.AvailableCategories, "Id", "Name"), 
       "--select parent category--") 
      @Html.ValidationMessageFor(x => x.ParentCategory) 
     </div> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 
<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

Index.cshtml视图应该像这样:

@model mysite.com.ViewModels.CategoryIndexModel 
@Html.ActionLink("Add Category", "Add") 
<ul> 
@foreach(var item in Model.Categories) 
{ 
    <li> @{ // List your categories, hyperlinks to editing pages } </li> 
} 
</ul> 

CategoryController.cs应该看起来像这样:

namespace mysite.com.Controllers{ 
    public class CategoryController : Controller 
    { 
     private IRepository<Category> _repository = new CategoryRepository(); 
     private IRepository<Product> _productRepo = new ProductRepository(); 

     public ActionResult Index() 
     { 
      var model = new CategoryIndexModel 
      { 
       Categories=_repository.GetAll() 
      }; 

      return View(model); 
     } 

     public ActionResult Add() 
     { 
      var model = new CategoryAddModel() 
      { 
       AvailableCategories = _repository.GetAll() 
      }; 
      return View(model); 
     } 

     [HttpPost] 
     public ActionResult Add(CategoryAddModel model){ 
      if (ModelState.IsValid) 
      { 
       //TODO: (varies based on your repository model) 
       //create a Category object from the model and persist it here. 

       return RedirectToAction("Index"); 
      } 
      //the complex collection does not return with the model; repopulate it here. 
      model.AvailableCategories = _repository.GetAll() 
      return View(model); 
     } 
    } 
} 

这应该让你在你正在寻找的一般领域。

相关问题