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

文章目录

    借实现我的 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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式