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

ASP.NET Core 6 Web API中IFormFile参数引发NotSupportedException问题

问题原因分析

异常的核心原因是:Dapper不识别EF Core的[NotMapped]特性。虽然你在模型的imageFile属性上加了[NotMapped],但这个特性仅对EF Core生效,Dapper会遍历对象的所有公共属性尝试转换为SQL参数。而IFormFile是ASP.NET Core用于处理文件上传的类型,无法被转换为数据库可接受的参数类型,因此抛出System.NotSupportedException。

另外,你在SaveInstitute方法中创建的values对象虽然复制了部分属性,但它本质还是InstituteInfo类型,仍然包含imageFile属性(即使未赋值,属性本身依然存在),Dapper依然会尝试处理这个属性。

解决方法

方法1:使用匿名类型传递参数(最简单直接)

直接在Dapper的Execute方法中使用匿名类型,只传入存储过程需要的参数,完全避开imageFile属性:

public int SaveInstitute(InstituteInfo info, string connectionID = "Default")
{
    // 仅传递存储过程需要的参数,排除imageFile
    var parameters = new 
    {
        info.ID,
        info.Institute_Name,
        info.Office_No,
        info.Cell_No,
        info.email,
        info.Institute_address,
        info.monogramPath
    };

    using IDbConnection connection = new SqlConnection(_config.GetConnectionString(connectionID));
    return connection.Execute("sp_SaveNewInstitute", parameters, commandType: CommandType.StoredProcedure);
}

方法2:创建数据库操作专用DTO

定义一个仅包含数据库字段的DTO类,避免业务模型和数据库模型耦合:

// 数据库操作专用DTO
public class InstituteInfoDbDto
{
    public int? ID { get; set; } = 1;
    public string Institute_Name { get; set; } = "";
    public string Office_No { get; set; } = "";
    public string Cell_No { get; set; } = "";
    public string email { get; set; } = "";
    public string Institute_address { get; set; } = "";
    public string monogramPath { get; set; } = "";
}

修改数据访问方法:

public int SaveInstitute(InstituteInfoDbDto infoDto, string connectionID = "Default")
{
    using IDbConnection connection = new SqlConnection(_config.GetConnectionString(connectionID));
    return connection.Execute("sp_SaveNewInstitute", infoDto, commandType: CommandType.StoredProcedure);
}

控制器中转换模型:

// 在Post方法中调用前转换
var dbDto = new InstituteInfoDbDto
{
    ID = Newinfo.ID,
    Institute_Name = Newinfo.Institute_Name,
    Office_No = Newinfo.Office_No,
    Cell_No = Newinfo.Cell_No,
    email = Newinfo.email,
    Institute_address = Newinfo.Institute_address,
    monogramPath = Newinfo.monogramPath
};
var result = _sqlDataAccess.SaveInstitute(dbDto);

方法3:手动构建DynamicParameters(最灵活)

使用Dapper的DynamicParameters类,逐个添加需要的参数,精确控制参数列表:

public int SaveInstitute(InstituteInfo info, string connectionID = "Default")
{
    var parameters = new DynamicParameters();
    parameters.Add("@ID", info.ID);
    parameters.Add("@Institute_Name", info.Institute_Name);
    parameters.Add("@Office_No", info.Office_No);
    parameters.Add("@Cell_No", info.Cell_No);
    parameters.Add("@email", info.email);
    parameters.Add("@Institute_address", info.Institute_address);
    parameters.Add("@monogramPath", info.monogramPath);

    using IDbConnection connection = new SqlConnection(_config.GetConnectionString(connectionID));
    return connection.Execute("sp_SaveNewInstitute", parameters, commandType: CommandType.StoredProcedure);
}
额外注意点
  • 检查存储过程sp_SaveNewInstitute的参数列表,确保传递的参数和存储过程定义的参数名称、类型完全匹配,避免因参数不匹配导致其他异常。
  • 控制器的Post方法当前返回void,但代码中调用了Ok(result)不会生效,建议修改返回类型为IActionResult:
[Route("Institute/AddNew")]
[HttpPost]
public IActionResult Post([FromForm] InstituteInfo Newinfo)
{
    try
    {
        var fileResult = _fileService.SaveImage(Newinfo.imageFile, 2);
        if(fileResult != null) 
        {
            if (fileResult.Item1 == 1)
            {
                Newinfo.monogramPath = fileResult.Item2;
            }
            var result = _sqlDataAccess.SaveInstitute(Newinfo);
            return Ok(result);
        }
        return BadRequest("文件保存失败");
    }
    catch (Exception ex)
    {
        return StatusCode(500, ex.Message);
    }
}

内容的提问来源于stack exchange,提问作者Khuram Jan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:37:46