Search code examples
c#asp.netexceptionroutes

Asp.net: Conflicting method/path when implement a controllerbase


I defined a class named BaseController which implements from ControllerBase, it has a query function with [HttpGet], when i define another class named UniqueController implements from BaseController, and then overwrite the query function, got error:

Actions require an explicit HttpMethod binding for Swagger/OpenAPI 3.0
// basecontroller
public class BaseController<T> : ControllerBase where T : BaseModel, new() 
{
        [HttpGet]
        public virtual async Task<IActionResult> Query()
        {
            var models = await _baseService.QueryModelAsync();
            return Ok(ApiResultHelper.Success("Success", new { Value = models }, models.Count));
        }
}
// uniquecontroller
public class UniqueController<T> : BaseController<T> where T : UniqueModel, new()
{
        public new async Task<IActionResult> Query()
        {
            var models = await _modelService.QueryModelAsync();
            return Ok(ApiResultHelper.Success("Success", new { Value = models }, models.Count));
        }
}
// module controller use
public class UserController : UniqueController<UserModel>
{
        public UserController(UniqueService<UserModel> modelService, IHttpContextAccessor httpContextAccessor) 
            : base(modelService, httpContextAccessor) {}
}

Solution

  • It is because you have hidden the method with new keyword.

    You would need to define it with override.

    Thinking about it from pure language perspective, new is hiding the method, meaning there will be two versions of the same method. Consider simple example:

    public class Base
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("Calling base virtual method");
        }
    }
    
    public class UniqueWithNew : Base
    {
        public new virtual void VirtualMethod()
        {
            Console.WriteLine("Calling UniqueWithNew method");
        }
    }
    
    public class UserWithNew : UniqueWithNew { }
    

    and the sample program:

    var userWithNew = new UserWithNew();
    
    userWithNew.VirtualMethod();
    Base @base = userWithNew;
    
    Console.WriteLine("Calling user with new as Base: ");
    
    @base.VirtualMethod();
    

    Each VirtualMethod() invocation will return different results, as they are two different methods.

    Swagger detect also these two methods, both having HttpGet attribute and will get confused.