【问题标题】:"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions" error“模板只能用于字段访问、属性访问、单维数组索引或单参数自定义索引器表达式”错误
【发布时间】:2014-02-13 12:18:45
【问题描述】:

为什么我会收到错误消息:

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

在此代码处:

@model IEnumerable<ArtSchoolProject.Models.Trainer>

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_PageLayout.cshtml";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<ul class="trainers">


@foreach (var item in Model) {
<li>
  <div>
      <div class="left">
          <a href="@Url.Action("Details", "Details", new { id = item.ID })">
              <img src="~/Images/Trainer/@item.Picture" />
          </a>
      </div>
      <div class="right">
          @Html.ActionLink(item.Name,"Details",new {id=item.ID})
          <br />
          @Html.DisplayFor(modelItem=>@string. item.Description.ToString().Substring(0,100))
      </div>
  </div>
  </li>
  }

  </ul>

在线:

@Html.DisplayFor(modelItem=>item.Description.ToString().Substring(0,100))

更新:

问题解决了。我添加到我的代码中:

  @{
string parameterValue = item.Description.ToString().Substring(0, 100); 
          }
          @Html.DisplayFor(modelItem=>parameterValue)

我的新代码:

@foreach (var item in Model) {
<li>
  <div>
      <div class="left">
          <a href="@Url.Action("Details", "Details", new { id = item.ID })">
              <img src="~/Images/Trainer/@item.Picture" />
          </a>
      </div>
      <div class="right">
          @Html.ActionLink(item.Name,"Details",new {id=item.ID})
          <br />
          @{
string parameterValue = item.Description.ToString().Substring(0, 100); 
          }
          @Html.DisplayFor(modelItem=>parameterValue)
      </div>
  </div>
 </li>
}

这只是一种可能。只是出于好奇,是否有解决错误的另一种解决方案?

【问题讨论】:

  • 太棒了!您的解决方案对我有用,而且非常简单。如果您可以将解决方案作为答案而不是更新并接受它,那就太好了。因为我们通常会查看已接受的答案。

标签: c# asp.net string asp.net-mvc-4


【解决方案1】:

我也遇到了类似的问题

@foreach (var item in Model)
{
    @Html.DisplayFor(m => !item.IsIdle, "BoolIcon")
}

我解决了这个问题

@foreach (var item in Model)
{
    var active = !item.IsIdle;
    @Html.DisplayFor(m => active , "BoolIcon")
}

知道诀窍后,就很简单了。

不同之处在于,在第一种情况下,我将方法作为参数传递,而在第二种情况下,它是一个表达式。

【讨论】:

  • 完美!!!谢谢你的回答@Daniel,我和这个混蛋战斗了好几个小时
  • 不,不,不。这是一个糟糕的模式。使用@Html.Display。如果您希望渲染的 HTML 以该属性命名,您只需要 DisplayFor - 如果您希望它回发到同一属性。 这个和人们在花括号内使用RenderAction 而不仅仅是Action。这让我觉得没有人真正知道 MVC 是如何工作的。
【解决方案2】:

它所指的模板是Html helper DisplayFor

DisplayFor 期望得到一个符合错误消息中指定规则的表达式。

您正在尝试传入要执行的方法链,但它不喜欢它。

这是 MVVM(模型-视图-视图模型)模式派上用场的完美示例。

您可以将您的 Trainer 模型类包装在另一个名为 TrainerViewModel 的类中,它可以像这样工作:

class TrainerViewModel
{
    private Trainer _trainer;

    public string ShortDescription
    {
        get
        {
            return _trainer.Description.ToString().Substring(0, 100);
        }
    }

    public TrainerViewModel(Trainer trainer)
    {
        _trainer = trainer;
    }
}

您将修改您的视图模型类以包含在视图中显示该数据所需的所有属性,因此名称为 ViewModel。

然后您将修改控制器以返回 TrainerViewModel 对象而不是 Trainer 对象,并将视图文件中的模型类型声明也更改为 TrainerViewModel

【讨论】:

  • +1 用于正确解释错误消息并提供比其他人描述的技巧更好的解决方案。
【解决方案3】:

我使用以下代码遇到了同样的错误消息:

@Html.DisplayFor(model => model.EndDate.Value.ToShortDateString())

我找到了good answer here

事实证明,您可以使用显示格式装饰模型中的属性,然后应用数据格式字符串。

请务必将以下库导入您的模型:

using System.ComponentModel.DataAnnotations;

【讨论】:

    【解决方案4】:

    HtmlHelper 上的 ...For 扩展方法(例如,DisplayForTextBoxForElementFor 等...)获取一个属性,没有别的。如果您没有属性,请使用非For 方法(例如,DisplayTextBoxElement 等...)。

    ...For 扩展方法提供了一种通过在属性后命名控件来简化回发的方法。这就是为什么它需要一个表达式而不仅仅是一个值。如果您对这种回发便利不感兴趣,请不要使用 ...For 方法。

    注意:你不应该在视图中调用ToString。这应该在视图模型内完成。我意识到很多演示项目将领域对象直接放入视图中。以我的经验,这很少奏效,因为它假定您不希望对域实体中的数据进行任何格式化。最佳实践是创建一个视图模型,将实体包装成可以直接被视图使用的东西。此视图模型中的大多数属性应该是已格式化的字符串或您为其创建了元素或显示模板的数据。

    【讨论】:

    • 感谢您提供有关使用 TextBox 而不是 TextBoxFor 的提示,以及最重要的是为什么它很重要以及在何处使用它们。赞赏。关于最后一段 - 在“应该在 mvc 中进行格式化的位置”上快速搜索 SO,揭示了在视图、模型、视图模型和服务层中执行的意见。只有控制器逃脱。我还是 mvc 的新手。
    • @DavidPierson,我尝试过到处格式化,发现在视图模型上将日期和货币值格式化为字符串效果最好。总是有纯粹主义者;我建议用一小粒盐来接受他们的建议。最终,做你认为对你和你的团队来说最干净、最简单的事情。根据我的经验,最好不要在视图中进行格式化,因为视图最好是声明性的。有一些方法可以以声明方式进行格式化,但我发现它们有局限性。
    【解决方案5】:

    使用@Html.Raw(item.Description.ToString().Substring(0,100))

    【讨论】:

      【解决方案6】:

      用模型填充服务层,然后将其发送到视图。 例如: ViewItem=ModelItem.ToString().Substring(0,100);

      【讨论】:

        【解决方案7】:

        将 DateTime 转换为 shortdate 的正确语法如下:

            @foreach (var item in Model)
            {
                @{var endDate= !item.EndDate.ToShortDateString();}
                @Html.DisplayFor(m => endDate,)
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-14
          • 1970-01-01
          • 1970-01-01
          • 2014-07-03
          • 1970-01-01
          • 2012-06-09
          相关资源
          最近更新 更多