c# - remarks - ''objeto'' no contiene una definición para ''X''
remarks c# (4)
Está utilizando un objeto anónimo aquí:
ViewBag.Languages = db.Languages
.Select(x => new { x.Name, x.EnglishName, x.Id })
.ToList();
Los objetos anónimos son emitidos como internal
por el compilador. Las vistas de Razor se compilan automáticamente en un ensamblaje separado por el tiempo de ejecución de ASP.NET. Esto significa que no puede acceder a ningún objeto anónimo generado en sus controladores.
Para solucionar su problema, puede definir un modelo de vista:
public class LanguageViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string EnglishName { get; set; }
}
y luego en su controlador use este modelo de vista:
ViewBag.Languages = db.Languages
.Select(x => new LanguageViewModel
{
Name = x.Name,
EnglishName = x.EnglishName,
Id = x.Id
})
.ToList();
Y ahora que tiene un modelo de vista, la próxima mejora de su código es, por supuesto, deshacerse de esta basura de ViewBag
que estoy harto de ver y simplemente usar modelos de vista y mecanografía fuerte:
public ActionResult Foo()
{
var model = db
.Languages
.Select(x => new LanguageViewModel
{
Name = x.Name,
EnglishName = x.EnglishName,
Id = x.Id
})
.ToList();
return View(model);
}
y luego, por supuesto, tener una vista fuertemente tipada:
@model IEnumerable<LanguageViewModel>
@Html.DisplayForModel()
y luego defina la plantilla de visualización correspondiente que será renderizada automáticamente por el motor ASP.NET MVC para cada elemento del modelo de vista, de modo que ni siquiera necesite escribir un solo foreach en sus vistas ( ~/Views/Shared/DisplayTemplates/LanguageViewModel.cshtml
):
@model LanguageViewModel
... generate the image or whatever you was attempting to do in the first place
Tuve este problema una vez y no lo resolví. Tengo una lista (generada en un controlador MVC3):
ViewBag.Languages = db.Languages
.Select(x => new { x.Name, x.EnglishName, x.Id })
.ToList();
y en mi página (Razor) trato de iterar a través de él:
foreach (var o in ViewBag.Languages)
{
string img = "Lang/" + o.EnglishName + ".png";
@* work *@
}
pero la referencia a o.EnglishName
falla con el error:
''objeto'' no contiene una definición para ''EnglishName''
aunque lo curioso es que si escribo en la ventana Inmediato (mientras se depura):
o { Name = བོད་སྐད་, EnglishName = Tibetan, Id = 31 } EnglishName: "Tibetan" Id: 31 Name: "བོད་སྐད་"
así que obviamente el campo está ahí. ¿Cuál es mi problema aquí?
Esto me estaba distrayendo hasta que revisé mi código y encontré esto:
class AdsViewModel
{
public int Id { get; set; }
public string City { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
public string UserEmail { get; set; }
public string ContactPhone { get; set; }
public string ShortTitle { get; set; }
public string AdUrl { get; set; }
}
Cambiándolo a:
public class AdsViewModel
Arreglado.
También puede suceder si el nombre de su clase no coincide con el nombre del archivo (sé que es estúpido, pero podría ayudarlo)
Utilice ViewData en lugar de ViewBag.
ViewData["Lang"] = db.Languages
.Select(x => new { x.Name, x.EnglishName, x.Id })
.ToList();
Entonces
foreach (var o in (dynamic) ViewData["Lang"])
{
string img = "Lang/" + o.EnglishName + ".png";
@* work *@
}