c# - mvc - "Las plantillas solo se pueden usar con acceso de campo, acceso a propiedades, índice de matriz de una dimensión o error de expresiones de indexadores personalizados de parámetro único"
variables de session c# mvc 4 (3)
¿Por qué estoy recibiendo el error?
Las plantillas solo se pueden usar con acceso de campo, acceso a propiedades, índice de matriz de una dimensión o expresiones de indizador personalizadas de parámetro único
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>
}
Esta es solo una posibilidad. Solo por curiosidad, ¿hay alguna otra solución para resolver el error?
La plantilla a la que hace referencia es la helper Html DisplayFor
.
DisplayFor espera recibir una expresión que cumpla con las reglas especificadas en el mensaje de error.
Está intentando pasar una cadena de método para ejecutar y no le gusta.
Este es un ejemplo perfecto de dónde el patrón MVVM (Model-View-ViewModel) es útil.
Puede TrainerViewModel
su clase de modelo Trainer
en otra clase llamada TrainerViewModel
que podría funcionar de la siguiente 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 objeto TrainerViewModel
lugar de un objeto Trainer
y también cambiaría su declaración de tipo de modelo en su archivo de vista a TrainerViewModel
.
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 pantalla y luego aplicar una cadena de formato de datos.
Asegúrese de importar la siguiente lib en su modelo:
using System.ComponentModel.DataAnnotations;
Tuve el mismo problema con algo así como
@foreach (var item in Model)
{
@Html.DisplayFor(m => !item.IsIdle, "BoolIcon")
}
Lo resolví solo 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.