如何在 ASP.NET MVC 中的 POST 请求之间传输 ViewModel 数据?
我有一个像这样的 ViewModel:
public class ProductEditModel
{
public string Name { get; set; }
public int CategoryId { get; set; }
public SelectList Categories { get; set; }
public ProductEditModel()
{
var categories = Database.GetCategories(); // made-up method
Categories = new SelectList(categories, "Key", "Value");
}
}
然后我有两个使用该模型的控制器方法:
public ActionResult Create()
{
var model = new ProductEditModel();
return View(model);
}
[HttpPost]
public ActionResult Create(ProductEditModel model)
{
if (ModelState.IsValid)
{
// convert the model to the actual entity
var product = Mapper.Map(model, new Product());
Database.Save(product);
return View("Success");
}
else
{
return View(model); // this is where it fails
}
}
用户第一次进入 Create
视图时,他们会看到一个类别列表。但是,如果验证失败,视图将发送回给他们,但这次 Categories
属性为 null。这是可以理解的,因为如果 Categories
不在 POST 请求中,则 ModelBinder
不会保留它。我的问题是,保持 Categories
持久化的最佳方法是什么?我可以做这样的事情:
[HttpPost]
public ActionResult Create(ProductEditModel model)
{
if (ModelState.IsValid)
{
// convert the model to the actual entity
var product = Mapper.Map(model, new Product());
Database.Save(product);
return View("Success");
}
else
{
// manually populate Categories again if validation failed
model.Categories = new SelectList(categories, "Key", "Value");
return View(model); // this is where it fails
}
}
但这是一个丑陋的解决方案。我还能怎样坚持呢?我无法使用隐藏字段,因为它是一个集合。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我会使用存储库来获取所需的任何数据,并且不认为这是一个丑陋的解决方案:
为了进一步重构这一点,我建议您观看优秀的 吉米·博加德 (Jimmy Bogard) 的让你的控制器节食视频演示。
I would use the repository to fetch whatever data is needed and don't think it's an ugly solution:
To further refactor this I would recommend you watching the excellent Putting Your Controllers on a Diet video presentation by Jimmy Bogard.
我通常将列表(用于下拉列表)实现为只读属性。当视图获取值时,该属性会自行包含返回值所需的内容。
如有必要,您可以从包含已发布并绑定到类实例的 id 的属性中获取当前选定的项目(即验证失败)。
I typically implement my lists (for drop downs) as a readonly property. When the View gets the value the property is self contained on what it needs to return the values.
If necessary you can grab the currently selected item (i.e. validation failed) from the property containing the id that was posted and bound to the instance of your class.
就我而言,我有一个 BaseModel 类,其中我将所有这些属性列表保留为类属性。
就像下面的示例一样:
GetCountryList()
是一个向 Singleton 请求数据的函数。这种情况在应用程序生命周期中只会发生一次。另一种方法(如果这些列表非常大)是使用一个静态实用程序类,其中包含返回 SelectListItem 的查找表。
如果您需要访问不时更改的列表,那么就不要使用 Singleton 类。
In my case I have a BaseModel class where I keep all those property list as class attributes.
Like in the following sample:
GetCountryList()
is a function that ask a Singleton for data. This would only happen once in the app lifecycleAnother way for doing this, and if those lists are pretty big, would be to have a static utility class with the lookup table that returns the SelectListItem.
If you need to access a list that change from time to time then simply dont use a Singleton class.