.NET Core MVC 渲染多条记录报错 foreach statement cannot operate on variables of type 'object'

更新日期: 2024-10-07 阅读次数: 297 字数: 455 分类: Windows

借实现我的 Emoji 字典工具 📖 的机会,了解了一下 .NET Core MVC 中使用 EF Core 及在 controll view 间传递变量的方式。

果然遇到了类型的问题。

foreach statement cannot operate on variables of type 'object'

问题代码

controller:

[HttpGet]
public async Task<IActionResult> Index()
{
    var items = await _context.Items.ToListAsync();
    ViewData["items"] = items;

    return View();
}

cshtml:

@foreach (var item in ViewData["items"])
{
    <div class="col-md-2">
        <h5>@item.content</h5>
        <p>@item.name</p>
    </div>
}

报错:

foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public instance or extension definition for 'GetEnumerator'CS1579

官方的做法

https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/adding-model?view=aspnetcore-8.0&tabs=visual-studio

这里顺便给出了解释

Earlier in this tutorial, you saw how a controller can pass data or objects to a view using the ViewData dictionary. The ViewData dictionary is a dynamic object that provides a convenient late-bound way to pass information to a view.

MVC provides the ability to pass strongly typed model objects to a view. This strongly typed approach enables compile time code checking. The scaffolding mechanism passed a strongly typed model in the MoviesController class and views.

也就是说,如果使用 ViewData 则传递的是一个动态对象,即 object 类型。怪不得提示说 foreach 不支持 object 类型。

如果需要强类型,就得

public async Task<IActionResult> Index()
{
    return View(await _context.Item.ToListAsync());
}

cshtml:

@model IEnumerable<Item>

@foreach (var item in Model) {
   <tr>
       ...
   </tr>
}

model / Model 的区别

  • The model is directive that is used to declare the type of the ViewModel
  • The Model is a variable used to access the ViewModel. The type of Model is declared by the keyword @model.

多个变量呢?

Since there is only one Model Property, you can have only one ViewModel per View.

一个 View 只能使用一个 Strongly Typed View。。。

  • 定义一个新的 class,里面每个字段对应一个需要传递的变量。参考 https://stackoverflow.com/questions/17334339/two-models-in-a-view-with-foreach
  • foreach 的使用强类型传递,其他的使用 ViewData 传递。但总感觉这个方式欠妥,且不方便扩展。
  • 是否可以在 cshtml 中强制类型转换?可以,如:(IEnumerable)ViewData["items"]。参考:https://stackoverflow.com/questions/37688670/loop-through-multiple-models-in-mvc-5-using-razor

参考

  • https://www.tektutorialshub.com/asp-net-core/asp-net-core-passing-data-from-controller-to-view/

微信关注我哦 👍

大象工具微信公众号

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式

tags: dotnet