我已经用MVC开发了几年,其中一个人认为我最初被教授的是一个HttpPost动作,first thing you a所做的就是检查ModelState.IsValid,所以.
[HttpPost]
public ActionResult Edit(ViewModel form) {
if(ModelState.IsValid) {
// Do post-processing here
}
}我现在谈到了一个问题,在这个问题上,我通过表单传递了一个散列ID。如果它是0,这是一个新的记录,如果它高于0,就意味着我在编辑。如果我的ModelState.IsValid返回false,我需要在返回到同一个模型的编辑视图之前再次设置一些下拉列表数据。要设置一些在失败后返回到表单中的项,我需要知道未散列的数字,但是在ModelState.IsValid中解哈希将使它在else语句中不可用。
因此,以下做法是否可以接受?
[HttpPost]
public ActionResult Edit(ViewModel form) {
int myID = 0;
if(/** unhashing is successful...**/)
{
if(ModelState.IsValid) {
// Do post-processing here
}
else
{
// Setup dropdowns using unhashed ID and return original view...
}
}
}注意,ModelState.IsValid不是HttpPost内部的第一个测试。这可以接受吗?如果没有,是否有更适当的方法来进行这种逻辑?
谢谢!
发布于 2016-06-19 12:57:40
在您的源代码中,您似乎已经写了一些关于解哈希的评论,但是这样的术语并不存在。散列函数的用途是不可逆转的。另一方面,我认为您的意思是解密查询字符串值。理想情况下,这种解密应该发生在视图模型的自定义模型绑定器中,为此参数将ModelState.IsValid值设置为false。因此,在您的控制器操作中,您只需要检查这个布尔参数。控制器操作不应解密任何查询字符串或任何参数。这应该在MVC执行管道中做得更早。自定义模型绑定器甚至自定义授权筛选器将更适合这种情况。
让我们举个例子:
public class ViewModel
{
public int Id { get; set; }
... some other stuff around
}现在您可以为该视图模型编写一个自定义模型绑定程序:
public class MyDecryptingBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
if (propertyDescriptor.Name == "Id")
{
var idParam = bindingContext.ValueProvider.GetValue("Id");
if (idParam != null)
{
string rawValue = idParam.RawValue as string;
int value;
if (this.DecryptId(rawValue, out value))
{
propertyDescriptor.SetValue(bindingContext.Model, value);
return;
}
}
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
private bool DecryptId(string raw, out int id)
{
// TODO: you know what to do here: decrypt the raw value and
// set it to the id parameter, or just return false if decryption fails
}
}现在,您可以在引导时(Application_Start)将这个自定义模型绑定器注册到视图模型:
ModelBinders.Binders.Add(typeof(ViewModel), new MyDecryptingBinder());然后,您的控制器操作将非常简单,如:
[HttpPost]
public ActionResult Index(ViewModel model)
{
if (ModelState.IsValid)
{
// The decryption of the id parameter has succeeded, you can use model.Id here
}
else
{
// Decryption failed or the id parameter was not provided: act accordingly
}
}https://stackoverflow.com/questions/37907332
复制相似问题