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

解决ViewModel InvalidOperationException模型类型不匹配报错

问题描述

我正在开发一个产品竞赛提交网站,购买产品的用户可输入序列号参与竞赛。用户提交的数据及序列号会被标记为“已使用序列号”,要求页面仅显示用户一次并展示其提交次数,且每个用户每个产品最多可参与两次。

我创建了OverviewModel和OverviewContestModel两个模型存储表格数据,并创建包含二者的OverviewContestViewModel。在视图顶部声明@model UmbracoAcmeMia.ViewModels.OverviewContestViewModel后,却出现模型类型不匹配错误。作为C#和.NET新手,我尝试修改@model路径、设置断点均未解决问题。


视图代码

@model UmbracoAcmeMia.ViewModels.OverviewContestViewModel
@{ ViewData["Title"] = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; }
<!-- 剩余视图代码略 -->

控制器代码

public IActionResult Index()
{
    var usedSerialNumber = _context.UsedSerialNumbers.ToList();
    var userList = _context.UsedSerialNumbers.Include(x => x.Users).Distinct();
    var OverviewContestViewModel = userList.Select(x => new OverviewContestModel()
    {
        FirsteName = x.Users.FirstName,
        LastName = x.Users.LastName,
        Email = x.Users.Email,
        Birthday = x.Users.Birthday,
        UsedCount = usedSerialNumber.Where(y => y.Value == x.Value).Count(),
    });
    return View(OverviewContestViewModel);
}

模型及ViewModel代码

// OverviewModel
public class OverviewModel
{ public DateTime UsedDate { get; set; } /* 其他属性略 */ }
// OverviewContestModel
public class OverviewContestModel
{ public string FirsteName { get; set; } /* 其他属性略 */ }
// OverviewContestViewModel
public class OverviewContestViewModel
{ public OverviewModel OverviewModel { get; set; } public OverviewContestModel OverviewContestModel { get; set; } }

错误信息

InvalidOperationException: 传入ViewDataDictionary的模型项类型为'Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[UmbracoAcmeMia.Models.OverviewContestModel]',但该ViewDataDictionary实例要求的模型项类型为'UmbracoAcmeMia.ViewModels.OverviewContestViewModel'。


问题分析与修复方案

核心问题

控制器返回的是IQueryable<OverviewContestModel>类型的用户集合,但视图期望接收的是单个OverviewContestViewModel对象,两者类型完全不匹配,直接导致报错。此外代码还存在两个额外问题:

  1. 变量名OverviewContestViewModel与类名重名,不符合C#小驼峰命名规范
  2. 用Distinct()无法正确按用户去重,因为UsedSerialNumbers是序列号记录,每条对应一个用户,直接去重不会按用户分组统计

修复步骤

1. 调整ViewModel结构

因为页面要展示多个用户的列表,ViewModel需要包含OverviewContestModel的集合,修改后的ViewModel:

public class OverviewContestViewModel
{
    // 若需要OverviewModel的数据可保留,否则可移除
    public OverviewModel OverviewModel { get; set; }
    // 存储用户列表及提交次数
    public List<OverviewContestModel> UserContestList { get; set; }
}

2. 修正控制器代码

按用户ID分组统计提交次数,再封装到ViewModel中返回:

public IActionResult Index()
{
    // 按用户分组,统计每个用户的提交次数
    var userContestData = _context.UsedSerialNumbers
        .Include(x => x.Users)
        .GroupBy(x => x.Users.Id) // 按用户ID分组确保去重
        .Select(g => new OverviewContestModel()
        {
            FirstName = g.First().Users.FirstName, // 修正拼写错误FirsteName→FirstName
            LastName = g.First().Users.LastName,
            Email = g.First().Users.Email,
            Birthday = g.First().Users.Birthday,
            UsedCount = g.Count() // 直接统计分组内的记录数即提交次数
        })
        .ToList();

    // 实例化ViewModel并赋值
    var viewModel = new OverviewContestViewModel()
    {
        UserContestList = userContestData
        // 若需赋值OverviewModel,可在此添加查询逻辑
        // OverviewModel = _context.Overviews.FirstOrDefault()
    };

    return View(viewModel);
}

3. 更新视图代码

修改模型声明并遍历用户列表展示数据:

@model UmbracoAcmeMia.ViewModels.OverviewContestViewModel
@{ ViewData["Title"] = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; }

<!-- 展示用户列表及提交次数 -->
<table class="table">
    <thead>
        <tr>
            <th>姓名</th>
            <th>邮箱</th>
            <th>生日</th>
            <th>提交次数</th>
        </tr>
    </thead>
    <tbody>
        @foreach(var user in Model.UserContestList)
        {
            <tr>
                <td>@user.FirstName @user.LastName</td>
                <td>@user.Email</td>
                <td>@user.Birthday.ToString("yyyy-MM-dd")</td>
                <td>@user.UsedCount</td>
            </tr>
        }
    </tbody>
</table>

额外优化建议

  • 修复OverviewContestModel中的拼写错误:FirsteName改为FirstName
  • 确保UsedSerialNumbers与Users的EF关联关系配置正确,避免Include失效
  • 在提交序列号时添加验证逻辑,查询当前用户对应产品的提交次数是否小于2,实现“每个用户每个产品最多参与两次”的要求

内容的提问来源于stack exchange,提问作者Maria Gath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:56:07