Last active
April 26, 2018 15:32
-
-
Save paulczy/4f13bc5ab7ac34eaa6a7da4d0ba16958 to your computer and use it in GitHub Desktop.
Add ETags to your ASP.NET Core responses.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Security.Cryptography; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.AspNetCore.Mvc.Filters; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Bson; | |
// ReSharper disable once CheckNamespace | |
public class ETagAttribute : ResultFilterAttribute | |
{ | |
public override Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) | |
{ | |
var result = context.Result as OkObjectResult; | |
if (result == null) return base.OnResultExecutionAsync(context, next); | |
string token; | |
using (var ms = new MemoryStream()) | |
{ | |
using (var writer = new BsonWriter(ms)) | |
{ | |
var serializer = new JsonSerializer(); | |
serializer.Serialize(writer, result); | |
token = GetToken(ms.ToArray()); | |
} | |
} | |
var clientToken = context.HttpContext.Request.Headers["If-None-Match"]; | |
if (token != clientToken) | |
{ | |
context.HttpContext.Response.Headers["ETag"] = token; | |
} | |
else | |
{ | |
context.Result = new StatusCodeResult(304); | |
} | |
return base.OnResultExecutionAsync(context, next); | |
} | |
private static string GetToken(byte[] bytes) | |
{ | |
var checksum = MD5.Create().ComputeHash(bytes); | |
return Convert.ToBase64String(checksum, 0, checksum.Length); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code totally wrong from point of view of it purpose...
IActionResult is not always OkObjectResult. There are a lot of results including own ones:
JsonResult
ContentResult
ObjectResult
OkObjectResult
NotFoundObjectResult
FileContentResult
FileStreamResult
VirtualFileResult
PhysicalFileResult
Only ObjectResult is related to OkObjectResult... All other will not be cached... For example if you want to serve static html templates with ViewResult or some own static file it will not work...
So maybe to avoid misunderstanding it should be named something like ETagObjectResultAttribute... because as universal etag attribute it is wrong.