Помилка "Шаблони можуть використовуватися лише з доступом до поля, доступом до властивостей, індексом одновимірного масиву або індивідуальними виразами індивідуального індексатора"


107

Чому я отримую помилку:

Шаблони можна використовувати лише з доступом до поля, доступом до властивостей, одновимірним індексом масиву або індивідуальними виразами індивідуального індексатора

за цим кодом:

@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>
}

Це лише одна можливість. Для цікавості є ще одне рішення для вирішення помилки?


3
Відмінно! Ваше рішення працювало на мене, і це так просто. Було б добре, якщо ви можете поставити своє рішення як відповідь замість оновлення та прийняти його. оскільки ми зазвичай дивимось на прийняті відповіді.
Даш

Відповіді:


101

У мене була така ж проблема з чимось подібним

@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")
}

Коли ти знаєш трюк, це просто.

Різниця полягає в тому, що в першому випадку я передав метод як параметр, тоді як у другому - це вираз.


1
Ідеально !!! Дякую за вашу відповідь @Daniel, я боровся з цим s *** годинами
JSEvgeny

75

Шаблон, на який він посилається, - це помічник Html DisplayFor.

DisplayFor розраховує отримати вираження, яке відповідає правилам, визначеним у повідомленні про помилку.

Ви намагаєтеся передати ланцюжок методів, який потрібно виконати, і це не подобається.

Це прекрасний приклад, коли модель MVVM (Model-View-ViewModel) стане в нагоді.

Ви можете перетворити свій 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.


5
+1 за правильне тлумачення повідомлення про помилку та для кращого рішення, ніж хитрість, описану іншими.
Р. Шреурс

11

Я зіткнувся з подібною проблемою з тим же повідомленням про помилку, використовуючи наступний код:

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

Тут я знайшов хорошу відповідь

Виявляється, ви можете прикрасити властивість у вашій моделі за допомогою дисплейного формату, а потім застосувати рядок даних.

Не забудьте імпортувати таку вкладку у вашу модель:

using System.ComponentModel.DataAnnotations;

0

Заповніть сервісний шар моделлю та відправте його на вигляд. Наприклад: ViewItem = ModelItem.ToString (). Підрядка (0,100);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.