MVC中@Html.EditorFor与@Html.PasswordFor渲染输入框样式不一致问题
问题原因
核心问题是**EditorFor和PasswordFor两个HTML辅助方法的参数签名规则不同,直接照搬EditorFor的传参格式给PasswordFor用,会导致自定义HTML属性无法被正确解析**。
从错误渲染结果可以直接定位问题:生成的input标签上出现了htmlattributes="{ class = form-control k-textbox large, placeholder = password, id = password, autocomplete = off }"这类异常属性,就是传参层级错误的典型表现。
两个方法的传参规则差异如下:
@Html.EditorFor属于模板化辅助方法,第二个参数是视图数据对象,所有自定义HTML属性必须包裹在htmlAttributes键对应的匿名对象中,你原来写的new { htmlAttributes = new { ... } }格式完全符合EditorFor的传参要求。@Html.PasswordFor属于直接渲染单个输入框的强类型辅助方法,和TextBoxFor、HiddenFor等方法签名一致,第二个参数直接接收HTML属性的匿名对象,不需要额外套一层htmlAttributes包装。把EditorFor的参数原样传给PasswordFor时,方法会把整个带htmlAttributes属性的外层匿名对象直接解析为标签属性,自然就把htmlAttributes本身当成一个属性输出,你定义的class、placeholder、autocomplete、自定义id等属性全部被嵌套在内层对象里,根本没有渲染到标签上,最终导致样式丢失、placeholder不显示。
标签上的data-val、data-val-required这类验证属性,是辅助方法根据模型上的验证特性自动生成的,和自定义HTML属性传参无关,所以哪怕传参错误这部分也会正常输出。
修复方法
去掉PasswordFor参数里外层包裹的htmlAttributes = new { ... }层级,直接把属性对象作为第二个参数传入即可,修正后的代码如下:
@Html.PasswordFor(x => x.Pwd, new { @class = "form-control k-textbox large", placeholder = "password", @id = "password", @autocomplete = "off" })
修正后渲染出的input标签会正确带上所有自定义属性,class、placeholder、autocomplete都会正常生效,样式表现和EditorFor生成的密码框完全一致。
注:代码中EditorFor绑定的是
Password字段、PasswordFor绑定的是Pwd字段,最终生成的标签name属性会分别对应两个字段名,属于正常表现,不属于异常。

内容的提问来源于stack exchange,提问作者gene
相关产品推荐
相关产品推荐

