Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Return a 405 Method Not Allowed response instead of 404 #388

Closed
kichalla opened this issue May 5, 2014 · 20 comments
Closed

Return a 405 Method Not Allowed response instead of 404 #388

kichalla opened this issue May 5, 2014 · 20 comments

Comments

@kichalla
Copy link
Member

kichalla commented May 5, 2014

For the below controller, a request like POST /simplerest results in a 404 Not Found.

Expected:
405 Method Not Allowed response with an Allow response header mentioning the list of methods supported by the resource identified by the url /simplerest. Currently MVC-WebAPI has this kind of support.

public class SimpleRest : Controller
    {
        public string Get()
        {
            return "Get method";
        }
    }

From Spec:
10.4.6 405 Method Not Allowed
The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.

@danroth27 danroth27 added this to the Post Alpha milestone May 13, 2014
@yishaigalatzer yishaigalatzer removed this from the Post Alpha milestone May 23, 2014
@danroth27 danroth27 added this to the Backlog milestone Oct 16, 2014
@darrelmiller
Copy link

If actionSelector.SelectAsync(context) returns null when an action cannot be found then how can we ever detect the difference between failing to match because of a HTTP method and failing because we can't match the URL. Wouldn't we need to return some kind of ActionSelectionResult?

@darrelmiller
Copy link

@Eilon @danroth27 Do you have someone working on this? Would you entertain a PR from me on it? I haven't done anything yet, just wanted to check with you before trying anything.

@danroth27
Copy link
Member

We don't have anyone working on this in part because we think the way the system is architected makes it difficult to do this in a general way that is still correct. Because of this I expect getting this feature into MVC will be difficult and involve a lot of discussion and iteration, but if you feel up to the challenge then go for it! 😄

@darrelmiller
Copy link

@danroth27 Yes, I spent some time looking at the way the action selection process evaluates constraints and there is no obvious solution. I'll let you know if I think of something.

@malekpour
Copy link

Any update on this?

Even though it does not comply with the spec, It is okay in my view. Just wondering if there is any plan to change the behavior for the RTM.

@danroth27
Copy link
Member

No plans to do this for RTM, but we may look at it for a future release.

@nathan-alden-sr
Copy link

Things like this drove my team and me to choose NancyFx over MVC 6. Come on, guys, you've had 10+ years to get this stuff right. Look up the status codes and their meanings in the RFC and implement them when appropriate. It's not difficult. As it stands, it seems impossible to do this myself due to the lack of an "action selector result" abstraction.

I'm sorry I'm so bitter but I had a lot of good shared code invested in Web API 2, only to see Web API 2 completely abandoned for an inferior API framework in MVC 6. If I want to benefit from .NET Core then the only choice for me is NancyFx.

@danroth27
Copy link
Member

@nathan-alden We haven't been prioritizing this issue very high because while supporting possible every HTTP status code is academically interesting we couldn't think of a scenario where returning a 405 instead of a 404 would actually be useful. It could be that we are missing a scenario here that we should prioritize higher. Can you tell us more about why returning a 405 is needed for your application? Is this purely about HTTP correctness? Or do you actually have client side logic that does something with 405 results?

@nathan-alden-sr
Copy link

nathan-alden-sr commented Dec 7, 2016

I realize it seems minor, but for long-time .NET developers like myself who remember the dark days of ASP.NET Web Forms, it's a reminder that HTTP can be an afterthought in Microsoft's design of web frameworks. Yes, MVC 6 is light years better than Web Forms, but it still has a long way to go. I am bitter that a superior RESTful application framework--Web API 2--was abandoned for an inferior set of abstractions in MVC 6.

I, like many, many others, prefer to implement RESTful APIs even though yes, any error code would work if the client doesn't care. The point is standardization. With Web API 2, it seemed that Microsoft was finally embracing HTTP as much as possible. The abstractions were well thought-out and excellent for RESTful applications. MVC 6 is a step backward, with its broken authentication abstractions and issues like this one.

There really aren't any questions to ask about this. Either Microsoft embraces HTTP and REST or they don't. I'm simply throwing my voice into the mix to say that I have to seek alternatives for several reasons; this thread is about 405s specifically so I stuck to just that reason.

Here is another issue that outlines everything I discovered in my migration from Web API 2 to MVC 6: #5532

@danroth27
Copy link
Member

danroth27 commented Dec 7, 2016

