【问题标题】:Controller in view doesn't update the view model upon being edited视图中的控制器在编辑时不会更新视图模型
【发布时间】:2019-02-01 21:40:26
【问题描述】:

我有以下表格。

@model LoginVm
<form asp-controller="Sec" 
      asp-action="Authorize"
      asp-all-route-data="@Model.Querify" 
      method="post">
  Email:  <input asp-for="@Model.UserName" /> <br />
  Password: <input asp-for="@Model.Password" /><br />
  <button type="submit">Send</button>
</form>

视图模型是这样的。

public class LoginVm
{
  public string UserName { get; set; }
  public string Password { get; set; }
  public string ReturnUrl { get; set; }

  public IDictionary<string, string> Querify 
    => new Dictionary<string, string>
    {
      { "username", UserName },
      { "password", Password },
      { "returnurl", ReturnUrl }
    };
  }

但是,在下面显示的接收方法中,只存在在再现之前写入视图模型的值。所以,无论我在将它传递到视图之前放入视图模型中的什么,它都在那里。我尝试在输入框中对模型进行的任何更改都会丢失。

[HttpPost]
public IActionResult Authorize(
  [FromQuery]string returnUrl, 
  [FromQuery]string userName, 
  [FromQuery] string password)
{ ... }

我虽然基于the docs 将输入框中的值绑定到模型中的字段,但显然我没有。不知道如何进一步诊断。

【问题讨论】:

    标签: c# razor asp.net-core asp.net-core-2.2


    【解决方案1】:

    我认为您可能由于以下行而将原始数据绑定回来:

          asp-all-route-data="@Model.Querify" 
    

    我认为这是将原始模型作为参数发送回控制器,并忽略表单中的参数。

    删除该行并将其替换为

     asp-route-returnurl="@Model.ReturnUrl"
    

    编辑:

    根据 cmets 更新。

    测试它可以正常工作,看起来 [FromQuery] 也是一个问题,因此只需取回视图模型即可。

    控制器代码:

      public IActionResult Sec()
        {
            var viewModel = new LoginVm();
    
            viewModel.ReturnUrl = "http://stackoverflow.com";
            return View(viewModel);
        }
    
        [HttpPost]
        public IActionResult Sec(LoginVm viewModel)
        {
           return Redirect(viewModel.ReturnUrl);
        }
    

    视图模型:

         public class LoginVm
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public string ReturnUrl { get; set; }
    }
    

    查看:

     @model LoginVm
    <form asp-controller="Authorization"
      asp-action="Sec"   
    asp-route-returnurl="@Model.ReturnUrl"
      method="post">
    Email:  <input asp-for="@Model.UserName" /> <br />
    Password: <input asp-for="@Model.Password" /><br />
    <button type="submit">Send</button>
    </form>
    

    【讨论】:

    • 要上下文化 @Mark 所说的内容,当在 Razor 页面中使用基于 @ 的嵌入式 C# 语法时,这些值会在生成视图时进行评估。创建页面的标记后,模型将不复存在 - 就您的视图而言,它无法有效地改变。
    • 我认为你是对的 - 查询字符串的再现可能会在页面加载时发生,此时,用户名和密码未设置。但是,您提出的解决方案不会这样做,因为我需要以某种方式传递实际输入的凭据。有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 2012-12-31
    • 2013-05-26
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多