Error "Las plantillas solo se pueden usar con acceso a campo, acceso a propiedad, índice de matriz de una dimensión o expresiones de indexación personalizadas de un solo parámetro"

107

¿Por qué recibo el error?

Las plantillas solo se pueden usar con acceso a campo, acceso a propiedad, índice de matriz de una dimensión o expresiones de indexación personalizadas de un solo parámetro

en este 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>

en línea:

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

Actualizar:

Problema resuelto. Agregué a mi código:

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

Mi nuevo 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>
}

Ésta es solo una posibilidad. Solo por curiosidad, ¿hay otra solución para solucionar el error?

POIR
fuente
3
¡Excelente! Tu solución funcionó para mí y es muy simple. Sería bueno si pudiera poner su solución como una respuesta en lugar de una actualización y aceptarla. ya que generalmente miramos las respuestas aceptadas.
Dush

Respuestas:

101

Tuve el mismo problema con algo como

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

Resolví esto simplemente haciendo

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

Cuando conoces el truco, es simple.

La diferencia es que, en el primer caso, pasé un método como parámetro mientras que en el segundo caso, es una expresión.

Daniel
fuente
1
¡¡¡Perfecto!!! Gracias por tu respuesta @Daniel, estuve luchando con esta
mierda
75

La plantilla a la que se refiere es el asistente Html DisplayFor.

DisplayFor espera recibir una expresión que se ajuste a las reglas especificadas en el mensaje de error.

Está intentando pasar una cadena de métodos para que se ejecute y no le gusta.

Este es un ejemplo perfecto de dónde resulta útil el patrón MVVM (Model-View-ViewModel).

Podría terminar su Trainerclase modelo en otra clase llamada TrainerViewModelque podría funcionar de esta manera:

class TrainerViewModel
{
    private Trainer _trainer;

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

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

Modificaría su clase de modelo de vista para que contenga todas las propiedades necesarias para mostrar esos datos en la vista, de ahí el nombre ViewModel.

Luego, modificaría su controlador para devolver un TrainerViewModelobjeto en lugar de un Trainerobjeto y cambiaría su declaración de tipo de modelo en su archivo de vista TrainerViewModeltambién.

Sean Airey
fuente
5
+1 por dar una interpretación adecuada del mensaje de error y por una mejor solución que el truco descrito por los demás.
R. Schreurs
11

Me encontré con un problema similar con el mismo mensaje de error usando el siguiente código:

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

Encontré una buena respuesta aquí

Resulta que puede decorar la propiedad en su modelo con un formato de visualización y luego aplicar una cadena de formato de datos.

Asegúrese de importar la siguiente biblioteca a su modelo:

using System.ComponentModel.DataAnnotations;
Robar
fuente
0

Complete la capa de servicio con el modelo y luego envíelo a la vista. Por ejemplo: ViewItem = ModelItem.ToString (). Substring (0,100);

Lágrimas de lluvia
fuente