41

I'd like to correctly support the HTTP HEAD request when bots hit my ASP.NET MVC site using HEAD. It was brought to my attention that all HTTP HEAD requests to the site were returning 404s, particularly from http://downforeveryoneorjustme.com. Which is really annoying. Wish they would switch to GET like all the other good bots out there.

If I just change [AcceptVerbs(HttpVerbs.Get)] to [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Head)] will MVC know to drop the body of the request?

What have you done to support HTTP HEAD requests? (Code sample would be great!)

DavGarcia
  • 18,540
  • 14
  • 58
  • 96
  • 1
    The MVC framework gives no special treatment to `HEAD` whatsoever. – Craig Stuntz Jul 06 '10 at 13:03
  • @CraigStuntz -- Not true; at least in current versions of ASP.NET MVC, responses to HEAD requests have just the headers but no body, as expected. See a7drew's answer below. – Jon Schneider Aug 17 '17 at 15:05

2 Answers2

58

I created a simple action method in an ASP.Net MVC 2 project:

public class HomeController : Controller
{
    public ActionResult TestMe()
    {
        return View();
    }
}

Then I launched Fiddler and built up an HTTP GET request to hit this URL:

http://localhost.:51149/Home/TestMe

The expected full page content was returned.

Then, I changed the request to use an HTTP HEAD instead of an HTTP GET. I received just the expected head info and no body info in the raw output.

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 07 Jul 2010 16:58:55 GMT
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 2.0
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 1120
Connection: Close

My guess is that you are including a constraint on the action method such that it will only respond to HTTP GET verbs. If you do something like this, it will work for both GET and HEAD, or you can omit the constraint entirely if it provides no value.

public class HomeController : Controller
{
    [AcceptVerbs(new[] {"GET", "HEAD"})]
    public ActionResult TestMe()
    {
        return View();
    }
}
a7drew
  • 7,801
  • 6
  • 38
  • 39
  • 1
    Thanks for this, great answer. I followed your example and replaced all instances of [HttpGet] with [AcceptVerbs(new[] {"GET", "HEAD"})] right throughout my site. Now twitter and other similar bots can call a HEAD on any of my content and receive the correct response, rather than the errors I was throwing them.. Cheers – Aaron Mar 09 '11 at 02:40
  • 1
    Just a heads up and don't make the mistake I did by trying to place the Get and Head verbs on separate actions as it will throw a 500 on the Head request. – cs-NET Sep 02 '16 at 14:29
  • 3
    You can also use [HttpGet, HttpHead] which is a little easier to type. – user169771 Oct 31 '16 at 16:15
  • 4
    Using [HttpGet, HttpHead] did NOT work for me (on .NET 4.5.1) -- they caused requests using either GET or HEAD to return 404s -- whereas the other provided solutions did work fine. – Jon Schneider Aug 17 '17 at 15:03
  • 2
    I use [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Head)] which eliminates any potential problems with using magic strings. (See also user2101889's answer.) – ChrisFox Mar 04 '19 at 10:19
30

You can achieve the result by simply doing following

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Head)]
public ActionResult TestMe() =>View();
tchelidze
  • 8,050
  • 1
  • 29
  • 49
user2101889
  • 309
  • 3
  • 2