readonly字段可正常提交,前提是必须有合法name属性;常见不提交原因包括:缺失name、误用disabled、滥用display:none/visibility:hidden或手动覆盖asp-for生成的name。

readonly 属性本身就能让字段只读且正常提交,不需要额外操作——前提是它有合法的 name 属性。
为什么 readonly 字段有时不提交?
常见错误是误以为只要加了 readonly 就万事大吉,却忽略了表单提交依赖的是 name 而非 id 或视觉状态:
- 没写
name属性 → 浏览器根本不会把它加入 FormData 或表单序列化结果中 - 用了
disabled="true"替代readonly→ 浏览器明确忽略该字段,后端收不到任何键值对 - 用
display: none或visibility: hidden配合隐藏<input>→ 多余 DOM、类型绑定易出错(如 decimal 模型绑定失败) - 在 ASP.NET Core 中手动覆盖了
name(比如写了name="delivery"而不是让asp-for="DeliveryCharge"自动生成)→ 模型绑定路径断裂
如何正确写一个可提交的 readonly input
最简可靠写法就是标准 HTML + 必须带 name:
<input type="text" name="country" value="China" readonly>
在 Razor Pages / ASP.NET Core MVC 中,推荐用 Tag Helper 保证语义和绑定一致性:
立即学习“前端免费学习笔记(深入)”;
<input readonly asp-for="DeliveryCharge" type="number" step="0.01">
关键点:
-
readonly是布尔属性,写成readonly或readonly="readonly"都行(XHTML 要求后者) -
asp-for="DeliveryCharge"会自动生成正确的name="DeliveryCharge"和value,无需手动干预 - 不要加
disabled,也不要套一层<div style="display:none"> - 如果 JS 动态更新值,直接赋给
input.value即可,不影响提交
JavaScript 动态控制 readonly 状态要注意什么
用 JS 切换只读状态时,别混用属性名和 DOM 属性名:
- ✅ 正确:
input.readOnly = true(注意是readOnly,驼峰写法) - ✅ 正确:
input.setAttribute('readonly', '')或input.removeAttribute('readonly') - ❌ 错误:
input.setAttribute('readonly', 'true')—— 布尔属性不需要值,设了反而可能被当字符串解析 - ❌ 错误:
input.readonly = true—— DOM 属性名是readOnly,小写readonly无效
另外,readonly 元素仍可触发 focus、select、copy,这点和 disabled 完全不同,适合需要用户复制结果的场景(比如订单号、计算金额)。
最容易被忽略的一点:readonly 字段的值在提交时仍按原始 type 解析(如 type="number" 提交的是数字字符串),后端模型绑定必须能处理这种格式;若用自定义转换或强类型(如 C# 的 decimal),确保前端没意外转成空格或单位符号(如 “¥12.50”),否则绑定会静默失败。



















