web-dev-qa-db-fra.com

Erreur "Les modèles ne peuvent être utilisés qu'avec les accès aux champs, aux propriétés, les index de tableaux à une dimension ou les indexeurs personnalisés à un seul paramètre"

Pourquoi est-ce que je reçois l'erreur?

Les modèles ne peuvent être utilisés qu'avec un accès de champ, un accès de propriété, un index de tableau à une dimension ou des expressions d'indexeur personnalisées à un seul paramètre

à ce code:

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

à la ligne:

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

Mise à jour:

Problème résolu. J'ai ajouté à mon code:

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

Mon nouveau code:

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

Ce n'est qu'une possibilité. Juste par curiosité, existe-t-il une autre solution pour résoudre l'erreur?

88
POIR

J'ai eu le même problème avec quelque chose comme

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

J'ai résolu ça juste en faisant

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

Quand vous connaissez le truc, c'est simple.

La différence est que, dans le premier cas, j'ai passé une méthode en tant que paramètre alors que dans le second cas, il s'agit d'une expression.

79
Daniel

Le modèle auquel il fait référence est l'assistant HTML DisplayFor.

DisplayFor s'attend à recevoir une expression conforme aux règles spécifiées dans le message d'erreur.

Vous essayez de transmettre une chaîne de méthodes à exécuter et elle ne l’aime pas.

Ceci est un exemple parfait de l’utilisation du modèle MVVM (Model-View-ViewModel).

Vous pouvez envelopper votre classe de modèle Trainer dans une autre classe appelée TrainerViewModel qui pourrait fonctionner de la manière suivante:

class TrainerViewModel
{
    private Trainer _trainer;

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

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

Vous modifieriez votre classe de modèle de vue pour contenir toutes les propriétés nécessaires pour afficher ces données dans la vue, d'où le nom ViewModel.

Vous pouvez ensuite modifier votre contrôleur pour renvoyer un objet TrainerViewModel plutôt qu'un objet Trainer et modifier la déclaration de type de modèle de votre fichier de vue en TrainerViewModel.

67
Sean Airey

J'ai rencontré un problème similaire avec le même message d'erreur en utilisant le code suivant:

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

J'ai trouvé un bonne réponse ici

Il s'avère que vous pouvez décorer la propriété dans votre modèle avec un displayformat puis appliquer un dataformatstring.

Assurez-vous d'importer la bibliothèque suivante dans votre modèle:

using System.ComponentModel.DataAnnotations;
7
Rob

Remplissez la couche de service avec le modèle, puis envoyez-la à la vue. Par exemple: ViewItem = ModelItem.ToString (). Substring (0,100);

0
MSM19