ASP.NET Core:asp- *属性使用请求有效负载而不是模型?

时间:2016-09-23 17:02:58

标签: asp.net asp.net-core asp.net-core-mvc .net-core asp.net-core-1.0

似乎在ASP.NET Core中,asp-*属性(例如asp-for)中的值取自模型之前的请求有效内容。例如:

发布此值:

MyProperty="User entered value."

采取此行动:

[HttpPost]
public IActionResult Foo(MyModel m)
{
    m.MyProperty = "Change it to this!";
    return View();
}

或者这个动作

[HttpPost]
public IActionResult Foo(MyModel m)
{
    m.MyProperty = "Change it to this!";
    return View(m);
}

查看呈现此内容:

<input asp-for="MyProperty" />

表单输入中的值为User entered value.而不是Change it to this!

首先,我很惊讶我们不需要将模型传递给视图并且它可以工作。其次,我很震惊请求有效负载优先于传递给视图的模型。任何人都知道这个设计决定的理由是什么?有没有办法在使用asp-for属性时覆盖用户输入的值?

2 个答案:

答案 0 :(得分:2)

我可以确认你的观察。真正让你大吃一惊的是:

[HttpPost]
public IActionResult Foo (MyModel m)
{
    m.MyProperty = "changed";
    var result = new MyModel { MyProperty = "changed" };
    return View(result);
}

...给你相同的结果。

我认为你应该记录一个错误:https://github.com/aspnet/mvc/issues

编辑:我现在记住以前遇到的这个问题并承认它不一定是一个错误,而是一个意想不到的后果。执行此代码的结果的原因并不明显。可能没有一个非平凡的方式来表达对此的警告,但PRG是一个很好的模式可以遵循。

答案 1 :(得分:2)

我相信这是预期的行为/设计。因为当您提交表单时,表单数据将存储到ModelState字典中,当razor呈现表单元素时,它将使用Model状态字典中的值。这就是为什么即使没有将视图模型的对象传递给View()方法,也会看到表单元素值。

如果要更新输入值,则需要明确清除模型状态字典。您可以使用ModelState.Clear()方法来执行此操作。

[HttpPost]
public IActionResult Create(YourviewModel model)
{       
    ModelState.Clear();
    model.YourProperty = "New Value";
    return View(model);
}

它使用模型状态字典来呈现表单元素值的原因是支持用例,当出现验证错误时显示表单中先前提交的值。

编辑:我找到了一个指向aspnet mvc官方github repo的链接,其中this is confirmed是Eilon(asp.net团队成员)

https://github.com/aspnet/Mvc/issues/4486#issuecomment-210603605

相关问题