6

In my ASP.NET core Controller I've got the following HttpGet-function:

[HttpGet("[action]")]
[HttpHead("[action]")]
[ResponseCache(NoStore = true)]
public async Task<IActionResult> GetProofPdf(long studentid)
{
  var rawPdfData = await _studentLogic.StudentPdfAsync(User, studentid);
  if (Request.Method.Equals("HEAD"))
  {
    Response.ContentLength = rawPdfData.Length;
    return Json(data: "");
  }
  else
  {
    return File(rawPdfData, "application/pdf");
  }
}

This does work nicely. The returned file object can be saved from the browser. The only problem is embedding the PDF in IE. IE sends a HEAD request first. The HEAD request Fails, so IE does not even try to get the PDF. Other browsers do not send HEAD or use GET when HEAD fails, but not IE.

Since I want so Support IE I want to create a HEAD Action. Just adding [HttpHead("[action]")] to the function will not work, probably because for HEAD the content must be empty ("The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.").

So how do I create a HttpHead-Verb-Function in ASP.NET Core? How do I return empty Content but the correct content-length?

Sam
  • 28,421
  • 49
  • 167
  • 247
  • At least in ASP .NET Core 2.2 it seems to suffice to just write both the `HttpGet` and `HttpHead` attributes without needing to check if the method is `HEAD` as the pipelines knows that it should ignore the body for HEAD requests. – ckuri Sep 09 '19 at 11:13
  • The last edit is weird as it already incorporates the accepted answer, which now does not make much sense. It is unclear what's missing there to work now. Do I get it correctly that the only missing point is `Ok()` instead of `Json(data: "")`, as commented under the accepted answer? – Palec Oct 14 '22 at 08:07

1 Answers1

5

Something along these lines should work for you.

    [HttpGet]
    [HttpHead]
    [ResponseCache(NoStore = true)]
    public async Task<IActionResult> GetProofPdf(long studentid)
    {
        if (Request.Method.Equals("HEAD"))
        {
            //Calculate the content lenght for the doc here?
            Response.ContentLength = $"You made a {Request.Method} request".Length;
            return Json(data: "");
        }
        else
        {
            //GET Request, so send the file here.
            return Json(data: $"You made a {Request.Method} request");
        }
    }
Muqeet Khan
  • 2,094
  • 1
  • 18
  • 28
  • Thanks! HEAD will be called, but embedding the PDF still does not work. I guess `return Json(data: "");` is not empty? I updated my source example. – Sam Dec 13 '17 at 13:20
  • 4
    @Sam You are actually returning some data, try using return Ok() instead of Json(data: ""); – Przemek Marcinkiewicz Dec 13 '17 at 14:39