Skip to content

Getting 400 "ApiVersionUnspecified " instead of 405 when using wrong HTTP method despite AssumeDefaultVersionWhenUnspecified = true #254

Closed
@krzkraw

Description

@krzkraw

I'm using Microsoft.AspNet.WebApi.Versioning v2.2.0 in my solution.

Hello2Controller's method Get() has [Route("hello")] and [Route("{version:apiVersion}/hello")] routes. Controller itself is [ApiVersion("2")].
HelloControler's method Get() is the same, however controller is [ApiVersion("1", Deprecated = true)]

So both api/hello endpoints support only HTTP GET in both v1 and v2.
Calling GET ...api/hello or api/1/hello or api/2/hello returns 200 OK.
Calling POST (or any unsupported verb for that matter) on api/1/hello or api/2/hello returns 405 Method Not Allowed - "UnsupportedApiVersion The requested resource with API version '1' does not support HTTP method 'POST'." , which is expected correct response.
However, when you do NOT specify API version and make a call like this POST ...api/hello response is 400 Bad Request - ApiVersionUnspecified An API version is required, but was not specified. - which is not expected correct response as it should be 405 too because of AssumeDefaultVersionWhenUnspecified being set to true.

So Web Api is not assuming the default API version which is set to 1.0 when request has wrong HTTP methods and returns Bad Request instead of Method Not Allowed. How this can be resolved and 405 returned when API version is not set explicitly? I've searched trough numerous open and closed issues, wikis and stackoverflow posts but I have not came across issue like this yet.

Here is versioning code from WebApiConfig:

config.AddApiVersioning(options =>
            {
                options.ReportApiVersions = true;
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
            });

            var constraintResolver = new DefaultInlineConstraintResolver
            {
                ConstraintMap =
                {
                    ["apiVersion"] = typeof(ApiVersionRouteConstraint)
                }
            };

            config.MapHttpAttributeRoutes(constraintResolver, new RoutePrefixProvider());

And here are the example controllers

[ApiVersion("2")]
    public class Hello2Controller : ApiController
    {
        [NoAuthorization]
        [HttpGet]
        [Route("hello")]
        [Route("{version:apiVersion}/hello")]
        public IHttpActionResult Get()
        {
            return Ok("Response from Hello2Controller");
        }
    }
[ApiVersion("1")]
    public class HelloController : ApiController
    {
        [NoAuthorization]
        [HttpGet]
        [Route("{version:apiVersion}/hello")]
        public IHttpActionResult Get()
        {
            return Ok("Response from HelloController");
        }
    }

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions