【问题标题】:Input field set as 'Value=' instead of 'value='输入字段设置为 'Value=' 而不是 'value='
【发布时间】:2015-02-18 00:11:16
【问题描述】:

我有一个使用 Razor 模板用 C# MVC 编写的项目。在我的一个页面上,我有几个包含数值的输入字段。设置这些输入字段值的 Razor 代码如下所示:

@Html.Editor(Model.DesignParams[i].ParamId,
new {
    htmlAttributes = new
    {
        @Value = Model.DesignParams[i].DefaultValue,
        @class = "form-control text-right",
        @type = "text",
        id = "_" + Model.DesignParams[i].ParamId,
        uomid = Model.DesignParams[i].UOMId,
        measureid = Model.DesignParams[i].MeasureId
    }
})

以上代码使用 FireFox 和 Chrome 可以正常工作,并生成如下所示的输入字段:

<input type="text" uomid="MBH" name="HeatOfRejection" measureid="HeatLoad"
       id="_HeatOfRejection" class="form-control text-right text-box single-line"
       value="5000.0">

但是相同的 Razor 代码,相同的 @Model 值在 IE 中查看会生成:

<input Value="5000" class="form-control text-right text-box single-line"
       id="_HeatOfRejection" measureid="HeatLoad" name="HeatOfRejection" 
       type="text" uomid="MBH" value="" />

如您所见,为 IE 生成的 value= 属性之间的区别在于,获取我的实际值的 value 属性以大写的“V”开头,而小写的值是空字符串。我被这件事难住了……

谁能告诉我为什么会发生这种情况以及如何处理它?

这种差异会影响 jQuery 返回输入值的能力:

var value = $(inputfield).attr("value");

也许.val() 将检索输入字段值,但这需要重写支持此页面和其他页面的核心 jQuery 代码,所以我想问是否有人能告诉我为什么这个 'Value=' 得到仅为 IE 创建,如果有解决问题的方法。

更新:

在 Firefox 和 IE 中将 @Value 更改为 @value(或只是 value)会导致 value 属性为空:

<input type="text" value="" uomid="MBH" name="HeatOfRejection" measureid="HeatLoad" 
       id="_HeatOfRejection" class="form-control text-right text-box single-line">

【问题讨论】:

  • 你为什么要绑定到属性然后尝试用另一个属性的值覆盖它的值。在返回初始视图之前,只需在控制器中将ParamId 的值设置为DefaultValue 的值。您的代码的副作用是用户输入一个值(例如 4000.0)然后提交。如果您因为(比如说)验证错误而返回视图,用户的值将被 5000.0 覆盖 - 肯定会惹恼您网站的用户。

标签: html asp.net-mvc-4 internet-explorer razor input-field


【解决方案1】:

正如 StuartLC 指出的那样,您正试图让 Html.Editor 做一些它原本不打算做的事情。

当您将@value@Value 键传递给htmlAttributes 时会发生什么情况是,渲染引擎会生成一个具有该名称的属性除了 value 属性它已经生成:

<input type="text" name="n" value="something" value="somethingElse" />

<input type="text" name="n" value="something" Value="somethingElse" />

在这两种情况下,您都在给浏览器一些虚假的东西,因此不能期望它表现出可预测的行为。

如上所述,Html.Editor 具有根据您传递给它的expression 参数生成value 属性的功能。问题是您也错误地使用了它。 Html.Editor() 的第一个参数需要是一个表达式,指示编辑器应该绑定到的模型属性。 (例如字符串值 "DesignParams[0].ParamId")如今,首选的做法是使用更现代的 EditorFor,它采用 lambda 函数,正如 StuartLC 在他的帖子中所展示的:

@Html.EditorFor(model => model.DesignParams[i].ParamId, ...)

