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/enchttps://localhost:7225/api/cursos/ENChttps://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
相关产品推荐
相关产品推荐

