如何让只读输入框正常提交表单数据而不依赖隐藏字段

在 asp.net 表单中,使用 `readonly` 的 `` 可以既保持用户不可编辑、又确保其值随表单一同提交,无需额外隐藏字段或 `display:none`/`visibility:hidden` 折衷方案。

在处理如“运费自动计算”这类场景时,一个常见误区是:为避免 disabled 字段不提交而改用 display:none 或 visibility:hidden 配合冗余隐藏字段。但这样做不仅增加 DOM 复杂度,还易引发绑定失败(如 type="hidden" 与 decimal 模型属性类型不匹配)、样式错位或 JavaScript 维护困难等问题。

✅ 正确做法是:直接使用带 name 属性的 readonly 输入框
readonly 元素不会被用户修改,但会参与表单序列化和服务器端模型绑定——只要它拥有合法的 name(对应模型属性名),ASP.NET MVC / Razor Pages 就能正确将值绑定到 decimal DeliveryCharge 等强类型属性上。

以下是精简、语义清晰且可直接落地的实现方案:

对应的 JavaScript 计算逻辑(示例):

function calculateDeliveryCharge() {
  const input = document.getElementById('deliveryChargeInput');
  // 示例:根据其他字段动态计算(如订单重量、地区等)
  const baseRate = 5.99;
  const surcharge = Math.random() * 3.0;
  const result = parseFloat((baseRate + surcharge).toFixed(2));
  input.value = result;
}

⚠️ 关键注意事项:

  • 必须保留 asp-for="DeliveryCharge":它会自动生成正确的 name="DeliveryCharge" 和 id,确保模型绑定;
  • 不要移除 readonly:它保障 UX(不可编辑)与功能(可提交)的统一;
  • 避免重复 asp-for:原代码中两个 asp-for="DeliveryCharge" 会导致生成同名字段,引发服务端绑定冲突或覆盖;
  • 禁用 disabled:disabled 字段永远不提交,即使视觉上类似 readonly,也不适用本场景;
  • 无需隐藏字段 在此场景下纯属冗余,且 type="hidden" 的值默认为字符串,若直接赋值 value="@Model.DeliveryCharge" 虽可工作,但绕过了 readonly 输入的双向一致性,增加维护成本。

? 进阶建议:
如需更严格的防篡改(例如防止用户通过 DevTools 修改 readonly 值),应在服务端重新校验并计算 DeliveryCharge,而非完全信任客户端输入——readonly 是 UX 层防护,非安全机制。

综上,拥抱 readonly + asp-for 的简洁组合,即可优雅解决“只读但可提交”的核心需求,兼顾可访问性、可维护性与服务端类型安全。