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

.NET Core Razor Pages实现.cshtml表单校验通过才可提交的问题修复

问题根因

你的表单校验无法阻止提交,核心是4个逻辑错误:

  • 单字段校验函数返回值逻辑完全混乱:比如fname()检测到名字为空(校验失败)时返回true,校验通过反而返回false;密码相关的checkpass1/checkpass2又反过来,校验失败返回false、通过返回true,用&&做联合判断时结果完全不可控
  • 全局count变量存在覆盖问题:前一个字段校验失败把count设为1,后一个字段校验通过又会把count改回0,导致漏判错误
  • validate()函数没有拦截浏览器默认提交行为:就算检测到错误,浏览器还是会正常发送POST请求
  • 后端校验失败返回页面时,没有重新加载国家下拉列表数据,会导致下拉框选项清空

修复步骤

1. 统一前端单字段校验逻辑

删掉全局无用的var count=0变量,所有单字段校验统一规则:校验通过返回true,校验失败返回false,替换原有的校验函数代码:

const fname = () => {
    const inputVal = document.getElementById("signUpFirstName").value.trim();
    const errorSpan = document.querySelector("#l1 span");
    if (inputVal.length === 0) {
        errorSpan.innerHTML = "Please Enter Your First Name";
        errorSpan.style.color = "red";
        return false;
    }
    errorSpan.innerHTML = "";
    return true;
}
const lname = () => {
    const inputVal = document.getElementById("signUpLastName").value.trim();
    const errorSpan = document.querySelector("#l2 span");
    if (inputVal.length === 0) {
        errorSpan.innerHTML = "Please Enter Your Last Name";
        errorSpan.style.color = "red";
        return false;
    }
    errorSpan.innerHTML = "";
    return true;
}
const checkcountry = () => {
    const inputVal = document.getElementById("signUpCountryCode").value.trim();
    const errorSpan = document.querySelector("#l3 span");
    if (inputVal.length === 0) {
        errorSpan.innerHTML = "Please Enter Your Country";
        errorSpan.style.color = "red";
        return false;
    }
    errorSpan.innerHTML = "";
    return true;
}
const checkMobile = () => {
    const inputVal = document.getElementById("signUpMobileNumber").value.trim();
    const errorSpan = document.querySelector("#i4 span");
    const phonenoReg = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
    if (!phonenoReg.test(inputVal)) {
        errorSpan.innerHTML = "Please Enter a valid Mobile No.";
        errorSpan.style.color = "red";
        return false;
    }
    errorSpan.innerHTML = "";
    return true;
}
const checkEmail = () => {
    const inputVal = document.getElementById("signUpEmail").value.trim();
    const emailReg = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
    const errorSpan = document.querySelector("#i5 span");
    if (!emailReg.test(inputVal)) {
        errorSpan.innerHTML = "Please Enter a valid Email id.";
        errorSpan.style.color = "red";
        return false;
    }
    errorSpan.innerHTML = "";
    return true;
}
const checkpass1 = () => {
    const inputVal = document.getElementById("signUpPassword").value;
    const errorSpan = document.querySelector("#i6 span");
    const specialCharReg = /[`!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?~]/;
    if (inputVal.length < 8) {
        errorSpan.innerHTML = "Password length must be atleast 8 characters";
        errorSpan.style.color = "red";
        return false;
    }
    if (inputVal.length > 12) {
        errorSpan.innerHTML = "Password length must not exceed 12 characters";
        errorSpan.style.color = "red";
        return false;
    }
    if (!specialCharReg.test(inputVal)) {
        errorSpan.innerHTML = "Password must contain atleast 1 special character";
        errorSpan.style.color = "red";
        return false;
    }
    errorSpan.innerHTML = "";
    return true;
}
const checkpass2 = () => {
    const confirmVal = document.getElementById("signUpConfirmPassword").value;
    const passwordVal = document.getElementById("signUpPassword").value;
    const errorSpan = document.querySelector("#i7 span");
    if (confirmVal !== passwordVal) {
        errorSpan.innerHTML = "Password does not match";
        errorSpan.style.color = "red";
        return false;
    }
    errorSpan.innerHTML = "";
    return true;
}

2. 绑定表单提交事件,拦截非法提交

首先给form标签加id,同时删掉提交按钮上的onclick="validate()"属性:

<form class="mb-3" method="post" id="signUpForm">

替换原有的validate()函数,直接监听表单的submit事件,校验失败时阻止默认提交行为:

const validate = (e) => {
    const isAllValid = fname() && lname() && checkcountry() && checkMobile() && checkEmail() && checkpass1() && checkpass2();
    if (!isAllValid) {
        e.preventDefault();
        console.log("校验失败,阻止表单提交");
        return false;
    }
    console.log("校验通过,允许提交");
    return true;
}
// 绑定表单提交事件
document.getElementById("signUpForm").addEventListener("submit", validate);

3. 修复后端校验逻辑

补全空值判断,校验失败返回页面时重新加载下拉列表数据,避免控件清空,替换原有的OnPost方法:

public async Task<IActionResult> OnPost()
{
    // 加载国家下拉列表公共逻辑
    async Task LoadCountryList()
    {
        if (!_memoryCache.TryGetValue("CountryList", out List<MasterDataContent> cacheValue))
        {
            var countryList = await this._masterData.GetData("MasterDataItems/GetCountry", "");
            cacheValue = countryList;
            _memoryCache.Set("CountryList", cacheValue, SoraCacheManager.ThreeHunderedSecondsCache());
        }
        signUp ??= new SignUpPageVM();
        signUp.CountryList = new SelectList(cacheValue, "key", "value");
    }

    if (!ModelState.IsValid || signUp == null)
    {
        await LoadCountryList();
        return Page();
    }

    if (signUp.ConfirmPassword != signUp.Password)
    {
        ModelState.AddModelError(string.Empty, "两次输入的密码不一致");
        await LoadCountryList();
        return Page();
    }

    UserSignUpRequestDTO signUpRequest = new UserSignUpRequestDTO
    {
        FirstName = signUp.FirstName,
        LastName = signUp.LastName,
        MobileNumber = signUp.MobileNumber,
        Email = signUp.Email,
        CountryCode = signUp.CountryCode,
        Password = signUp.Password
    };

    var response = await this._webClient!.PostData("User/SignUp", signUpRequest);
    return RedirectToPage("Login");
}

注意:前端JS校验仅用于提升用户体验,后端校验必须保留,用户可以直接禁用JS绕过前端校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:36:29