“Os modelos podem ser usados ​​apenas com acesso a campo, acesso de propriedade, índice de matriz de dimensão única ou expressões de indexador personalizadas de parâmetro único”

107

Por que estou recebendo o erro:

Os modelos podem ser usados ​​apenas com acesso a campo, acesso de propriedade, índice de matriz de dimensão única ou expressões de indexador personalizadas de parâmetro único

neste código:

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

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

Atualizar:

Problema resolvido. Eu adicionei ao meu código:

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

Meu novo código:

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

Esta é apenas uma possibilidade. Só por curiosidade, existe outra solução para solucionar o erro?

POIR
fonte
3
Excelente! Sua solução funcionou para mim e é tão simples. Seria bom se você pudesse colocar sua solução como uma resposta em vez de atualização e aceitá-la. já que geralmente olhamos para as respostas aceitas.
Dush

Respostas:

101

Eu tive o mesmo problema com algo como

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

Eu resolvi isso apenas fazendo

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

Quando você conhece o truque, é simples.

A diferença é que, no primeiro caso, passei um método como parâmetro enquanto no segundo caso é uma expressão.

Daniel
fonte
1
Perfeito!!! Obrigado por sua resposta @Daniel, eu estava lutando com essa merda por horas
JSEvgeny
75

O modelo ao qual ele se refere é o auxiliar Html DisplayFor.

DisplayFor espera receber uma expressão que esteja em conformidade com as regras especificadas na mensagem de erro.

Você está tentando passar uma cadeia de métodos para ser executado e ele não gostou.

Este é um exemplo perfeito de onde o padrão MVVM (Model-View-ViewModel) é útil.

Você poderia encerrar sua Trainerclasse de modelo em outra classe chamada TrainerViewModelque poderia funcionar assim:

class TrainerViewModel
{
    private Trainer _trainer;

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

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

Você modificaria sua classe de modelo de exibição para conter todas as propriedades necessárias para exibir esses dados na exibição, daí o nome ViewModel.

Então você modificaria seu controlador para retornar um TrainerViewModelobjeto em vez de um Trainerobjeto e alteraria sua declaração de tipo de modelo em seu arquivo de visualização para TrainerViewModeltambém.

Sean Airey
fonte
5
1 para dar uma interpretação adequada da mensagem de erro e para uma solução melhor do que o truque descrito pelos outros.
R. Schreurs
11

Encontrei um problema semelhante com a mesma mensagem de erro usando o seguinte código:

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

Eu encontrei uma boa resposta aqui

Acontece que você pode decorar a propriedade em seu modelo com um formato de exibição e, em seguida, aplicar uma cadeia de formatos de dados.

Certifique-se de importar a seguinte biblioteca para o seu modelo:

using System.ComponentModel.DataAnnotations;
Roubar
fonte
0

Preencha a camada de serviço com o modelo e envie-o para a visualização. Por exemplo: ViewItem = ModelItem.ToString (). Substring (0,100);

RainyTears
fonte