Błąd „Szablony mogą być używane tylko w przypadku dostępu do pól, dostępu do właściwości, indeksu tablicy jednowymiarowej lub niestandardowych wyrażeń indeksatora z jednym parametrem”

107

Dlaczego otrzymuję błąd:

Szablony mogą być używane tylko z dostępem do pola, dostępem do właściwości, indeksem tablicy jednowymiarowej lub niestandardowymi wyrażeniami indeksatora z jednym parametrem

pod tym kodem:

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

na linii:

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

Aktualizacja:

Problem rozwiązany. Dodałem do mojego kodu:

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

Mój nowy kod:

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

To tylko jedna możliwość. Czy dla ciekawości istnieje inne rozwiązanie problemu?

POIR
źródło
3
Doskonały! Twoje rozwiązanie zadziałało dla mnie i jest takie proste. Byłoby miło, gdybyś zamiast tego mógł podać swoje rozwiązanie jako aktualizację i zaakceptować je. ponieważ zwykle patrzymy na zaakceptowane odpowiedzi.
Dush

Odpowiedzi:

101

Miałem ten sam problem z czymś takim

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

Rozwiązałem to po prostu robiąc

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

Kiedy znasz sztuczkę, to jest proste.

Różnica polega na tym, że w pierwszym przypadku przekazałem metodę jako parametr, podczas gdy w drugim przypadku jest to wyrażenie.

Daniel
źródło
1
Idealny!!! Dzięki za twoją odpowiedź @Daniel, walczyłem z tym
gównem
75

Szablon, do którego się odnosi, jest pomocnikiem HTML DisplayFor.

DisplayFor oczekuje, że zostanie podane wyrażenie zgodne z regułami określonymi w komunikacie o błędzie.

Próbujesz przekazać łańcuch metod do wykonania i to się nie podoba.

Jest to doskonały przykład tego, gdzie przydaje się wzorzec MVVM (Model-View-ViewModel).

Możesz zawrzeć swoją Trainerklasę modelu w innej klasie o nazwie, TrainerViewModelktóra może działać mniej więcej tak:

class TrainerViewModel
{
    private Trainer _trainer;

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

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

Należy zmodyfikować klasę modelu widoku, aby zawierała wszystkie właściwości potrzebne do wyświetlenia tych danych w widoku, stąd nazwa ViewModel.

Następnie zmodyfikowałbyś kontroler, aby zwracał TrainerViewModelobiekt, a nie Trainerobiekt, i zmienić deklarację typu modelu w pliku widoku na TrainerViewModelrównież.

Sean Airey
źródło
5
+1 za podanie właściwej interpretacji komunikatu o błędzie i lepsze rozwiązanie niż sztuczka opisana przez innych.
R. Schreurs,
11

Napotkałem podobny problem z tym samym komunikatem o błędzie przy użyciu następującego kodu:

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

Tu znalazłem dobrą odpowiedź

Okazuje się, że możesz udekorować właściwość w swoim modelu formatem wyświetlania, a następnie zastosować łańcuch danych.

Pamiętaj, aby zaimportować następującą bibliotekę do swojego modelu:

using System.ComponentModel.DataAnnotations;
Obrabować
źródło
0

Wypełnij warstwę usługową modelem, a następnie wyślij go do widoku. Na przykład: ViewItem = ModelItem.ToString (). Substring (0,100);

Rainy Tears
źródło