ASP.NET Core OData控制器AmbiguousMatchException错误求助
ASP.NET Core OData控制器Delete请求出现AmbiguousMatchException的解决方法
出现这个错误的核心原因是OData会自动为实体生成默认的CRUD端点,包括DELETE请求的路由/odata/People({key}),而你手动添加了带有[HttpDelete("odata/People({key})")]属性的方法,导致两个端点(自动生成的和自定义的)匹配同一个请求,引发路由冲突。
方案一:移除手动路由属性,依赖OData自动路由
ODataController默认支持CRUD操作,只要你的方法符合命名约定(比如方法名以Delete开头,参数为实体的键),OData会自动绑定到默认路由。修改你的方法如下:
public async Task<IActionResult> DeletePerson(int key) { var currentPerson = await _airVinylDbContext.People.FirstOrDefaultAsync(c => c.PersonId == key); if (currentPerson == null) { return NotFound(); } _airVinylDbContext.Remove(currentPerson); await _airVinylDbContext.SaveChangesAsync(); return NoContent(); }
移除[HttpDelete]属性后,OData会自动将这个方法映射到DELETE /odata/People({key})路由,不会再出现冲突。
方案二:自定义唯一路由,避免与默认端点冲突
如果需要保留自定义逻辑且不想依赖默认路由,可以修改路由模板,或者使用OData专属的[ODataRoute]属性指定唯一路由:
方法A:修改HttpDelete的路由模板
[HttpDelete("odata/People({key})/CustomDelete")] public async Task<IActionResult> DeletePerson(int key) { // 原有逻辑不变 }
此时请求地址需改为DELETE /odata/People({key})/CustomDelete,避免与默认路由冲突。
方法B:使用ODataRoute属性
[ODataRoute("People({key})/Delete")] public async Task<IActionResult> DeletePerson(int key) { // 原有逻辑不变 }
同样,请求地址变为DELETE /odata/People({key})/Delete,确保路由唯一。
方案三:关闭OData默认的Delete端点
如果不需要OData自动生成的Delete端点,可以在OData配置中禁用对应实体的Delete操作:
在Program.cs/Startup.cs的OData配置处添加:
builder.Services.AddControllers().AddOData(options => { options.Select().Filter().OrderBy().Expand().Count().SetMaxTop(100); options.AddRouteComponents("odata", GetEdmModel(), builder => { // 禁用Person实体的默认Delete操作 builder.EntityType<Person>().DisableDelete(); }); });
禁用后,OData不会自动生成Delete端点,你手动添加的[HttpDelete("odata/People({key})")]方法即可正常使用。
内容的提问来源于stack exchange,提问作者nabeel yahya
相关产品推荐
相关产品推荐

