我有一个名为ProductController的Controller。 Controller代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Services.Abstract;
using Web.Models;
using Ninject;
using Services.Entities;
namespace Web.Controllers
{
public class ProductController : Controller
{
IProductRepository productRepository;
public ProductController(IProductRepository products)
{
productRepository = products;
}
[HttpGet]
public ActionResult Create() {
Product p = new Product {
Id = 5
};
string theTitle = "The Title";
var viewModel = new ProductViewModel {
Product = p,
TheTitle = theTitle
};
return View(viewModel);
}
[HttpPost]
public ActionResult Create(ProductViewModel pvm) {
if (ModelState.IsValid) {
int result = productRepository.SaveProduct(pvm.Product);
return Content(result.ToString());
}
else {
return View(pvm);
}
}
}
}
我正在使用ViewModel模式向View发送各种信息。例如,我发送的产品默认Id设置为5,我也设置了title属性[Aside:这不是生产代码 - 只是测试数据: - )]
到目前为止一切顺利。第一次调用/ Product / Create时,我的Title属性显示在视图上,Product Id默认为5.但是,当我发布表单时,只保留Product信息。如果ModelState不是有效的,我再次向用户显示View。但是,这一次,Title不会显示(它被设置为null)。该产品确实按预期显示。
如果可能,我想在ModelState无效时将原始标题发送回视图。有没有办法在不使用Session,ViewData和TempData的情况下执行此操作?
问候,并提前感谢
答案 0 :(得分:1)
如果我理解正确,简短的回答是“不”。
如果ProductViewModel.TheTitle属性不是发布到Create POST方法的表单数据的一部分,则必须以某种方式重新创建 。您可以通过可能的方式在多个请求中保留此值,但我会问是否真的有必要最终去那里。
在我看来,如果你在Create GET方法中检索Title属性的方式对于那些请求来说已经足够了,那么在POST请求中以相同的方式重新创建它也同样足够好。 POST通常会花费更多的资源和时间来处理(验证,保存数据等),因此您可能会面临额外的依赖性和漏洞,从而可能进行简单的优化。也就是说,我确信有很多场景可以证明你的方法是合理的。
在您的示例中,由于Title属性不用于保存产品并且可以有效地忽略,如果您仍希望在不重新创建它的情况下将其保留在这些页面中,最简单的方法可能是将其包含在隐藏中表单字段,因此除了产品之外,您的模型绑定器还会选择它。请注意,如果最终用户操纵了表单有效负载,则可以更改此值。