【问题标题】:Razor syntax for view models of type IEnumerable<T> for DisplayFor用于 DisplayFor 的 IEnumerable<T> 类型的视图模型的 Razor 语法
【发布时间】:2012-10-04 16:06:32
【问题描述】:

我从 SQL db 中提取日期时间,格式为 hh:mm dd/mm/yyyy

使用 Razor 语法,我可以显示存储在数据库中的日期

@Html.DisplayFor(modelItem => item.Updated)

我希望 Razor 以以下格式显示 dd MMM yyyy 所以我按照另一个 StackOverflow 答案尝试了以下操作:

@Html.DisplayFor(modelItem => item.Updated.ToString("dd MMM yyyy"))

Converting DateTime format using razor

但是这会产生以下错误:

“/”应用程序中的服务器错误。

模板只能用于字段访问、属性访问、 一维数组索引,或单参数自定义索引器 表达式。

描述:执行过程中发生了未处理的异常 当前的网络请求。请查看堆栈跟踪以获取更多信息 有关错误的信息以及它在代码中的来源。

异常详细信息:System.InvalidOperationException:模板可以 仅与字段访问、属性访问、一维数组一起使用 index 或单参数自定义索引器表达式。

来源错误:

第 36 行:第 37 行:第 38 行:
@Html.DisplayFor(modelItem => item.Updated.ToString("dd MMM yyyy")) 第 39 行:第 40 行:

我刚刚开始掌握 ASP.NET 等...我不确定如何创建视图模型来尝试这个示例,因为我首先使用自动生成的 edmx 文件构建 DB:

[DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")] 
pubilc DateTime Updated { get; set } 

有什么建议吗?

目前这些工作。我要做的就是更改“更新”属性的显示格式。 我的视图文件: http://pastebin.com/Ywn8Z0TV

我的控制器: http://pastebin.com/1jAih6AE

我的模型: http://pastebin.com/UC61QjFZ

更新:对于那些声明应该是 item => item.Updated...

Error   1   A local variable named 'item' cannot be declared in this scope because it would give a different meaning to 'item', which is already used in a 'parent or current' scope to denote something else

【问题讨论】:

  • 你的 lambda 表达式都是modelItem =&gt; item.[...] 的形式。你不应该在 RHS 上使用modelItem 吗?
  • 您好,modelItem => modelItem 不起作用。 modelItem =>item 是脚手架。它适用于 modelItem => item。我只需要更改显示格式
  • 这对我来说听起来非常很奇怪 - item 那时指的是什么变量?
  • 你能编辑你的帖子并显示@model@model 使用的类定义吗?脚手架上发生了一些不寻常的事情。
  • @Erik - 我已经通过上面的 pastebin 包含了模型、视图和控制器。谢谢

标签: c# asp.net-mvc razor


【解决方案1】:

您的解决方案不起作用的具体原因与错误状态完全相同。

模板只能用于字段访问、属性访问、一维数组索引或单参数自定义索引器表达式。

所以ToString() 是一种方法,不适用于模板。

其他人已经给出了另一种解决方案,我想解释一下为什么你的不起作用。

我刚刚开始掌握 ASP.NET 等...我不确定如何创建视图模型来尝试这个示例,因为我首先使用自动生成的 edmx 文件构建 DB

您的 edmx 文件应该创建一个看起来也相似的类:

public partial class SomeTable
{
  public DateTime Updated { get; set } 
}

在同一个项目中,在同一个 NameSpace(不一定是目录)中创建一个名为 SomeTable.Partial.cs 的文件,看起来也很相似:

public partial class SomeTable
{
  [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")] 
  pubilc DateTime Updated { get; set } 
}

Entity Framework 默认创建Partial Classes 代表您选择的表。这意味着您可以在另一个文件中定义另一个部分类,并且 .Net 在编译时会将每个属性的所有属性组合成一个属性。

更新

这段代码对我来说看起来很奇怪,我不明白它是如何工作的:

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Metal.Name)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Currency.Code)