【讨论】:

    【解决方案2】:

    您正在“大写”value html 属性。将其更改为小写...

     @Value = Model.DesignParams[i].DefaultValue
    

    如下...

    @value = Model.DesignParams[i].DefaultValue
    

    IE 不是最聪明的网络浏览器,Trident(它们正在解析引擎)验证元素属性的方式肯定有问题,如这些线程中所见...

    https://github.com/highslide-software/highcharts.com/issues/1978

    Highcharts adds duplicate xmlns attribute to SVG element in IE

    另外,正如在其他地方已经指出的那样。 Editor 扩展方法需要什么?改用TextBoxFor 不是更简单吗?

    @Html.TextBoxFor(model => model.DesignParams[i].ParamId
        , new 
            { 
                @class = "form-control text-right"
                , uomid = Model.DesignParams[i].UOMId
                , measureid = Model.DesignParams[i].MeasureId 
             })
    

    【讨论】:

    • 我应该注意到这是我的第一直觉,但是我的值没有在任何浏览器的 value= 字段中设置,最终为 0。我希望将 @Value 设置为@value 解决了问题。
    • 不...我已将其更改为全小写(@value),还尝试了@StuartLC 答案使其成为value 没有'@',但随后我得到value="" 在IE 中呈现和 Firefox。
    • @Leo 我不认为 IE 真的应该归咎于不知道如何处理同名的两个属性。至少它将具有不同大小写的属性视为单独的属性,而不是像其他浏览器那样假装它们是相同的属性。
    • @JLRishe 完全相反,如果我们要责怪任何人,那就是 IE 没有遵循明确指出属性不区分大小写的标准,因此 Value 与 @987654333 相同@
    • @Leo 当有两个同名的属性以不同的大小写时,标准是否说明了浏览器应该做什么?我猜这是一个灰色地带。在我看来,IE 正在尽最大努力尽可能地适应页面的虚假标记。当没有重复时,IE 正确地将属性视为不区分大小写。
    【解决方案3】:

    编辑器使用元数据。那么你需要更多关于这个, http://aspadvice.com/blogs/kiran/archive/2009/11/29/Adding-html-attributes-support-for-Templates-2D00-ASP.Net-MVC-2.0-Beta_2D00_1.aspx

    但最简单的方法是使用

    @model Namespace.ABCModel
    
    @using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
     @Html.TextBoxFor(model => model.DesignParams[i].ParamId, new { @class = "form-control text-right",     uomid = Model.DesignParams[i].UOMId, measureid = Model.DesignParams[i].MeasureId })
    }
    

    【讨论】:

    • 您的示例中的 value 属性在哪里设置?
    • 值会自动用这种方式设置,我会编辑我的答案以获得更多解释
    【解决方案4】:

    您不应该以这种方式使用无效的 Html 属性。使用 Html 5 中的data- 属性。

    另外,您对@Html.Editor(Model.DesignParams[i].ParamId 的使用(假设ParamId 是一个字符串)偏离了帮助程序的目的,即从模型中反映具有给定名称的属性,并将该属性的值用作Html @987654326 input 上的 @ 属性。 (无论 ParamId 的值是多少,MVC 都会在根模型上寻找一个属性,这似乎默默地失败了 FWR)

    我会事先在 Controller 中或在 DesignParams 构造函数中默认 Model.DesignParams[i].ParamId = Model.DesignParams[i].DefaultValue

    @Html.EditorFor(m => m.DesignParams[0].ParamID,
       new {
          htmlAttributes = new
            {
                // Don't set value at all here - the value IS m.DesignParams[0].ParamID
                @class = "form-control text-right",
                @type = "text",
                id = "_" + Model.DesignParams[i].ParamId,
                data_uomid = Model.DesignParams[i].UOMId,
                data_measureid = Model.DesignParams[i].MeasureId
            }
    

    请注意,这会将输入名称指定为 DesignParams[0].ParamID,如有必要,需要使用该名称将字段发回。

    这是一些示例代码的Gist

    underscorewill be converteddash) 在 jQuery 中使用data() 来获取这些值:

    var value = $(inputfield).data("uomid");
    

    【讨论】:

    • 谢谢你。这很有帮助。你是说你认为这会解决我发布的问题吗?我的意思是,您可能会指出我处理自定义属性的“正确”方式。这是个好建议,但您认为它会解决问题吗?
    • Data attributes in html 5 提供了一种将自定义属性附加到 html 元素的标准方法,而无需使用我们自己的自定义属性。并且通过数据的 jQuery 支持使得刮掉它们变得很简单(记得省略 .data() 的前缀 .data()
    • @rwkiii 我添加了一些示例 Gist 代码,以提供有关使用创建输入字段的替代想法,并正确设置值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 2012-12-18
    • 2016-11-09
    • 2015-06-03
    • 2017-06-29
    • 2022-11-10
    相关资源
    最近更新 更多