You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core MVC使用ExpandoObject传多模型分部视图类型报错

异常原因

异常由两个问题直接导致:

  • 分部视图传参规则:在视图中调用<partial>标签时,如果不显式指定model参数,框架会自动将当前视图的母模型作为参数传入分部视图。当前Details视图的母模型是System.Dynamic.ExpandoObject类型,而Comments分部视图声明的强类型为MyProject.Models.Comments,类型不匹配直接抛出InvalidOperationException。
  • 现有控制器代码未向动态模型中添加Comments相关数据,即便传参逻辑正确,也拿不到对应的模型对象。
正确实现方案

第一步:修改控制器Details方法,补充Comments数据

如果分部视图用于提交评论,传入绑定了当前食谱ID的空Comments实例即可;如果需要展示已有评论,额外查询对应食谱的评论列表赋值到动态模型:

public ViewResult Details(int id)
{
    dynamic mymodel = new ExpandoObject();
    var det = _recepie.Recepies.Find(id);
    var user = _usr.Users.Find(det.UserId);
    // 初始化评论对象,绑定当前食谱ID
    var newComment = new MyProject.Models.Comments() { RecepieId = id };
    // 如需展示已有评论列表,解开下面注释
    // var commentList = _cmnt.Comments.Where(c => c.RecepieId == id).ToList();
    
    mymodel.Recepie = det;
    mymodel.User = user;
    mymodel.Comment = newComment;
    // mymodel.CommentList = commentList;
    return View(mymodel);
}

第二步:修改Details视图的分部视图调用代码

调用partial标签时显式传入Comments类型的模型,禁止框架默认传递ExpandoObject母模型:

@model dynamic
@{
    Layout="_RecepieLayout";
}

<div class="row">
        <div class="col-md-5 col-sm-12" >
            <img src="~/Images/fishsoup.jpg" style="max-width:500px;"/>
        </div>
        <div class="col-md-7">
            <h1>
                @Model.Recepie.Category
            </h1>
            <p>
                @Model.Recepie.name
            </p>
            <p>
                创建者:@Model.User.name
            </p>
            <p>
                @Model.Recepie.Description
            </p>
            <p>
                @Model.Recepie.Ingredients
            </p>
        </div>
</div>

@* 关键修改:显式指定传入分部视图的模型 *@
<partial name="Comments" model="Model.Comment" />
@* 如果要渲染评论列表,将分部视图@model改为IEnumerable<MyProject.Models.Comments>,此处传Model.CommentList即可 *@

可选优化:使用强类型视图模型替代ExpandoObject

ExpandoObject属于动态类型,编译阶段无法检查类型错误,线上更容易出问题,更规范的做法是自定义专用视图模型:

  1. 新建视图模型类
// 路径建议:ViewModels/RecepieDetailsViewModel.cs
namespace MyProject.ViewModels
{
    public class RecepieDetailsViewModel
    {
        public Recepie Recepie { get; set; }
        public User User { get; set; }
        public Comments Comment { get; set; }
        public IEnumerable<Comments> CommentList { get; set; }
    }
}
  1. 控制器改用强类型视图模型
public ViewResult Details(int id)
{
    var det = _recepie.Recepies.Find(id);
    var user = _usr.Users.Find(det.UserId);
    var viewModel = new RecepieDetailsViewModel
    {
        Recepie = det,
        User = user,
        Comment = new Comments { RecepieId = id },
        CommentList = _cmnt.Comments.Where(c => c.RecepieId == id).ToList()
    };
    return View(viewModel);
}
  1. Details视图顶部修改模型声明,其余代码无需变动
@model MyProject.ViewModels.RecepieDetailsViewModel

内容的提问来源于stack exchange,提问作者ARSH AHMAD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 21:57:23