Fehler "Vorlagen können nur mit Feldzugriff, Eigenschaftszugriff, eindimensionalem Array-Index oder benutzerdefinierten Indexerausdrücken mit einzelnen Parametern verwendet werden"

107

Warum erhalte ich den Fehler:

Vorlagen können nur mit Feldzugriff, Eigenschaftszugriff, eindimensionalem Array-Index oder benutzerdefinierten Indexerausdrücken mit einzelnen Parametern verwendet werden

bei diesem 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>

in der Zeile:

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

Aktualisieren:

Problem gelöst. Ich habe meinem Code hinzugefügt:

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

Mein neuer 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>
}

Dies ist nur eine Möglichkeit. Gibt es aus Neugier eine andere Lösung, um den Fehler zu beheben?

POIR
quelle
3
Ausgezeichnet! Ihre Lösung hat bei mir funktioniert und ist so einfach. Es wäre schön, wenn Sie Ihre Lösung stattdessen als Antwort als Update verwenden und akzeptieren könnten. da schauen wir uns meist akzeptierte antworten an.
Dush

Antworten:

101

Ich hatte das gleiche Problem mit so etwas

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

Ich habe das nur dadurch gelöst

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

Wenn Sie den Trick kennen, ist es einfach.

Der Unterschied besteht darin, dass ich im ersten Fall eine Methode als Parameter übergeben habe, während es im zweiten Fall ein Ausdruck ist.

Daniel
quelle
1
Perfekt!!! Vielen Dank für Ihre Antwort @ Daniel, ich habe stundenlang mit diesem S ***
gekämpft
75

Die Vorlage, auf die es sich bezieht, ist der HTML-Helfer DisplayFor.

DisplayFor erwartet einen Ausdruck, der den in der Fehlermeldung angegebenen Regeln entspricht.

Sie versuchen, eine auszuführende Methodenkette zu übergeben, die ihr nicht gefällt.

Dies ist ein perfektes Beispiel dafür, wo das MVVM-Muster (Model-View-ViewModel) nützlich ist.

Sie könnten Ihre TrainerModellklasse in eine andere Klasse einbinden TrainerViewModel, die ungefähr so ​​funktioniert:

class TrainerViewModel
{
    private Trainer _trainer;

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

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

Sie würden Ihre Ansichtsmodellklasse so ändern, dass sie alle Eigenschaften enthält, die zum Anzeigen dieser Daten in der Ansicht erforderlich sind, daher der Name ViewModel.

Dann würden Sie Ihren Controller so ändern, dass er ein TrainerViewModelObjekt anstelle eines TrainerObjekts zurückgibt, und Ihre Modelltypdeklaration in Ihrer Ansichtsdatei ebenfalls ändern TrainerViewModel.

Sean Airey
quelle
5
+1 für eine korrekte Interpretation der Fehlermeldung und für eine bessere Lösung als der von den anderen beschriebene Trick.
R. Schreurs
11

Ich bin auf ein ähnliches Problem mit derselben Fehlermeldung mit folgendem Code gestoßen:

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

Ich habe hier eine gute Antwort gefunden

Es stellt sich heraus, dass Sie die Eigenschaft in Ihrem Modell mit einem Anzeigeformat dekorieren und dann einen Datenformatstring anwenden können.

Stellen Sie sicher, dass Sie die folgende Bibliothek in Ihr Modell importieren:

using System.ComponentModel.DataAnnotations;
rauben
quelle
0

Füllen Sie die Service-Schicht mit dem Modell aus und senden Sie es an die Ansicht. Zum Beispiel: ViewItem = ModelItem.ToString (). Teilzeichenfolge (0,100);

RainyTears
quelle