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

ASP.NET Core 6.0 Web API:Get传字符串返回对象报400验证错误

ASP.NET Core 6.0 Web API 400验证错误排查与解决

问题场景

在ASP.NET Core 6.0 Web API中,尝试通过Get方法传递课程缩写(sigla)字符串获取对应Curso对象时,请求返回400验证错误,提示'id字段值"enc"无效'。

错误信息

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-8db2fbce7dfcc684ce94f0e8b4baaab1-67a764080f12fca7-00",
"errors": {
    "id": [
        "The value 'enc' is not valid."
    ]
}

相关代码

控制器Get方法

// GET: api/Cursos/LES
[HttpGet("cursos/{sigla}")]
public async Task<ActionResult<Curso>> GetCurso(string sigla)
{
    if (_context.Cursos == null)
    {
        return NotFound();
    }
    var curso = await _context.Cursos.Include(f => f.Sigla).
    FirstOrDefaultAsync(a => a.Sigla == sigla);

    if (curso == null)
    {
        return NotFound();
    }

    return curso;
}

Curso类定义

namespace UniversidadeApi.Models
{
    public class Curso
    {
        public long Id { get; set; }
        public string? Sigla { get; set; }
        public string? Nome { get; set; }
    }
}

测试场景

请求URL:

  • https://localhost:7225/api/cursos/enc
  • https://localhost:7225/api/cursos/ENC
  • https://localhost:7225/api/cursos/"ENC"

已通过Post创建的对象:

{
    "id": 1,
    "sigla": "ENC",
    "nome": "Engenharia da Computação"
}

问题原因与解决方案

原因分析

控制器中大概率存在默认的根据ID查询的Get方法(如[HttpGet("{id}")]),当请求api/cursos/enc时,ASP.NET Core的路由匹配机制会优先尝试将路径中的enc绑定到long类型的id参数,导致类型转换失败,触发验证错误。

解决方法

方法1:修改路由路径,避免冲突

将自定义Get方法的路由改为更明确的路径,同时调整方法名区分逻辑:

[HttpGet("by-sigla/{sigla}")]
public async Task<ActionResult<Curso>> GetCursoBySigla(string sigla)
{
    if (_context.Cursos == null)
    {
        return NotFound();
    }
    var curso = await _context.Cursos.FirstOrDefaultAsync(a => a.Sigla == sigla);

    if (curso == null)
    {
        return NotFound();
    }

    return curso;
}

此时请求URL改为:https://localhost:7225/api/cursos/by-sigla/ENC

方法2:添加路由约束,明确参数类型

在路由中给sigla参数添加字符串类型约束,告诉框架该参数是字符串,避免和id的long类型路由匹配:

[HttpGet("cursos/{sigla:string}")]
public async Task<ActionResult<Curso>> GetCurso(string sigla)
{
    if (_context.Cursos == null)
    {
        return NotFound();
    }
    var curso = await _context.Cursos.FirstOrDefaultAsync(a => a.Sigla == sigla);

    if (curso == null)
    {
        return NotFound();
    }

    return curso;
}

此时原请求URLhttps://localhost:7225/api/cursos/ENC即可正常使用。

额外优化

代码中的Include(f => f.Sigla)是多余的,因为Sigla是Curso类的直接属性,不是EF Core的导航属性,删除该调用可以避免不必要的查询开销。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:25:30