You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止Asp.NET Razor Pages提交表单时清空字段?

注册失败时表单字段被清空的解决办法

我有一个注册页面,注册成功会跳转到Index页面;但注册失败时,页面会显示错误信息,可所有表单字段都会被清空,怎么避免这个问题?我试过用JS的preventDefault(),但它会阻止表单提交,根本解决不了问题。另外我的OnGet方法是空的。

前端表单代码

<form method="post" asp-page-handler="Register" id="myForm">
      <div asp-validation-summary="All" class="text-danger"> </div>

      <div class="edit-profile__body">
          <div class="form-group mb-20">
              <label for="name">User name</label>
              <input type="text" class="form-control" name="UserName" id="name" placeholder="user name">
          </div>
          <div class="form-group mb-20">
              <label for="username">showing name</label>
              <input type="text" class="form-control" id="username" name="ShowName" placeholder="showing name">
          </div>
          <div class="form-group mb-20">
              <label for="email">Email</label>
              <input type="text" class="form-control" name="Email" id="email" placeholder="name@example.com">
          </div>
          <div class="form-group mb-15">
              <label for="password-field">password</label>
              <span asp-validation="password"></span>
              <div class="position-relative">
                  <input id="password-field" type="password" class="form-control" name="password"
                         placeholder="password">
                  <div class="uil uil-eye-slash text-lighten fs-15 field-icon toggle-password2"></div>
              </div>
          </div>
          <div class="admin-condition">
              <div class="checkbox-theme-default custom-checkbox">
                  <input class="checkbox" type="checkbox" name="ConfirmRules" id="admin-1" value="true">
                  <label for="admin-1">
                      <span class="checkbox-text">
                          I accept <a href="#" class="color-primary">Rules</a>
                          
                      </span>
                  </label>
              </div>
          </div>
          <div class="admin__button-group button-group d-flex pt-1 justify-content-md-start justify-content-center">
              <button type="submit" id="formSubmit" class="btn btn-primary btn-default w-100 btn-squared text-capitalize lh-normal px-50 signIn-createBtn ">
                  Create Account
              </button>
          </div>
      </div>
  </form>

后端处理代码

public async Task<IActionResult> OnPostRegister(SignUpVM signUpVM, CancellationToken cancellationToken)
{
    UserManagerResponse result;

    if (ModelState.IsValid && signUpVM.ConfirmRules)
    {
        var model = new UserDTO()
        {
            UserName = signUpVM.UserName,
            ShowName = signUpVM.ShowName,
            Email = signUpVM.Email,
            Password = signUpVM.Password,
        };

        result = await _userAppServices.Register(model, cancellationToken);

        if (result.IsSuccess)
        {
            return LocalRedirect("Index");
        }
        else
        {
            ModelState.AddModelError(string.Empty, result.Message);

            return default;
        }
    }
    else
    {
        return default;
    }
}

解决步骤

1. 修改后端方法,返回携带ViewModel的Page

原来的return default;会返回空页面结果,不会携带用户提交的表单数据。改成return Page();后,Razor Pages会自动把当前的signUpVM和ModelState传递回页面,用来填充表单字段。

修改后的后端代码:

public async Task<IActionResult> OnPostRegister(SignUpVM signUpVM, CancellationToken cancellationToken)
{
    UserManagerResponse result;

    if (ModelState.IsValid && signUpVM.ConfirmRules)
    {
        var model = new UserDTO()
        {
            UserName = signUpVM.UserName,
            ShowName = signUpVM.ShowName,
            Email = signUpVM.Email,
            Password = signUpVM.Password,
        };

        result = await _userAppServices.Register(model, cancellationToken);

        if (result.IsSuccess)
        {
            return LocalRedirect("Index");
        }
        else
        {
            ModelState.AddModelError(string.Empty, result.Message);
            // 返回Page(),保留表单数据
            return Page();
        }
    }
    else
    {
        // 验证失败时同样返回Page()
        return Page();
    }
}

2. 给前端表单添加asp-for绑定

把原来的name属性替换成asp-for,让Razor自动绑定ViewModel的属性,页面加载时会从ModelState中读取值填充输入框。修改后的关键字段示例:

<!-- UserName字段 -->
<input type="text" class="form-control" asp-for="UserName" id="name" placeholder="user name">
<!-- ShowName字段 -->
<input type="text" class="form-control" asp-for="ShowName" id="username" placeholder="showing name">
<!-- Email字段 -->
<input type="text" class="form-control" asp-for="Email" id="email" placeholder="name@example.com">
<!-- Password字段 -->
<input id="password-field" type="password" class="form-control" asp-for="Password" placeholder="password">
<!-- ConfirmRules复选框 -->
<input class="checkbox" type="checkbox" asp-for="ConfirmRules" id="admin-1">

asp-for会自动生成正确的name属性,同时完成数据绑定。

3. 密码字段的特殊处理(可选)

密码属于敏感信息,ModelState默认不会保留它的值。如果需要让用户不用重新输入密码(不推荐,存在安全风险),可以在注册失败的分支里手动把密码值添加到ModelState:

ModelState.SetModelValue(nameof(SignUpVM.Password), new ValueProviderResult(signUpVM.Password, System.Globalization.CultureInfo.InvariantCulture));

更安全的做法是让用户重新输入密码,只保留其他字段的值。

4. 完善OnGet方法(可选)

虽然空的OnGet方法也能工作,但显式返回Page()会更清晰,确保页面初始化时能正确绑定ViewModel:

public IActionResult OnGet()
{
    return Page();
}

内容的提问来源于stack exchange,提问作者Alireza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:38:14