Asp.net mvc 复合ViewModel和UpdateModel
在事后行动中,在未受欢迎的价值观中,缺少了什么 控制器Asp.net mvc 复合ViewModel和UpdateModel,asp.net-mvc,asp.net-mvc-3,Asp.net Mvc,Asp.net Mvc 3,在事后行动中,在未受欢迎的价值观中,缺少了什么 控制器 public ActionResult Index() { var productPageViewModel = new ProductPageViewModel(); productPageViewModel.ProductPageCriteria = BuildProductPageCriteriaViewModel(); productPageViewModel.Products = GetProducts(
public ActionResult Index()
{
var productPageViewModel = new ProductPageViewModel();
productPageViewModel.ProductPageCriteria = BuildProductPageCriteriaViewModel();
productPageViewModel.Products = GetProducts(productPageViewModel.ProductPageCriteria);
return View(productPageViewModel);
}
[HttpPost]
public ActionResult Index(ProductPageViewModel productPageViewModel, FormCollection formCollection)
{
// productPageViewModel is not populated with posted values of ProductPageCriteria.CategoryID, ProductPageCriteria.DepartmentID and ProductPageCriteria.PageSize
// formCollection has correct values
// Calling UpdateModel(productPageViewModel); has no affect - makes sense, the framework has already called it
// Calling UpdateModel(productPageViewModel.ProductPageCriteria); populates the values.
// The renderd form has names like CategoryID, DepartmentID unlike ProductPageCriteria.CategoryID, ProductPageCriteria.DepartmentID
// if the top model was passed to all partial views also.
return View(productPageViewModel);
}
模型
public class ProductPageCriteriaViewModel
{
public const int DefaultPageSize = 15;
public ProductPageCriteriaViewModel()
{
Categories = new List<Category>();
Departments = new List<Department>();
PageSize = DefaultPageSize;
}
[Display(Name = "Category")]
public int? CategoryID { get; set; }
[Display(Name = "Department")]
public int DepartmentID { get; set; }
[Display(Name = "Page Size")]
public int? PageSize { get; set; }
public List<Category> Categories { get; set; }
public List<Department> Departments { get; set; }
}
public class ProductPageViewModel
{
public ProductPageViewModel()
{
ProductPageCriteria = new ProductPageCriteriaViewModel();
Products = new List<Product>();
}
public ProductPageCriteriaViewModel ProductPageCriteria { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public Category Category { get; set; }
public Department Department { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
}
public class Department
{
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
}
部分视图\u ProductCriteria.cshtml
@model Mvc3Application4.Models.ProductPageCriteriaViewModel
<fieldset>
<legend>Criteria</legend>
<div class="editor-label">
@Html.LabelFor(model => model.CategoryID)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.CategoryID, new SelectList(Model.Categories, "CategoryID", "CategoryName", Model.CategoryID), "--- All ---")
@Html.ValidationMessageFor(model => model.CategoryID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DepartmentID)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.DepartmentID, new SelectList(Model.Departments, "DepartmentID", "DepartmentName", Model.DepartmentID), "--- All ---")
@Html.ValidationMessageFor(model => model.DepartmentID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.PageSize)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.PageSize, new SelectList(new List<int> {10, 15, 20, 25, 50, 100}.Select(n => new {Value = n, Text = n}), "Value", "Text", Model.PageSize), "--- All ---")
@Html.ValidationMessageFor(model => model.PageSize)
</div>
<p>
<input type="submit" value="Search" />
</p>
</fieldset>
部分视图\u ProductList.cshtml
@model IEnumerable<Mvc3Application4.Models.Product>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th></th>
<th>
ProductName
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ProductID }) |
@Html.ActionLink("Details", "Details", new { id=item.ProductID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ProductID })
</td>
<td>
@item.ProductName
</td>
</tr>
}
</table>
这是我的想法,未经测试,但我相信如果您将父模型ProductPageViewModel传递给products criteria部分视图,将部分视图更改为继承此模型,并将控件更改为使用model=>model.ProductPageCriteria.CategoryID而不是model=>model.CategoryID,它应该维护命名,以便UpdateModel可以将字段与发布的值相匹配
对不起,这句话太过分了,如果这句话不正确,我相信我会很快赢得我的同龄人压力徽章希望这能有所帮助。如果我添加对UpdateModelproductPageViewModel.ProductPageCriteria的调用;子模型ProductPageCriteria已更新。表单输入在名称中没有任何装饰,因此它可以理解为什么它以这种方式工作。这条路对吗?还有其他方法吗?你能告诉我为什么把FormCollection作为第二个参数吗?对于这个问题,可以忽略它。它的存在与否没有任何区别。我添加它是为了验证在fiddler中验证的所有提交值是否确实显示在该方法中。是的,这很好。事实上,我之前就是这样做的。为了进行重构,我希望视图依赖于较小的模型,即只使用它们需要的东西。例如,在本例中,_ProductCriteria.cshtml只需要ProductPageCriteriaViewModel。我可以让它也工作,只是我必须为每个子模型调用UpdateModel。我想知道这是否是正确的方法,其他人也是这样处理的。我不是MVC最佳实践方面的专家,但我相信主视图会在数据从控制器传入之前将部分视图呈现到页面中。由于主视图继承父视图,因此传递子视图模型与传递父视图模型相同,只是为其生成了名称。在这一点上我可能完全错了,但这就是我对过程的看法。不过,我很想听听其他人的反应。
@model IEnumerable<Mvc3Application4.Models.Product>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th></th>
<th>
ProductName
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ProductID }) |
@Html.ActionLink("Details", "Details", new { id=item.ProductID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ProductID })
</td>
<td>
@item.ProductName
</td>
</tr>
}
</table>