我正在努力更好地了解和了解MCV4。
什么是将我的Product对象的PropertyType属性传递回HttpPost上的控制器的最佳方法。
我正在寻找一种方法,所以我不必手工写出每一处房产。 我目前正在使用反射来迭代Category类型的属性,并使用@ Html.Hidden方法将它们添加为隐藏的输入变量。 这有效,但我想知道我是否采用正确的方法(最佳实践)。
我的复杂类型如下。
public class Product
{
[Key]
public int Id { get; set; }
[Required]
public string ProductName { get; set; }
public Category CategoryType { get; set; }
}
public class Category
{
[Key]
public int Id { get; set; }
[Required]
public string CategoryName { get; set; }
}
使用控制器如下
public class ProductController : Controller
{
//
// GET: /Product/
public ActionResult Index()
{
return View();
}
public ActionResult Add()
{
//Add a new product to the cheese category.
var product = new Product();
var category = new Category { Id = 1, CategoryName = "Cheese" };
product.CategoryType = category;
return View(product);
}
[HttpPost]
public ActionResult Add(Product product)
{
if (ModelState.IsValid)
{
//Add to repository code goes here
//Redirect to Index Page
return RedirectToAction("Index");
}
return View(product);
}
}
使用
的添加视图 @model BootstrapPrototype.Models.Product
@{
ViewBag.Title = "Add";
}
<h2>Add</h2>
@using (Html.BeginForm())
{
@Html.DisplayFor(m => m.ProductName);
@Html.EditorFor(m => m.ProductName);
foreach(var property in Model.CategoryType.GetType().GetProperties())
{
//I know how to use the Hidden but would also know how to use the HiddenFor with reflections.
@Html.Hidden("CategoryType." + property.Name, property.GetValue(Model.CategoryType));
}
<button type="submit">Add</button>
}
感谢。
答案 0 :(得分:4)
我认为您将类别字段放在隐藏字段中的原因是因为您不希望用户更新它们,而且还需要将这些值作为Product
对象的一部分返回,否则您的产品对象将在没有类别(null
值)的情况下保存。这正是ViewModel
非常重要的原因。您创建一个viewmodel,它接受您只需要的那些值的输入。因此,如果您需要创建一个只需要名称和预选不可编辑类别的产品,那么您可以拥有一个视图模型:
public class ProductModel {
public int Id {get;set;}
public strnig Name{get;set;}
public int CategoryId {get;set;}
}
和视图
@model ProductModel
@Html.HiddenFor(m=>m.Id)
@Html.HiddenFor(m=>m.CategoryId)
@Html.TextboxFor(m=>m.Name)
你可以从控制器方法获得
public ActionResult Add() {
var product = new ProductModel {
CategoryId = getIdFromDb("cheese");
};
return View();
}
您可以在控制器方法中接收
[HttpPost]
public ActionResult Add(ProductMOdel input) {
// map input to an entity
var productENtity = mapModelToEntity(input);
// save entity to your repo
}
如果您的Product
和Category
类中有一百个字段,则可以放大此方法的这一优势。并且您有一个用例,其中只有部分字段将被编辑。
但当然你仍然可以按照自己的方式去做。但是,不是做反射,而是提供开销,而应该摆脱它并做脚手架。以这种方式,您不必手动编写类的所有字段。以下是两个很好的链接,可以帮助您开始使用脚手架:
但如果你坚持使用反射那么它完全有可能(你的代码中几乎有它)
@foreach(var property in Model.CategoryType.GetType().GetProperties())
{
@Html.Hidden("Product." + property.Name,
property.GetValue(Model.CategoryType));
}
该代码的关键是"Product."
,允许模型绑定器完成它的工作 - 隐藏字段中的值将传递回POST控制器方法。但是,如果CategoryType
为null,则该代码将不起作用。
答案 1 :(得分:0)
我相信MVC4有HiddenInputAttribute。您可以将它与Html.EditorFor。
结合使用