I certainly agree that compromises were made on the API front when we merged MVC and Web API for ASP.NET Core. We definitely pivoted more towards MVC. We've been waiting to hear from users where this caused more pain than good, so this kind of feedback is very much appreciated. If there are areas were ASP.NET Core falls short for Web API development then please let us know with as many specifics as you can!

For example, can you tell me what you mean specifically by the broken authentication abstractions? Have you already opened a separate issue with that feedback? If yes, then please point me at it and we'll take a look.

If you strongly preferred the ASP.NET Web API programming model then you might also take a look at the Web API compat shim. It basically puts a ASP.NET Web API façade over ASP.NET Core MVC. It's primary intended use case was to ease migration to ASP.NET Core for existing ASP.NET Web API customers.

As for this particular issue I wouldn't interpret the delay in addressing this as an indication that Microsoft no longer cares about REST. This is purely about prioritization. Given that we still need to implement support for real-time scenarios, HTTP/2, finish hardening Kestrel and a whole bunch of other large things this issue simply hasn't bubbled anywhere near the top. Please let us know though if you think we should reconsider.

@nathan-alden-sr
Copy link

nathan-alden-sr commented Dec 7, 2016

I understand that returning 405s isn't going to be the highest priority. I would much rather you folks continue to focus on .NET Standard 2.0, VS 2017, Linux compatibility, etc.; there are huge wins to be had there. I am just expressing my frustrations that MVC 6 is not as API-focused as Web API 2 was. The issue I linked to at the end of my previous post details some of my concerns. It's not that there's one glaring issue that prevents me from using MVC 6; it's more like "death by a thousand cuts." NancyFx simply gets me much closer to what I need my web framework to be: close to the metal (HTTP), simple pipeline concept, lots of extensibility points, not as opinionated about specific abstractions that only work for some folks. Web API 2, for sure, had lots of abstractions that NancyFx doesn't have, but they were abstractions that allowed me to extend the behavior as necessary for code reuse and RESTfulness.

Thanks for considering my feedback; I appreciate it. 👍

@danroth27
Copy link
Member

The issue I linked to at the end of my previous post details some of my concerns.

Perfect - thanks for the detailed feedback!

@davidfowl
Copy link
Member

Yes, MVC 6 is light years better than Web Forms, but it still has a long way to go. I am bitter that a superior RESTful application framework--Web API 2--was abandoned for an inferior set of abstractions in MVC 6.

nit: It's not MVC 6, it's MVC Core 1.x.

@danroth27
Copy link
Member

nit: It's not MVC 6, it's MVC Core 1.x.

nit nit: It's actually ASP.NET Core MVC 😸

@davidfowl
Copy link
Member

nit nit nit: It's Microsoft ASP.NET Core MVC 1.x

@Eilon
Copy link
Member

Eilon commented May 11, 2017

Closing because there are no plans to implement this.

@pierslawson
Copy link

Is there an extension point where I might be able to implement this myself. My reason for wanting to return a 405 is simply backwards compatibility. We implemented it in a previous incarnation of our API and a number of automated tests would ideally not have to change just because we are changing the underlying technology. It also goes in hand in hand with supporting the Allow header (which I have implemented) which means a client can discover the functionality it has been granted (e.g. I can read an employee's details but I can't update them).

@vanillajonathan
Copy link

vanillajonathan commented Aug 31, 2017

This issue still remains in ASP.NET Core MVC 2.0.

Here is how to manually return a 405 status code if you really need to. But it is boilerplate code for something that ought to be provided by the framework.

    public class HomeController : Controller
    {
        [HttpGet]
        public IActionResult Foo()
        {
            return Ok();
        }

        public IActionResult Foo(string foo)
        {
            Response.Headers.Add("Allow", "GET, HEAD");
            return StatusCode(StatusCodes.Status405MethodNotAllowed);
        }
    }

https://tools.ietf.org/html/rfc7231#section-7.4.1

@nathan-alden-sr
Copy link

@vanillajonathan That's very suboptimal because you'd have to add a [useless] method stub for every common HTTP method. Talk about bloat...

@malekpour
Copy link

Probably there is a better way to achieve this. I am thinking about a filter attribute that can be added on method or globally to produce 405 status code. Something like this:

public class HomeController : Controller
{
    [HttpGet, OtherMethodsNotAllowed]
    public IActionResult Foo()
    {
        return Ok();
    }
}

The filter will be executed before the action and if the HTTP method is not explicitly defined, writes the response with status code 405 and ends execution. Filter can be applied at controller level or globally at startup for all actions in the project.

More at: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants