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

如何在POST请求中使用Entity Framework自动生成的实体类型?

问题分析与解决方案

首先得明确你遇到的核心问题:不是[BindNever]的作用没生效,而是JSON里传递的CharacteristicId和CommodityId是字符串类型(比如"test1"),但你的CommoditiesCharacteristics类里这两个属性是int类型,模型绑定阶段无法完成字符串到整数的转换,才导致的执行失败。[BindNever]是告诉模型绑定器跳过某些属性的绑定,但你JSON里根本没传Id、Characteristic、Commodity这些属性,所以加这个特性完全没触及问题根源。

接下来给你两种可行的解决思路,你可以根据场景选择:


思路1:调整JSON数据格式(最简单,若能控制输入源)

如果JSON的生成方可以修改,直接把CharacteristicId和CommodityId的值改成合法的整数,比如:

{"Type":{"CharacteristicId":1,"CommodityId":2},...}

这样模型绑定就能顺利把JSON值映射到int类型属性上,不需要修改任何后端代码。


思路2:用DTO(数据传输对象)接收请求(推荐,符合最佳实践)

如果无法修改JSON的输入格式,最规范的做法是新建一个专门用于接收请求的DTO类,和你的EF实体类解耦,避免污染数据库实体。

步骤1:定义DTO类

// 单个钻头特征的DTO
public class DrillCharacteristicDto
{
    public string CharacteristicId { get; set; }
    public string CommodityId { get; set; }
}

// 整个钻头请求的DTO
public class DrillRequestDto
{
    public DrillCharacteristicDto Type { get; set; }
    public DrillCharacteristicDto ShankType { get; set; }
    public DrillCharacteristicDto SharpeningAngel { get; set; }
    public DrillCharacteristicDto SharpeningDirection { get; set; }
    public DrillCharacteristicDto MaterialFor { get; set; }
    public DrillCharacteristicDto WorkingLength { get; set; }
    public DrillCharacteristicDto Length { get; set; }
    public DrillCharacteristicDto Diameter { get; set; }
}

步骤2:修改控制器方法接收DTO并映射到实体

[HttpPost]
[Route("SaveDrill")]
public IActionResult SaveDrill(DrillRequestDto drillDto)
{
    // 先做数据验证:把字符串转成合法整数
    if (!int.TryParse(drillDto.Type.CharacteristicId, out int charId) 
        || !int.TryParse(drillDto.Type.CommodityId, out int commId))
    {
        return BadRequest("CharacteristicId和CommodityId必须是合法的整数");
    }

    // 将DTO转换为EF实体
    var typeChar = new CommoditiesCharacteristics
    {
        CharacteristicId = charId,
        CommodityId = commId
    };
    _toolStoreContext.CommoditiesCharacteristics.Add(typeChar);

    // 其他属性同理完成转换与添加
    // ...

    _toolStoreContext.SaveChanges();
    return Ok();
}

这种方式的好处是:实体类只负责数据库映射,DTO负责接收外部请求,两者职责清晰,后续不管是请求格式变化还是数据库结构调整,都不会互相影响。


不推荐的思路:修改实体类添加辅助属性

如果你不想新建DTO,也可以在CommoditiesCharacteristics里添加字符串类型的辅助属性,用[NotMapped]标记(告诉EF不要把这个属性映射到数据库列),再通过属性的get/set方法完成类型转换:

public partial class CommoditiesCharacteristics
{
    public int Id { get; set; }
    public int CharacteristicId { get; set; }
    public int CommodityId { get; set; }
    public virtual DrillBitsCharacteristics Characteristic { get; set; }
    public virtual Commodities Commodity { get; set; }

    [NotMapped]
    [JsonPropertyName("CharacteristicId")]
    public string CharacteristicIdStr 
    { 
        get => CharacteristicId.ToString(); 
        set => int.TryParse(value, out CharacteristicId); 
    }

    [NotMapped]
    [JsonPropertyName("CommodityId")]
    public string CommodityIdStr 
    { 
        get => CommodityId.ToString(); 
        set => int.TryParse(value, out CommodityId); 
    }
}

但这种做法会把请求处理的逻辑塞进数据库实体类里,违反了单一职责原则,后续维护起来会很麻烦,所以不建议使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:19:10