在POST操作更改视图模型属性 [英] Changing ViewModel properties in POST action

查看:216
本文介绍了在POST操作更改视图模型属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的POST操作:

  [HttpPost]
公众的ActionResult GetReport(GetReportModel模型)
{
    如果(!ModelState.IsValid)
    {
        返回查看(模型);
    }    返回视图(GetReport,新GetReportModel()
       {
          标识符=测试,
          权限=真
       });
}

当我发布我的形式,并执行这个动作有在造成视图没有变化。我的意思是,文本框标识符没有我在动作设置测试字符串值。但是,如果我清除的ModelState ,查看将显示新值:

  [HttpPost]
公众的ActionResult GetReport(GetReportModel模型)
{
    如果(!ModelState.IsValid)
    {
        返回查看();
    }    ModelState.Remove(名称);
    ModelState.Remove(许可);    返回视图(GetReport,新GetReportModel()
       {
          标识符=测试,
          权限=真
       });
}

我不明白,为什么出现这种情况?而为什么每个人都回到自己的模式,以查看它是否有一个无效的模型状态?例如,微软默认的项目模板有这个code:

 公众的ActionResult登录(LoginModel型号,串RETURNURL)
{
    如果(ModelState.IsValid)
    {
        返回RedirectToLocal(RETURNURL);
    }
    //为什么他们传递的模型对象视图
    //如果它会在那里反正从POST数据?
    返回查看(模型);
}


解决方案

要先回答你的第二个问题:模型对象不会在那里,如果你不把它传递给查看()。在视图模型属性为。这意味着在你看来如此简单的东西:

  @ Model.Identifier

...将失败,的NullReferenceException 。这就是为什么我们通过模型回视图。该ModelState中无效并不重要(它将被提供给视图,即使你没有传递模型) - 事实上,我们的希望的是无效状态,因为它是什么可以让我们为用户提供有用的错误消息。

但实际上有一个在你的第一个问题,这几年MVC程序员似乎认识到,因为它是最常见的情况是透明的一个很好的点:

原因如的HtmlHelper -created输入字段和验证的仍将的工作时调用查看()无从POST方法模式是这样的:如果他们可以逃脱它的helper方法根本不使用模型的属性。他们会试图找到例如值<输入> S IN顺序是:


  • 的ModelState [标识符。值

  • 的ViewData (仅在某些情况下)

  • 模型的价值。

第一个不为空胜。

在换句话说,助手将只看到你的模型的标识符财产,如果的ModelState [标识符] 为空(或其为空)。

这也意味着,你的模型更改属性,你在第一个例子做会的的改变呈现字段的内容。如果用户输入不是,请不要测试,即使你发回一个模型测试,在输入字段的文本仍将是不,请不要试。

所以,是的,如果你需要的响应张贴您的输入设置新值,你需要从的ModelState 删除其状态。还是不要使用HTML佣工。

I have this POST action:

[HttpPost]
public ActionResult GetReport(GetReportModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    return View("GetReport", new GetReportModel()
       { 
          Identifier = "test", 
          Permission = true 
       });
}

When I POST my form, and this action is executed there are no changes in the resulting View. I mean, the TextBox for Identifier doesn't have the "test" string value I set in the action. But if I clear ModelState, the View will show the new value:

[HttpPost]
public ActionResult GetReport(GetReportModel model)
{
    if (!ModelState.IsValid)
    {
        return View();
    }

    ModelState.Remove("Identifier");
    ModelState.Remove("Permission");

    return View("GetReport", new GetReportModel() 
       {
          Identifier = "test", 
          Permission = true 
       });
}

I don't understand why this happens? And why does everyone return their model to the View if it has an invalid model state? For example, the default project template from Microsoft has this code:

public ActionResult Login(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        return RedirectToLocal(returnUrl);
    }
    // Why do they pass the model object to the view
    // if it will be there anyway from post data?
    return View(model);
}

解决方案

To answer your second question first: The model object won't be there if you don't pass it to View(). The Model property of the view will be null. Which means something as simple as this in your view:

@Model.Identifier

... will fail with a NullReferenceException. Which is one reason why we pass the model back into the view. That the ModelState is invalid doesn't matter (and it will be given to the view even if you don't pass a model) - actually, we want that invalid state, because it's what allows us to give the user helpful error messages.

But there's actually a good point in your first question, which few MVC programmers seem to realize, because it's transparent in the most common use case:

The reason e.g. HtmlHelper-created input fields and validation will still work when calling View() without the model from your POST method is this: If they can get away with it, the helper methods don't use the model's properties at all. They'll try to find the value for e.g. <input>s in this order:

  • ModelState["Identifier"].Value
  • ViewData (only in certain cases)
  • the model's value.

The first one that isn't null wins.

In other words, the helper will only look at your model's Identifier property if ModelState["Identifier"] is null (or its Value is null).

That also means that changing the properties on your model as you do in the first example will not change the rendered field's contents. If the user entered "no, please don't test", even if you send back a model with "test", the text in the input field will still be "no, please don't test".

So yes, if you need to set new values for your inputs as response to POST, you'll need to remove their state from the ModelState. Or not use the HTML helpers.

这篇关于在POST操作更改视图模型属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