更新 2

DisplayFor 用于显示模型上的属性(并且仅直接显示模型上的属性)。当您枚举类型为IEnumerable&lt;&gt;(或模型上的属性)的模型时,您不能再使用DisplayFor 来显示这些值。您应该改用Display。例如,Metal.Name 不存在于 IEnumerable 中,它存在于 IEnumerable 中的元素内。

@foreach (var item in Model) {
<tr>
    <td>
        @Html.Display(item.Metal.Name)
    </td>
    <td>
        @Html.Display(item.Currency.Code)

错误更新

错误 1 ​​不能在此范围内声明名为“item”的局部变量,因为它会给“item”赋予不同的含义,而“item”已在“父或当前”范围中用于表示其他内容

当存在如下代码时:

@foreach (var item in Model) // or Model.Items
{
  <div>
  @Html.DisplayFor(item => item.Updated)
  </div>
}

所有 MVC EditForDisplayFor 方法都使用 Expression&lt;TDelegate&gt; 所以当代码状态 DisplayFor(item =&gt; item.Updated) 第一个 item 基本上定义了一个变量 T item 但是你不能再次定义相同的变量名.为了说明这不是 MVC 特定的,这也不会编译并给出相同的错误(并且对于相同变量名的声明更明显):

var item = 1;
var items = new List<int>() { 1, 2, 3, 4};
var sameItem = items.Select(item => item == item);

【讨论】:

  • 嗨 Erik... 这很奇怪,而且不帮助我学习 ASP.NET !!!我向你保证它有效。更重要的是,我所有的 index.cshtml 视图都是这样搭建的......'modelItem => item.Property'。脚手架显示标签的方式不同... ' @Html.DisplayNameFor(model => model.Category.Name) @Html.DisplayNameFor(model => model.Metal.Name) th> @Html.DisplayNameFor(model => model.Name) '
  • 如果我改成你说的样子...已在“父级或当前”范围内用于表示其他内容
  • 关于带有数据注释的部分类——这是我正在使用的一种方法,到目前为止似乎是一个成功的解决方案。这篇博文与讨论相关,有助于加深我的理解Ardalis - EF Partials
【解决方案2】:

试试这个:

[DisplayFormat(DataFormatString = "{0:dd MM yyyy}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public DateTime Updated { get; set; }

【讨论】:

  • 谢谢,但是当我首先使用自动生成的数据库模型做数据库时,如何为此创建一个视图模型?
  • 您的模型类是否由 LINQ、实体框架等自动生成?如果是,那么这些是部分类。您可以添加自己的分部类来扩展 DB 生成的类,并将 MetadataType 注释附加到该类,并为您的模型的元数据严格创建类。这是一直在做的。有关示例,请参见此链接:jameschambers.com/blog/…
【解决方案3】:

试试下面的。您似乎正在使用不正确的语法调用 DisplayFor 方法。

@Html.DisplayFor(x => x.Updated)

使用 lambda 时,需要匹配 =&gt; 符号前后的符号名称。

您当前使用的modelItemitem 不一样。

【讨论】:

  • 他已经这样做了,它在显示数据时使用默认的 DateTime 格式。不过,他想要一种不同的格式。
  • 那么他应该用他实际使用的代码更新他的问题。
  • 他在问题顶部附近显示了确切的Html.DisplayFor。然后在它的正下方,显示了他试图做的事情没有奏效。所以他尝试的两种解决方案都不起作用,他正在寻求帮助。
  • 啊,modelItem/item。是的,但是在将代码放入他的问题时似乎是一个错误,因为他说它显示了DateTime 罚款。仍然给他留下了使用不正确格式的问题。
  • 谢谢 Gromer... 你明白了... modelItem => modelItem 不起作用。 modelItem =>item 是脚手架。它适用于 modelItem => item。我只需要更改显示格式
猜你喜欢
  • 2012-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多