如何在 MVC Razor 中的数组或 IEnumerable 对象上应用 DataFormatSt

How to apply DataFormatString on a array or IEnumerable object in MVC Razor?
2021-11-25
  •  译文(汉语)
  •  原文(英语)

我的视图模型中有一个 double 数组,我想应用如下所示的数据格式字符串:

class MyVM 
{
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:F2}")]
    public double Currents[] { get; set; }
}

在我的视图中,我在如下所示的数组上使用 EditorFor,它正常工作,除了不应用数据格式字符串.

@Html.EditorFor(model => model.Currents)

我了解到我可以使用自定义模板,但想知道是否有比创建自定义模板更简单的方法.如果自定义模板是唯一的解决方案,那么应该处理格式的最简单的自定义模板是什么?我尝试创建一个,但未能正确应用数据格式字符串.

我可以在 ~Views\Shared 文件夹中创建一个 CurrentsTemplate.cshtml 包含以下内容

@model double[]

@foreach (double x in Model) {
<div class="editor-field">
    @Html.TextBoxFor(m=>x, "{0:F2}")
</div>
}

并通过调用@Html.EditorFor(m => m.Currents,"CurrentsTemplate") 来使用它,它会工作,但表单数据在发布后不会持久化.猜猜我需要 for 循环中的隐藏字段以及 TextBox.

解决过程1

创建一个自定义模板,将根据需要格式化您的 double.这样,当 MVC 看到double它时,它将使用您的模板而不是它的内部逻辑来显示它.

例如,EditorTemplates在您的 Views\Shared 文件夹中创建一个文件夹,然后创建名为 double.cshtml 的 double 类型的强局部视图.

这段代码

@model double

@Html.TextBoxFor(m => m, "{0:F2}")

希望这可以帮助.

解决过程2

解决的办法是与期望的数据格式字符串沿使用实际的构件名称@Html.TextBoxFor帮手.由于数据是 IEnumerable,因此只需将其放在 for 循环中即可.生成的 HTML 将包含与视图模型的成员名称匹配的适当名称字段,这对于跨 POST 返回的数据持久性很重要.不需要隐藏的 HTML 表单字段.

@for (int k = 0; k < Model.Currents.Count(); k++ ) {
    @Html.TextBoxFor(model => model.Currents[k], "{0:F2}")                                                           
}

以上将适用于正确的数据格式.它产生

 <input name="Currents[0]" id="Currents_0_" type="text" data-val-number="The field Double must be a number." data-val="true" value="0.8"/>

并在 POST 后以适当的持久性工作.

以下三种情况不起作用:

情况1:

@foreach (double x in Model) {
    @Html.TextBoxFor(m=>x, "{0:F2}")
}
  • 不会在 POST 后保持不变,因为它会生成 name="x" 的 HTML.
  • 不过,这个应用了正确的数据格式.

案例2:

@Html.EditorFor(m => m.Currents)
  • 不按需要格式化数据
  • 但由于实际的视图数据成员名称在生成的 HTML 中使用,因此在 POST 后仍然存在.

案例3:

@Html.EditorFor(m => m.Currents, "TemplateName")

与案例1相同.

I have an array of double in my View Model and I'd like to apply a data format string like shown below:

class MyVM 
{
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:F2}")]
    public double Currents[] { get; set; }
}

In my View, I am using EditorFor on the array like shown below, which is properly working except its not applying the data format string.

@Html.EditorFor(model => model.Currents)

I learned that I can use custom templates, but was wondering is there is a simpler way than creating a custom template. If custom template is the only solution, what is the simplest custom template that should take care of the formatting? I tried creating one but was not successful in applying the data format string properly.

I can create a CurrentsTemplate.cshtml in the ~Views\Shared folder with the below content

@model double[]

@foreach (double x in Model) {
<div class="editor-field">
    @Html.TextBoxFor(m=>x, "{0:F2}")
</div>
}

and use that by calling @Html.EditorFor(m => m.Currents,"CurrentsTemplate"), it will work but the form data is not persisting after its POSTed. Guess I need hidden fields in the for loop along with the TextBox.

Solutions1

Create a custom template that will format your double as needed. That way when MVC sees double it will use your template rather than it's internal logic for displaying it.

For example, create a EditorTemplates folder in your Views\Shared folder, then create strongly partial view of type double named double.cshtml.

This piece of code

@model double

@Html.TextBoxFor(m => m, "{0:F2}")

Hope this helps.

Solutions2

The solution is to use the actual member name along with the desired data format string in the @Html.TextBoxFor helper. Since the data is an IEnumerable simply place it in a for loop. The generated HTML will contain appropriate name field that matches the View Model's member name which is important for data persistence across POST backs. No hidden HTML form fields needed.

@for (int k = 0; k < Model.Currents.Count(); k++ ) {
    @Html.TextBoxFor(model => model.Currents[k], "{0:F2}")                                                           
}

The above will work with proper data formatting. It generates

 <input name="Currents[0]" id="Currents_0_" type="text" data-val-number="The field Double must be a number." data-val="true" value="0.8"/>

and works with proper persistence across POST backs.

The following three cases don't work:

case 1:

@foreach (double x in Model) {
    @Html.TextBoxFor(m=>x, "{0:F2}")
}
  • Does not persist across POST backs as it generates HTML with name="x".
  • This one applies proper data formatting though.

case 2:

@Html.EditorFor(m => m.Currents)
  • Does not data format as needed
  • But persists across POST backs since actual view data member name is used in the generated HTML.

case 3:

@Html.EditorFor(m => m.Currents, "TemplateName")

Same as case 1.

转载于:https://stackoverflow.com/questions/15238328/how-to-apply-dataformatstring-on-a-array-or-ienumerable-object-in-mvc-razor

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入