【问题标题】:ASP.NET Core: asp-* attributes use request payload over model?ASP.NET Core:asp-* 属性在模型上使用请求有效负载?
【发布时间】:2017-02-01 15:01:33
【问题描述】:

似乎在 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 属性时有没有办法覆盖用户输入的值?

【问题讨论】:

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


    【解决方案1】:

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

    如果要更新输入值,则需要明确清除模型状态字典。你可以使用ModelState.Clear() 方法来做到这一点。

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

    它使用模型状态字典来呈现表单元素值的原因是为了支持用例,例如在发生验证错误时在表单中显示之前提交的值。

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

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

    【讨论】:

    • 即使我确实将模型传递给视图,我也会看到这种行为。请参阅我在问题中的第二个示例。 ModelState.Clear() 似乎是解决这个问题的一种混乱方式。我不认为 MVC 5 需要这样的东西。
    • 没有。这就是这样做的方法。即使在 MVC5 中,它的工作方式也是一样的。请参阅官方成员(Eilon)确认此链接的此链接github.com/aspnet/Mvc/issues/4486#issuecomment-210603605
    【解决方案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 是一个很好的模式。

    【讨论】:

    • 好的,我在这里提交了一个问题:github.com/aspnet/Mvc/issues/5315
    • 很好,你们提出了这个问题,我很幸运能找到它。在我发现 ModelState.Clear() 方法之前,我一直在解决这个问题。我正在从 asp.net mvc 迁移到 asp core mvc,在 asp.net 中,相同的代码没有像在 core 中那样的问题。
    猜你喜欢
    • 2013-09-23
    • 2023-04-10
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 2019-11-10
    相关资源
    最近更新 更多