[{"data":1,"prerenderedAt":991},["ShallowReactive",2],{"i-feather:search":3,"i-feather:x":8,"i-feather:moon":10,"i-feather:sun":12,"i-fa-brands:youtube":14,"i-fa-brands:twitch":18,"i-fa-brands:github":20,"i-fa-brands:linkedin":23,"i-fa-brands:stack-overflow":26,"i-simple-icons:bluesky":29,"i-fa-brands:mastodon":31,"i-fa-regular:envelope":33,"i-fa-solid:rss":35,"post-\u002Fasp-net-core-caching-in-practice\u002F":37,"post-navigation":590,"i-fa-solid:share-alt":971,"i-fa-brands:facebook":973,"i-fa-brands:twitter":975,"i-fa-brands:reddit":977,"i-fa-brands:patreon":979,"i-simple-icons:buymeacoffee":981,"i-fa-brands:paypal":983,"i-fa-regular:question-circle":985,"i-feather:arrow-left":987,"i-feather:arrow-right":989},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003Cpath d=\"m21 21l-4.35-4.35\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 6L6 18M6 6l12 12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21 12.79A9 9 0 1 1 11.21 3A7 7 0 0 0 21 12.79\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"5\"\u002F>\u003Cpath d=\"M12 1v2m0 18v2M4.22 4.22l1.42 1.42m12.72 12.72l1.42 1.42M1 12h2m18 0h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":15,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":17},576,512,"\u003Cpath fill=\"currentColor\" d=\"M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597c-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821c11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305m-317.51 213.508V175.185l142.739 81.205z\"\u002F>",{"left":4,"top":4,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cpath fill=\"currentColor\" d=\"M391.17 103.47h-38.63v109.7h38.63ZM285 103h-38.63v109.75H285ZM120.83 0L24.31 91.42v329.16h115.83V512l96.53-91.42h77.25L487.69 256V0Zm328.24 237.75l-77.22 73.12h-77.24l-67.6 64v-64h-86.87V36.58h308.93Z\"\u002F>",{"left":4,"top":4,"width":21,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":22},496,"\u003Cpath fill=\"currentColor\" d=\"M165.9 397.4c0 2-2.3 3.6-5.2 3.6c-3.3.3-5.6-1.3-5.6-3.6c0-2 2.3-3.6 5.2-3.6c3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9c2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9c.3 2 2.9 3.3 5.9 2.6c2.9-.7 4.9-2.6 4.6-4.6c-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2c12.8 2.3 17.3-5.6 17.3-12.1c0-6.2-.3-40.4-.3-61.4c0 0-70 15-84.7-29.8c0 0-11.4-29.1-27.8-36.6c0 0-22.9-15.7 1.6-15.4c0 0 24.9 2 38.6 25.8c21.9 38.6 58.6 27.5 72.9 20.9c2.3-16 8.8-27.1 16-33.7c-55.9-6.2-112.3-14.3-112.3-110.5c0-27.5 7.6-41.3 23.6-58.9c-2.6-6.5-11.1-33.3 2.6-67.9c20.9-6.5 69 27 69 27c20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27c13.7 34.7 5.2 61.4 2.6 67.9c16 17.7 25.8 31.5 25.8 58.9c0 96.5-58.9 104.2-114.8 110.5c9.2 7.9 17 22.9 17 46.4c0 33.7-.3 75.4-.3 83.6c0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252C496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2c1.6 1.6 3.9 2.3 5.2 1c1.3-1 1-3.3-.7-5.2c-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9c1.6 1 3.6.7 4.3-.7c.7-1.3-.3-2.9-2.3-3.9c-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2c2.3 2.3 5.2 2.6 6.5 1c1.3-1.3.7-4.3-1.3-6.2c-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2c-1.4-2.3-4-3.3-5.6-2\"\u002F>",{"left":4,"top":4,"width":24,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":25},448,"\u003Cpath fill=\"currentColor\" d=\"M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3M135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5c0 21.3-17.2 38.5-38.5 38.5m282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7c-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5c67.2 0 79.7 44.3 79.7 101.9z\"\u002F>",{"left":4,"top":4,"width":27,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":28},384,"\u003Cpath fill=\"currentColor\" d=\"M290.7 311L95 269.7L86.8 309l195.7 41zm51-87L188.2 95.7l-25.5 30.8l153.5 128.3zm-31.2 39.7L129.2 179l-16.7 36.5L293.7 300zM262 32l-32 24l119.3 160.3l32-24zm20.5 328h-200v39.7h200zm39.7 80H42.7V320h-40v160h359.5V320h-40z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":30},"\u003Cpath fill=\"currentColor\" d=\"M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037c-.856 3.061-3.978 3.842-6.755 3.37c4.854.826 6.089 3.562 3.422 6.299c-5.065 5.196-7.28-1.304-7.847-2.97c-.104-.305-.152-.448-.153-.327c0-.121-.05.022-.153.327c-.568 1.666-2.782 8.166-7.847 2.97c-2.667-2.737-1.432-5.473 3.422-6.3c-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026\"\u002F>",{"left":4,"top":4,"width":24,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":32},"\u003Cpath fill=\"currentColor\" d=\"M433 179.11c0-97.2-63.71-125.7-63.71-125.7c-62.52-28.7-228.56-28.4-290.48 0c0 0-63.72 28.5-63.72 125.7c0 115.7-6.6 259.4 105.63 289.1c40.51 10.7 75.32 13 103.33 11.4c50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.5 102.5 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7c56.12-6.7 105-41.3 111.23-72.9c9.8-49.8 9-121.5 9-121.5m-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175c25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5l11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1c23.71 27.3 18.4 53 18.4 175z\"\u002F>",{"left":4,"top":4,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":34},"\u003Cpath fill=\"currentColor\" d=\"M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48m0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49c-16.841 13.247-50.201 45.072-73.413 44.701c-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646c21.857 17.205 60.134 55.186 103.062 54.955c42.717.231 80.509-37.199 103.053-54.947c49.528-38.783 82.032-64.401 104.947-82.653V400z\"\u002F>",{"left":4,"top":4,"width":24,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":36},"\u003Cpath fill=\"currentColor\" d=\"M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041s64.04 28.673 64.04 64.041m175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018c111.832 7.284 201.473 96.702 208.772 208.772c.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79m144.249.288C439.596 229.677 251.465 40.445 16.503 32.01C7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999c191.179 7.839 344.627 161.316 352.465 352.465c.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504\"\u002F>",{"id":38,"title":39,"author":40,"body":41,"comments":393,"date":567,"dateModified":568,"description":569,"extension":570,"headings":571,"heroImage":577,"meta":578,"path":579,"permalink":579,"published":580,"stem":581,"tags":582,"timeToRead":589},"posts\u002Fposts\u002F2017\u002Fasp-net-core-caching-in-practice\u002Findex.md","ASP.NET Core Caching in Practice","Muhammad Rehan Saeed",{"type":42,"value":43,"toc":390},"minimark",[44,69,84,93,100,111,114,124,127,132,135,147,156,161,164,202,222,229,234,237,248,256,281,302,305,316,330,333,336,357,363,374,386],[45,46,48,68],"h1",{"id":47},"cache-control-http-header",[49,50,53],"anchor-link",{"href":51,"label":52},"#cache-control-http-header","Link to this section",[54,55,62],"svg",{"xmlns":56,"xmlns:xlink":57,"viewBox":58,"version":59,"width":60,"height":60,"aria-hidden":61},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","http:\u002F\u002Fwww.w3.org\u002F1999\u002Fxlink","0 0 16 16","1.1",22,"true",[63,64],"path",{"fill":65,"fill-rule":66,"d":67},"currentColor","evenodd","M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z","Cache-Control HTTP Header",[70,71,72,73,83],"p",{},"The ",[74,75,82],"a",{"href":76,"rel":77,"target":81},"https:\u002F\u002Fdevelopers.google.com\u002Fweb\u002Ffundamentals\u002Fperformance\u002Foptimizing-content-efficiency\u002Fhttp-caching",[78,79,80],"nofollow","noopener","noreferrer","_blank","Cache-Control"," HTTP header can be used to set how long your resource can be cached for. However, the problem with this HTTP header is that you need to be able to predict the future and know before hand when the cache will become invalid. For some use cases, like writing an API where someone could change the resource at any time that's just not feasible.",[70,85,86,87,92],{},"I recommend you read the response caching middleware ",[74,88,91],{"href":89,"rel":90,"target":81},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fperformance\u002Fcaching\u002Fmiddleware",[78,79,80],"documentation",", it's not necessary as I do a quick overview next but the knowledge below builds upon it. The simple way to set the cache control header is directly on the action method like so:",[94,95],"pre",{"className":96,"language":97,"meta":98,"style":98,"html":99},"language-cs shiki shiki-themes light-plus monokai","cs","","\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">[\u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpGet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">ResponseCache\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Duration\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"s0PsH\"> 3600\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Location\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> ResponseCacheLocation\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Any\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IActionResult\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> GetCats\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">()\n\u003C\u002Fspan>\u003C\u002Fspan>",[70,101,102,103,107,108,110],{},"Adding the ",[104,105,106],"code",{},"ResponseCache"," attribute just adds the ",[104,109,82],{}," HTTP header but does not actually cache the response on the server. To do that you also need to add the response caching middleware like so:",[94,112],{"className":96,"language":97,"meta":98,"style":98,"html":113},"\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> void\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> Configure\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IApplicationBuilder\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> application\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">) \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">    application\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">UseResponseCaching\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">().\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">UseMvc\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>",[70,115,116,117,119,120,123],{},"Instead of hard coding all of your cache settings in the ",[104,118,106],{}," attribute, it's possible to store them in the ",[104,121,122],{},"appsettings.json"," configuration file. To do so, you need to use a feature called cache profiles which look like this:",[94,125],{"className":96,"language":97,"meta":98,"style":98,"html":126},"\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">[\u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpGet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">ResponseCache\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">CacheProfile\u003C\u002Fspan>\u003Cspan class=\"snCLD\">=\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"Cache1Hour\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IActionResult\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> GetCats\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">()\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">public class Startup\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{    \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">    private\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IConfiguration\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> configuration\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">    public\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> Startup\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">() \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">configuration\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> configuration\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">    public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> void\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> ConfigureServices\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IServiceCollection\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> services\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">) \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">        services\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">            .\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">Configure\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">Dictionary\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">string\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">CacheProfile\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;&gt;(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">configuration\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetSection\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"CacheProfiles\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">))\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">            .\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">AddMvc\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">options\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">            {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s1q82\">                \u002F\u002F Read cache profiles from appsettings.json configuration file\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">                var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> cacheProfiles\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">configuration\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetSection\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">Dictionary\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">string\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">CacheProfile\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;&gt;();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">                foreach\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> (\u003C\u002Fspan>\u003Cspan class=\"s4J9F\">var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> keyValuePair\u003C\u002Fspan>\u003Cspan class=\"smL5M\"> in\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> cacheProfiles\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">                {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">                    options\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">CacheProfiles\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">Add\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">keyValuePair\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">                }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">            });\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">            \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s1q82\">    \u002F\u002F Omitted\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[94,128],{"className":129,"language":130,"meta":98,"style":98,"html":131},"language-json shiki shiki-themes light-plus monokai","json","\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"svrZB\">  \"CacheProfiles\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">: {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"svrZB\">    \"Cache1Hour\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">: {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"svrZB\">      \"Duration\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">: \u003C\u002Fspan>\u003Cspan class=\"s0PsH\">3600\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"svrZB\">     \"Location\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">: \u003C\u002Fspan>\u003Cspan class=\"syaXe\">\"Any\"\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">  },\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s1q82\">  \u002F\u002F Omitted...\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[70,133,134],{},"Now all your caching can be configured from a single configuration file.",[136,137,139,146],"h2",{"id":138},"cache-control-immutable-directive",[49,140,142],{"href":141,"label":52},"#cache-control-immutable-directive",[54,143,144],{"xmlns":56,"xmlns:xlink":57,"viewBox":58,"version":59,"width":60,"height":60,"aria-hidden":61},[63,145],{"fill":65,"fill-rule":66,"d":67},"Cache-Control Immutable Directive",[70,148,149,151,152,155],{},[104,150,82],{}," also has a new draft directive called ",[104,153,154],{},"immutable",". When you add this to the HTTP header value, you are basically telling the client that this resource never changes even if it has expired. You might be asking, why do we need this? Well, it turns out that when you refresh a page in a browser, it goes off to the server and checks to see if the resource has expired or not.",[94,157],{"className":158,"language":159,"meta":98,"style":98,"html":160},"language-http shiki shiki-themes light-plus monokai","http","\u003Cspan class=\"line\">\u003Cspan class=\"sjbfc\">Cache-Control\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">:\u003C\u002Fspan>\u003Cspan class=\"swiDo\"> max-age=365000000, immutable\n\u003C\u002Fspan>\u003C\u002Fspan>",[70,162,163],{},"It turns out that you get a massive reduction in requests to your server by implementing this directive. Read more about it in these links:",[165,166,167,175,182,188,195],"ul",{},[168,169,170],"li",{},[74,171,174],{"href":172,"rel":173,"target":81},"https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Fdraft-mcmanus-immutable-00",[78,79,80],"IETF Draft Spec",[168,176,177],{},[74,178,181],{"href":179,"rel":180,"target":81},"https:\u002F\u002Fhacks.mozilla.org\u002F2017\u002F01\u002Fusing-immutable-caching-to-speed-up-the-web\u002F",[78,79,80],"Using Immutable Caching To Speed Up The Web",[168,183,184],{},[74,185,82],{"href":186,"rel":187,"target":81},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTTP\u002FHeaders\u002FCache-Control",[78,79,80],[168,189,190],{},[74,191,194],{"href":192,"rel":193,"target":81},"https:\u002F\u002Fbitsup.blogspot.co.uk\u002F2016\u002F05\u002Fcache-control-immutable.html",[78,79,80],"Cache-Control: immutable",[168,196,197],{},[74,198,201],{"href":199,"rel":200,"target":81},"https:\u002F\u002Fcode.facebook.com\u002Fposts\u002F557147474482256",[78,79,80],"This browser tweak saved 60% of requests to Facebook",[70,203,204,205,210,211,215,216,218,219,221],{},"This directive has not yet been implemented in ASP.NET Core but I've raised an issue on GitHub ",[74,206,209],{"href":207,"rel":208,"target":81},"https:\u002F\u002Fgithub.com\u002Faspnet\u002FHttpAbstractions\u002Fissues\u002F763",[78,79,80],"here"," and there is also another issue ",[74,212,209],{"href":213,"rel":214,"target":81},"https:\u002F\u002Fgithub.com\u002Faspnet\u002FResponseCaching\u002Fissues\u002F97",[78,79,80]," to add the immutable directive to the static files middleware. If you really wanted to, it's really easy to add this directive today, as you just need to append the word ",[104,217,154],{}," onto the end of your ",[104,220,82],{}," HTTP header.",[70,223,224,225,228],{},"A word of warning! You need to make sure that your resource really never changes. You can do this in Razor by using the ",[104,226,227],{},"asp-append-version"," attribute on your script tags:",[94,230],{"className":231,"language":232,"meta":98,"style":98,"html":233},"language-html shiki shiki-themes light-plus monokai","html","\u003Cspan class=\"line\">\u003Cspan class=\"sNflI\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sjbfc\">script\u003C\u002Fspan>\u003Cspan class=\"snDo4\"> src\u003C\u002Fspan>\u003Cspan class=\"sfK3G\">=\u003C\u002Fspan>\u003Cspan class=\"squEy\">\"~\u002Fsite.js\"\u003C\u002Fspan>\u003Cspan class=\"snDo4\"> asp-append-version\u003C\u002Fspan>\u003Cspan class=\"sfK3G\">=\u003C\u002Fspan>\u003Cspan class=\"squEy\">\"true\"\u003C\u002Fspan>\u003Cspan class=\"sNflI\">&gt;&lt;\u002F\u003C\u002Fspan>\u003Cspan class=\"sjbfc\">script\u003C\u002Fspan>\u003Cspan class=\"sNflI\">&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>",[70,235,236],{},"This will append a query string to the link to site.js which will contain a hash of the contents of the file. Each time the file changes, the hash is changed and thus you can safely mark the resource as immutable.",[45,238,240,247],{"id":239},"e-tags",[49,241,243],{"href":242,"label":52},"#e-tags",[54,244,245],{"xmlns":56,"xmlns:xlink":57,"viewBox":58,"version":59,"width":60,"height":60,"aria-hidden":61},[63,246],{"fill":65,"fill-rule":66,"d":67},"E-Tags",[70,249,250,255],{},[74,251,254],{"href":252,"rel":253,"target":81},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHTTP_ETag",[78,79,80],"E-tags"," are typically generated in three ways (Read the link to understand what they are):",[257,258,259,272,278],"ol",{},[168,260,261,262,265,266,271],{},"Hashing the HTTP response body - You'd want to use a very fast and collision resistant hash function like MD5 (MD5 is broken security wise and you should never use it but it's ok to use it for caching). Unfortunately, this method is slow because you have to load the entire response body into memory (which is not the default in ASP.NET Core which streams it straight to the client for better performance) to hash it. If you're still interested in implementing this ",[104,263,264],{},"E-Tag","'s using this method ",[74,267,270],{"href":268,"rel":269,"target":81},"https:\u002F\u002Fmadskristensen.net\u002Fpost\u002Fsend-etag-headers-in-aspnet-core",[78,79,80],"Mads Kristensen"," wrote a nice blog post showing how it can be done.",[168,273,274,275,277],{},"Last modification timestamp - The ",[104,276,264],{}," can literally be the time the object was last modified which you can store in your database (I usually store created and modified timestamps for anything I store in a database anyway). This solves the performance problem above but now what is the difference between doing this and using the Last Modified HTTP header?",[168,279,280],{},"Revision Number - This could be some kind of integer stored in the database which gets incremented each time the data is modified. I don't see any advantage of doing this over using the last modification timestamp above, unless you have a naturally occurring revision number in your data that you could use.",[70,282,283,284,287,288,291,292,295,296,298,299,301],{},"One additional thing you need to be careful of is the ",[104,285,286],{},"Accept",", ",[104,289,290],{},"Accept-Encoding"," and ",[104,293,294],{},"Accept-Language"," HTTP headers. Any time you send a different response based on these HTTP headers, your ",[104,297,264],{}," needs to be different e.g. a JSON non-gzip'ed response in Mandarin needs to have a different ",[104,300,264],{}," to an XML gzip'ed response in Urdu.",[70,303,304],{},"For option one, this can be achieved by calculating the hash after the response body has gone through GZIP compression. For the second and third options, you would need to append the value of the Accept HTTP headers to the last modified date or revision number and then hash all of that.",[45,306,308,315],{"id":307},"last-modified--if-modified-since",[49,309,311],{"href":310,"label":52},"#last-modified--if-modified-since",[54,312,313],{"xmlns":56,"xmlns:xlink":57,"viewBox":58,"version":59,"width":60,"height":60,"aria-hidden":61},[63,314],{"fill":65,"fill-rule":66,"d":67},"Last-Modified & If-Modified-Since",[70,317,318,319,291,324,329],{},"I'm assuming you already know about the ",[74,320,323],{"href":321,"rel":322,"target":81},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTTP\u002FHeaders\u002FLast-Modified",[78,79,80],"Last-Modified",[74,325,328],{"href":326,"rel":327,"target":81},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTTP\u002FHeaders\u002FIf-Modified-Since",[78,79,80],"If-Modified-Since"," HTTP headers. If not, go ahead and read the links. Below is an example controller and action method that returns a list of cats.",[94,331],{"className":96,"language":97,"meta":98,"style":98,"html":332},"\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">[\u003C\u002Fspan>\u003Cspan class=\"sw29p\">Route\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"[controller]\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> class\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> CatsController\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> : \u003C\u002Fspan>\u003Cspan class=\"sw29p\">ControllerBase\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> ICatRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> catRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> ICatMapper\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> catMapper\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> CatsController\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">        ICatRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> catRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">        ICatMapper\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> catMapper\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">catRepository\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> catRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">catMapper\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> catMapper\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    [\u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpGet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> async\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetCats\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">CancellationToken\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> cancellationToken\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> cats\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> await\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">catRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetAll\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">cancellationToken\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> lastModified\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> cats\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Count\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> ==\u003C\u002Fspan>\u003Cspan class=\"s0PsH\"> 0\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> ?\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">            (\u003C\u002Fspan>\u003Cspan class=\"sw29p\">DateTimeOffset\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">?)\u003C\u002Fspan>\u003Cspan class=\"sMc8R\">null\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> :\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">            cats\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">Max\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">x\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =&gt;\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> x\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">ModifiedTimestamp\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Response\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetTypedHeaders\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">().\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">LastModified\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> lastModified\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> requestHeaders\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Request\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetTypedHeaders\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        if\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> (\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">requestHeaders\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">IfModifiedSince\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">HasValue\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> &amp;&amp;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">            requestHeaders\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">IfModifiedSince\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Value\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> &gt;=\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> lastModified\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">            return\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">StatusCode\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">StatusCodes\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Status304NotModified\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> catViewModels\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">catMapper\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">MapList\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">cats\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        return\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">Ok\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">catViewModels\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[70,334,335],{},"All of our cats have a ModifiedTimestamp, so we know when they were last changed. There are four scenarios that this action method handles:",[257,337,338,341,347,352],{},[168,339,340],{},"Our repository does not contain any cats, so just always return an empty list.",[168,342,343,344,346],{},"No ",[104,345,323],{}," HTTP header exists in the request, so we just return all cats.",[168,348,349,351],{},[104,350,323],{}," HTTP header exists and cats have been modified since that date, so return all cats.",[168,353,354,356],{},[104,355,323],{}," HTTP header exists but no cats have been modified since that date, so return a 304 Not Modified response.",[70,358,359,360,362],{},"In all cases, except when we have no cats at all, we set the ",[104,361,323],{}," date to the latest date than any cat has been modified.",[45,364,366,373],{"id":365},"conclusions",[49,367,369],{"href":368,"label":52},"#conclusions",[54,370,371],{"xmlns":56,"xmlns:xlink":57,"viewBox":58,"version":59,"width":60,"height":60,"aria-hidden":61},[63,372],{"fill":65,"fill-rule":66,"d":67},"Conclusions",[70,375,376,377,379,380,382,383,385],{},"Which caching HTTP headers you pick, depends on your data but at a minimum, I would add ",[104,378,264],{},"'s or ",[104,381,323],{},". Add ",[104,384,82],{}," where possible, usually for static assets.",[387,388,389],"style",{},"html pre.shiki code .sjLUg, html code.shiki .sjLUg{--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sw29p, html code.shiki .sw29p{--shiki-default:#267F99;--shiki-default-text-decoration:inherit;--shiki-dark:#A6E22E;--shiki-dark-text-decoration:underline}html pre.shiki code .sFrd5, html code.shiki .sFrd5{--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .snCLD, html code.shiki .snCLD{--shiki-default:#000000;--shiki-dark:#F92672}html pre.shiki code .s0PsH, html code.shiki .s0PsH{--shiki-default:#098658;--shiki-dark:#AE81FF}html pre.shiki code .sJvqV, html code.shiki .sJvqV{--shiki-default:#0000FF;--shiki-dark:#F92672}html pre.shiki code .sWm5y, html code.shiki .sWm5y{--shiki-default:#795E26;--shiki-dark:#A6E22E}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swiDo, html code.shiki .swiDo{--shiki-default:#A31515;--shiki-dark:#E6DB74}html pre.shiki code .sK46n, html code.shiki .sK46n{--shiki-default:#0000FF;--shiki-dark:#FD971F}html pre.shiki code .s1q82, html code.shiki .s1q82{--shiki-default:#008000;--shiki-dark:#88846F}html pre.shiki code .s4J9F, html code.shiki .s4J9F{--shiki-default:#0000FF;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .smL5M, html code.shiki .smL5M{--shiki-default:#AF00DB;--shiki-dark:#F92672}html pre.shiki code .svrZB, html code.shiki .svrZB{--shiki-default:#0451A5;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .syaXe, html code.shiki .syaXe{--shiki-default:#A31515;--shiki-dark:#CFCFC2}html pre.shiki code .sjbfc, html code.shiki .sjbfc{--shiki-default:#800000;--shiki-dark:#F92672}html pre.shiki code .sNflI, html code.shiki .sNflI{--shiki-default:#800000;--shiki-dark:#F8F8F2}html pre.shiki code .snDo4, html code.shiki .snDo4{--shiki-default:#E50000;--shiki-dark:#A6E22E}html pre.shiki code .sfK3G, html code.shiki .sfK3G{--shiki-default:#000000FF;--shiki-dark:#F8F8F2}html pre.shiki code .squEy, html code.shiki .squEy{--shiki-default:#0000FF;--shiki-dark:#E6DB74}html pre.shiki code .sMc8R, html code.shiki .sMc8R{--shiki-default:#0000FF;--shiki-dark:#AE81FF}",{"title":98,"searchDepth":391,"depth":391,"links":392},2,[],{"issue":394,"comments":398},{"number":395,"title":396,"html_url":397},53,"[Comment] ASP.NET Core Caching in Practice","https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53",[399,411,420,428,437,445,453,461,470,478,486,494,502,515,526,534,542,550,558],{"id":400,"html_url":401,"body_html":402,"created_at":403,"updated_at":403,"author_association":404,"user":405,"reactions":409},627234453,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234453","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F095e3b4df2a4cc3f7edb4472772f67ce5ee4561792fc4b91cd53b53cc31ff35b\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63376630363935376439373964643932666237643634623764376430303262663f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Robin\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F095e3b4df2a4cc3f7edb4472772f67ce5ee4561792fc4b91cd53b53cc31ff35b\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63376630363935376439373964643932666237643634623764376430303262663f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"http:\u002F\u002Ffloodassist.co.uk\u002F\">Robin\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-10-26 15:48:26\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>hmmm, I'm doing similar things by adding the following to my Configure method in startup.cs:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>app\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>UseStaticFiles\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>new\u003C\u002Fspan> \u003Cspan>StaticFileOptions\u003C\u002Fspan>\n\u003Cspan>{\u003C\u002Fspan>\n    \u003Cspan>OnPrepareResponse\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan> \u003Cspan>ctx\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan>\n    \u003Cspan>{\u003C\u002Fspan>\n        \u003Cspan>const\u003C\u002Fspan> int durationInSeconds \u003Cspan>=\u003C\u002Fspan> \u003Cspan>60\u003C\u002Fspan> \u003Cspan>*\u003C\u002Fspan> \u003Cspan>60\u003C\u002Fspan> \u003Cspan>*\u003C\u002Fspan> \u003Cspan>24\u003C\u002Fspan> \u003Cspan>*\u003C\u002Fspan> \u003Cspan>1\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>\u002F\u002Fone day!\u003C\u002Fspan>\n        ctx\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Context\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Response\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Headers\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Add\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>\"cache-control\"\u003C\u002Fspan>\u003Cspan>,\u003C\u002Fspan> \u003Cspan>new\u003C\u002Fspan>\u003Cspan>[\u003C\u002Fspan>\u003Cspan>]\u003C\u002Fspan> \u003Cspan>{\u003C\u002Fspan> \u003Cspan>\"public,max-age=\"\u003C\u002Fspan> \u003Cspan>+\u003C\u002Fspan> \u003Cspan>durationInSeconds\u003C\u002Fspan> \u003Cspan>}\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\n        ctx\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Context\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Response\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Headers\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Add\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>\"Expires\"\u003C\u002Fspan>\u003Cspan>,\u003C\u002Fspan> \u003Cspan>new\u003C\u002Fspan>\u003Cspan>[\u003C\u002Fspan>\u003Cspan>]\u003C\u002Fspan> \u003Cspan>{\u003C\u002Fspan> \u003Cspan>DateTime\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>UtcNow\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>AddSeconds\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>durationInSeconds\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>ToString\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>\"R\"\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan> \u003Cspan>}\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>\u002F\u002F Format RFC1123\u003C\u002Fspan>\n    \u003Cspan>}\u003C\u002Fspan>\n\u003Cspan>}\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>I'm only concerned with caching \"big\" things like images etc (which is why its for static files).\u003C\u002Fp>","2020-05-12T09:47:33Z","OWNER",{"login":406,"avatar_url":407,"html_url":408},"RehanSaeed","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2270364?v=4","https:\u002F\u002Fgithub.com\u002FRehanSaeed",{"url":410,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234453\u002Freactions",{"id":412,"html_url":413,"body_html":414,"created_at":415,"updated_at":416,"author_association":404,"user":417,"reactions":418},627234506,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234506","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F0e25150d582639209d75a3759473963fd9037a9855f9d038ba458448366d4f1a\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37643566306636396566323735353137633232303437656339663761663332303f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Shahzad Hassan\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F0e25150d582639209d75a3759473963fd9037a9855f9d038ba458448366d4f1a\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37643566306636396566323735353137633232303437656339663761663332303f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fwww.softmatters.co.uk\u002F\">Shahzad Hassan\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-10-26 16:08:14\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Thanks for sharing. Yet again, a very nice blog indeed. I have a question for you.\u003C\u002Fp>\n\u003Cp>I know that Response Caching cannot be used if \u003Ccode>Authorization\u003C\u002Fcode> header is present in the request. I have a scenario where multiple API subscribers need to pass in a \u003Ccode>Bearer\u003C\u002Fcode> token in the \u003Ccode>Authorization\u003C\u002Fcode> header so the request can be authenticated\u002Fauthorized. However, the response of a REST API call is exactly the same regardless of who is calling, as far as they are authenticated.\u003C\u002Fp>\n\u003Cp>How would you approach to solve this particular problem? Would you recommend implementing a custom caching layer using \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fmvc\u002Fcontrollers\u002Ffilters#resource-filters\">ResourceFilters\u003C\u002Fa> or something as they will be second in a row after the \u003Ccode>AuthorizeFilters\u003C\u002Fcode>? What are your thoughts on it?\u003C\u002Fp>\n\u003Cp>Thanks\u003C\u002Fp>","2020-05-12T09:47:40Z","2020-05-12T12:55:42Z",{"login":406,"avatar_url":407,"html_url":408},{"url":419,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234506\u002Freactions",{"id":421,"html_url":422,"body_html":423,"created_at":424,"updated_at":424,"author_association":404,"user":425,"reactions":426},627234544,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234544","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-11-13 09:03:31\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>hmmm, I'm doing similar things by adding the following to my Configure method in startup.cs:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>app\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>UseStaticFiles\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>new\u003C\u002Fspan> \u003Cspan>StaticFileOptions\u003C\u002Fspan>\n\u003Cspan>{\u003C\u002Fspan>\n    \u003Cspan>OnPrepareResponse\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan> \u003Cspan>ctx\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan>\n    \u003Cspan>{\u003C\u002Fspan>\n        \u003Cspan>const\u003C\u002Fspan> int durationInSeconds \u003Cspan>=\u003C\u002Fspan> \u003Cspan>60\u003C\u002Fspan> \u003Cspan>*\u003C\u002Fspan> \u003Cspan>60\u003C\u002Fspan> \u003Cspan>*\u003C\u002Fspan> \u003Cspan>24\u003C\u002Fspan> \u003Cspan>*\u003C\u002Fspan> \u003Cspan>1\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>\u002F\u002Fone day!\u003C\u002Fspan>\n        \u003Cspan>ctx\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Context\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Response\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Headers\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Add\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>\"cache-control\"\u003C\u002Fspan>\u003Cspan>,\u003C\u002Fspan> \u003Cspan>new\u003C\u002Fspan>\u003Cspan>[\u003C\u002Fspan>\u003Cspan>]\u003C\u002Fspan> \u003Cspan>{\u003C\u002Fspan> \u003Cspan>\"public,max-age=\"\u003C\u002Fspan> \u003Cspan>+\u003C\u002Fspan> \u003Cspan>durationInSeconds\u003C\u002Fspan> \u003Cspan>}\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\n        ctx\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Context\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Response\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Headers\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Add\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>\"Expires\"\u003C\u002Fspan>\u003Cspan>,\u003C\u002Fspan> \u003Cspan>new\u003C\u002Fspan>\u003Cspan>[\u003C\u002Fspan>\u003Cspan>]\u003C\u002Fspan> \u003Cspan>{\u003C\u002Fspan> \u003Cspan>DateTime\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>UtcNow\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>AddSeconds\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>durationInSeconds\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>ToString\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>\"R\"\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan> \u003Cspan>}\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>\u002F\u002F Format RFC1123\u003C\u002Fspan>\n    \u003Cspan>}\u003C\u002Fspan>\n\u003Cspan>}\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>I'm only concerned with caching \"big\" things like images etc (which is why its for static files).\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Looks reasonable. Setting \u003Ccode>Cache-Control\u003C\u002Fcode>, \u003Ccode>Expires\u003C\u002Fcode> and \u003Ccode>Pragma\u003C\u002Fcode> HTTP headers is complicated, which is why I use the helper method.\u003C\u002Fp>","2020-05-12T09:47:46Z",{"login":406,"avatar_url":407,"html_url":408},{"url":427,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234544\u002Freactions",{"id":429,"html_url":430,"body_html":431,"created_at":432,"updated_at":433,"author_association":404,"user":434,"reactions":435},627234595,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234595","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-11-13 09:11:13\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Thanks for sharing. Yet again, a very nice blog indeed. I have a question for you.\u003C\u002Fp>\n\u003Cp>I know that Response Caching cannot be used if \u003Ccode>Authorization\u003C\u002Fcode> header is present in the request. I have a scenario where multiple API subscribers need to pass in a \u003Ccode>Bearer\u003C\u002Fcode> token in the \u003Ccode>Authorization\u003C\u002Fcode> header so the request can be authenticated\u002Fauthorized. However, the response of a REST API call is exactly the same regardless of who is calling, as far as they are authenticated.\u003C\u002Fp>\n\u003Cp>How would you approach to solve this particular problem? Would you recommend implementing a custom caching layer using \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fmvc\u002Fcontrollers\u002Ffilters#resource-filters\">ResourceFilters\u003C\u002Fa> or something as they will be second in a row after the \u003Ccode>AuthorizeFilters\u003C\u002Fcode>? What are your thoughts on it?\u003C\u002Fp>\n\u003Cp>Thanks\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fgithub.com\u002Faspnet\u002FResponseCaching\u002Fissues\u002F128\">This\u003C\u002Fa> GitHub issue in the aspnet\u002FResponseCache repository deals with caching being turned off when the \u003Ccode>Authorization\u003C\u002Fcode> HTTP header is present.\u003C\u002Fp>\n\u003Cp>In my opinion, the best way to go might be to override or replace the logic in the \u003Ccode>ResponseCache\u003C\u002Fcode> middleware where caching is turned off based on the \u003Ccode>Authorization\u003C\u002Fcode> HTTP header.\u003C\u002Fp>","2020-05-12T09:47:53Z","2020-05-12T12:55:53Z",{"login":406,"avatar_url":407,"html_url":408},{"url":436,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234595\u002Freactions",{"id":438,"html_url":439,"body_html":440,"created_at":441,"updated_at":441,"author_association":404,"user":442,"reactions":443},627234653,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234653","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F0e25150d582639209d75a3759473963fd9037a9855f9d038ba458448366d4f1a\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37643566306636396566323735353137633232303437656339663761663332303f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Shahzad Hassan\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F0e25150d582639209d75a3759473963fd9037a9855f9d038ba458448366d4f1a\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37643566306636396566323735353137633232303437656339663761663332303f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Shahzad Hassan\u003C\u002Fstrong> commented on \u003Cstrong>2017-11-23 08:26:51\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fgithub.com\u002Faspnet\u002FResponseCaching\u002Fissues\u002F128\">This\u003C\u002Fa> GitHub issue in the aspnet\u002FResponseCache repository deals with caching being turned off when the Authorization HTTP header is present.\u003C\u002Fp>\n\u003Cp>In my opinion, the best way to go might be to override or replace the logic in the \u003Ccode>ResponseCache\u003C\u002Fcode> middleware where caching is turned off based on the \u003Ccode>Authorization\u003C\u002Fcode> HTTP header.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Ok, Thanks. Makes sense, l will have a look.\u003C\u002Fp>","2020-05-12T09:48:00Z",{"login":406,"avatar_url":407,"html_url":408},{"url":444,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234653\u002Freactions",{"id":446,"html_url":447,"body_html":448,"created_at":449,"updated_at":449,"author_association":404,"user":450,"reactions":451},627234705,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234705","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F97f955c2d8396debf29d1fbdb913ce2ae703b11db57ddef581dc6748cedccf82\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f62636530356332376530373566306265643031633164656365613334333263363f733d393626643d6d6d26723d67\">\u003Cimg alt=\"John\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F97f955c2d8396debf29d1fbdb913ce2ae703b11db57ddef581dc6748cedccf82\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f62636530356332376530373566306265643031633164656365613334333263363f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>John\u003C\u002Fstrong> commented on \u003Cstrong>2018-06-29 08:16:29\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Nice post. The way you controller works it's kind confusing me. You always hit the db to fetch all the data anyway.. so no much optimization there. Or maybe was just a silly example? Thanks!\u003C\u002Fp>","2020-05-12T09:48:06Z",{"login":406,"avatar_url":407,"html_url":408},{"url":452,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234705\u002Freactions",{"id":454,"html_url":455,"body_html":456,"created_at":457,"updated_at":457,"author_association":404,"user":458,"reactions":459},627234755,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234755","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2018-06-29 09:23:56\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Nice post. The way you controller works it's kind confusing me. You always hit the db to fetch all the data anyway.. so no much optimization there. Or maybe was just a silly example? Thanks!\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Yes, that's a good point. The code I've shown optimises what gets sent over the wire but not the database calls. If you wanted to optimise the database call, you could start with a query that returns the count for the number of items and the latest modified timestamp and use that to figure out if you need to do another query to get all of the data or return a 304 not modified response.\u003C\u002Fp>","2020-05-12T09:48:13Z",{"login":406,"avatar_url":407,"html_url":408},{"url":460,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234755\u002Freactions",{"id":462,"html_url":463,"body_html":464,"created_at":465,"updated_at":466,"author_association":404,"user":467,"reactions":468},627234798,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234798","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F5d0e61aadaeab789925a1b7811f32f3019ebb96bf6a64f8f5f0b4d61f91b5117\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65653862333962633233363632323633616361613063373331333164346363383f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Noah\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F5d0e61aadaeab789925a1b7811f32f3019ebb96bf6a64f8f5f0b4d61f91b5117\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65653862333962633233363632323633616361613063373331333164346363383f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Noah\u003C\u002Fstrong> commented on \u003Cstrong>2018-11-16 07:43:47\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Great article about caching. While, I have read HTTP-based cache mechanism \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fperformance\u002Fcaching\u002Fresponse?view=aspnetcore-2.1\">here\u003C\u002Fa>, and I want to know does HTTP-based cache make sense for an Web API application? Back to your example for \u003Ccode>Last-Modified\u003C\u002Fcode> &amp; \u003Ccode>If-Modified-Since\u003C\u002Fcode>, is it reasonable for an API client receiving 304 response? Could you provide some advice and best practices about implementing HTTP-based cache for a Web API application? Thanks.\u003C\u002Fp>","2020-05-12T09:48:20Z","2020-05-12T09:48:33Z",{"login":406,"avatar_url":407,"html_url":408},{"url":469,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234798\u002Freactions",{"id":471,"html_url":472,"body_html":473,"created_at":474,"updated_at":474,"author_association":404,"user":475,"reactions":476},627234862,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234862","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2018-11-16 09:06:25\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Great article about caching. While, I have read HTTP-based cache mechanism \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fperformance\u002Fcaching\u002Fresponse?view=aspnetcore-2.1\">here\u003C\u002Fa>, and I want to know does HTTP-based cache make sense for an Web API application? Back to your example for \u003Ccode>Last-Modified\u003C\u002Fcode> &amp; \u003Ccode>If-Modified-Since\u003C\u002Fcode>, is it reasonable for an API client receiving 304 response? Could you provide some advice and best practices about implementing HTTP-based cache for a Web API application? Thanks.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>It does make sense sometimes. If the resource you are getting has a last modified date that you store in the database, you can take that and turn it into \u003Ccode>Last-Modified\u003C\u002Fcode> &amp; \u003Ccode>If-Modified-Since\u003C\u002Fcode> HTTP headers. If your client is a web browser, then it will respect the header. If the client is custom code such as C#'s \u003Ccode>HttpClient\u003C\u002Fcode>, then you will need to write some extra code to respect the HTTP headers and cache responses.\u003C\u002Fp>","2020-05-12T09:48:27Z",{"login":406,"avatar_url":407,"html_url":408},{"url":477,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234862\u002Freactions",{"id":479,"html_url":480,"body_html":481,"created_at":482,"updated_at":482,"author_association":404,"user":483,"reactions":484},627234931,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234931","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2018-12-01 10:59:58\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Great article about caching. While, I have read HTTP-based cache mechanism \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fperformance\u002Fcaching\u002Fresponse?view=aspnetcore-2.1\">here\u003C\u002Fa>, and I want to know does HTTP-based cache make sense for an Web API application? Back to your example for \u003Ccode>Last-Modified\u003C\u002Fcode> &amp; \u003Ccode>If-Modified-Since\u003C\u002Fcode>, is it reasonable for an API client receiving 304 response? Could you provide some advice and best practices about implementing HTTP-based cache for a Web API application? Thanks.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>I can make sense for an API. You just need to know when the resource was last changed. Also, the client has to support caching headers and store resources in some way that makes sense.\u003C\u002Fp>","2020-05-12T09:48:34Z",{"login":406,"avatar_url":407,"html_url":408},{"url":485,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234931\u002Freactions",{"id":487,"html_url":488,"body_html":489,"created_at":490,"updated_at":490,"author_association":404,"user":491,"reactions":492},627234997,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627234997","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F5e0cbb5e5f680a77bb3567e6068a7f0b1fdf7326c969dc1323eaaa0bfade2d40\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34343031383135303037366631653430663138363663623532346435323565353f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Abhi\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F5e0cbb5e5f680a77bb3567e6068a7f0b1fdf7326c969dc1323eaaa0bfade2d40\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34343031383135303037366631653430663138363663623532346435323565353f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Abhi\u003C\u002Fstrong> commented on \u003Cstrong>2019-04-12 12:37:50\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Hi,\u003C\u002Fp>\n\u003Cp>Thank you for good article,\u003C\u002Fp>\n\u003Cp>I am getting error on the line\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>var\u003C\u002Fspan> \u003Cspan>cacheProfiles\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan> \u003Cspan>this\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>configuration\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>GetSection\u003C\u002Fspan>\u003Cspan>&lt;\u003C\u002Fspan>\u003Cspan>Dictionary\u003C\u002Fspan>\u003Cspan>&lt;\u003C\u002Fspan>\u003Cspan>string\u003C\u002Fspan>\u003Cspan>,\u003C\u002Fspan> \u003Cspan>CacheProfile\u003C\u002Fspan>\u003Cspan>&gt;\u003C\u002Fspan>\u003Cspan>&gt;\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>GetSection not supporting..\u003C\u002Fp>\n\u003Cp>.netcore 2.1 framework\u003C\u002Fp>","2020-05-12T09:48:41Z",{"login":406,"avatar_url":407,"html_url":408},{"url":493,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627234997\u002Freactions",{"id":495,"html_url":496,"body_html":497,"created_at":498,"updated_at":498,"author_association":404,"user":499,"reactions":500},627235062,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-627235062","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002Fc918ba8e7337b7c49e08f2ddb97846155fcd9598aaef780b13515dc87345cb2a\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63366530373537303839626336653834326663633361656264306439316433313f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Al Stevens\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002Fc918ba8e7337b7c49e08f2ddb97846155fcd9598aaef780b13515dc87345cb2a\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63366530373537303839626336653834326663633361656264306439316433313f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Al Stevens\u003C\u002Fstrong> commented on \u003Cstrong>2019-12-16 17:49:31\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Hi,\u003C\u002Fp>\n\u003Cp>Thank you for good article,\u003C\u002Fp>\n\u003Cp>I am getting error on the line\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>var\u003C\u002Fspan> \u003Cspan>cacheProfiles\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan> \u003Cspan>this\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>configuration\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>GetSection\u003C\u002Fspan>\u003Cspan>&lt;\u003C\u002Fspan>\u003Cspan>Dictionary\u003C\u002Fspan>\u003Cspan>&lt;\u003C\u002Fspan>\u003Cspan>string\u003C\u002Fspan>\u003Cspan>,\u003C\u002Fspan> \u003Cspan>CacheProfile\u003C\u002Fspan>\u003Cspan>&gt;\u003C\u002Fspan>\u003Cspan>&gt;\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>GetSection not supporting..\u003C\u002Fp>\n\u003Cp>.netcore 2.1 framework\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Abhi,\u003C\u002Fp>\n\u003Cp>I hit the same thing too, you need to change it to the following:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>var\u003C\u002Fspan> \u003Cspan>cacheProfiles\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan> \u003Cspan>this\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>configuration\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>GetSection\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>\"CacheProfiles\"\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Get\u003C\u002Fspan>\u003Cspan>&lt;\u003C\u002Fspan>\u003Cspan>Dictionary\u003C\u002Fspan>\u003Cspan>&lt;\u003C\u002Fspan>\u003Cspan>string\u003C\u002Fspan>\u003Cspan>,\u003C\u002Fspan> \u003Cspan>CacheProfile\u003C\u002Fspan>\u003Cspan>&gt;\u003C\u002Fspan>\u003Cspan>&gt;\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Hope that helps.\u003C\u002Fp>","2020-05-12T09:48:48Z",{"login":406,"avatar_url":407,"html_url":408},{"url":501,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627235062\u002Freactions",{"id":503,"html_url":504,"body_html":505,"created_at":506,"updated_at":506,"author_association":507,"user":508,"reactions":512},688483940,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-688483940","\u003Cp>Thanks the article helped me\u003C\u002Fp>","2020-09-07T19:28:42Z","NONE",{"login":509,"avatar_url":510,"html_url":511},"xhafan","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F13038902?v=4","https:\u002F\u002Fgithub.com\u002Fxhafan",{"url":513,"total_count":514,"+1":514,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F688483940\u002Freactions",1,{"id":516,"html_url":517,"body_html":518,"created_at":519,"updated_at":519,"author_association":507,"user":520,"reactions":524},773352843,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-773352843","\u003Cp>I'm trying to do the same thing you described in the 'Last-Modified &amp; If-Modified-Since' section.  However, after the initial call to the controller, Chrome (and I tested FF too) doesn't even call back to my controller.  I simply returns like this:\u003C\u002Fp>\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F6237247\u002F106906603-f67ce180-66c2-11eb-9ee0-c7766f3e5229.png\">\u003Cimg alt=\"image\" src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F6237247\u002F106906603-f67ce180-66c2-11eb-9ee0-c7766f3e5229.png\" \u002F>\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>It says \u003Cem>(disk cache)\u003C\u002Fem>.  I haven't done any 'configuration setup' in \u003Ccode>Startup\u003C\u002Fcode>.  I simply implemented code for checking if-modified-since against our database timestamp.  Do I need code in \u003Ccode>Startup\u003C\u002Fcode> to make this work?\u003C\u002Fp>","2021-02-04T14:30:26Z",{"login":521,"avatar_url":522,"html_url":523},"terryaney","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6237247?v=4","https:\u002F\u002Fgithub.com\u002Fterryaney",{"url":525,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F773352843\u002Freactions",{"id":527,"html_url":528,"body_html":529,"created_at":530,"updated_at":530,"author_association":404,"user":531,"reactions":532},773395331,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-773395331","\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fgithub.com\u002Fterryaney\">@terryaney\u003C\u002Fa> If you've implemented the headers you mention correctly and the header is telling the browser that a resource has not been modified since it last made a request to the resource then the browser will cache that resource. This is why you get a 'disk cache' in the browsers network tab. Is that not what you want?\u003C\u002Fp>","2021-02-04T15:31:02Z",{"login":406,"avatar_url":407,"html_url":408},{"url":533,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F773395331\u002Freactions",{"id":535,"html_url":536,"body_html":537,"created_at":538,"updated_at":538,"author_association":507,"user":539,"reactions":540},773441088,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-773441088","\u003Cp>I'm just saying that it doesn't even post back to my action so that I can check 'if-modified-since' against my database.  The browser just caches it itself.  So when I update the resource in our database, the new version is never returned because it doesn't hit my code.\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Ccode>protected async Task&lt;IActionResult&gt; CachedOrModifiedAsync( CacheDownloadInfo cacheDownloadInfo, IDbConnectionFactory dbConnectionFactory )\n{\n\tvar lastModifiedDate = cacheDownloadInfo.LastModifiedDate.Value.ToUniversalTime();\n\n\t\u002F\u002F https:\u002F\u002Frehansaeed.com\u002Fasp-net-core-caching-in-practice\u002F#last-modified--if-modified-since\n\t\u002F\u002F https:\u002F\u002Fwww.geekytidbits.com\u002Fefficient-caching-dynamic-resources-asp-net-304-not-modified\u002F\n\tvar requestHeaders = HttpContext.Request.GetTypedHeaders();\n\tif ( !requestHeaders.IfModifiedSince.HasValue )\n\t{\n\t\t\u002F\u002F Set Last Modified time\n\t\tHttpContext.Response.GetTypedHeaders().LastModified = lastModifiedDate;\n\t}\n\telse\n\t{\n\t\t\u002F\u002F HTTP does not provide milliseconds, so remove it from the comparison\n\t\tif ( lastModifiedDate.AddMilliseconds( -lastModifiedDate.Millisecond ) == requestHeaders.IfModifiedSince.Value )\n\t\t{\n\t\t\treturn NotModified();\n\t\t}\n\t}\n\n\tvar bds = new SqlBinaryDataStream&lt;Guid&gt;( dbConnectionFactory.GetDataLockerConnectionString(), \"Cache\", \"UID\", \"Content\", cacheDownloadInfo.Token.Value );\n\treturn new FileStreamResult( await bds.ContentIsCompressedAsync ? new GZipStream( bds, CompressionMode.Decompress ) : bds, cacheDownloadInfo.ContentType );\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>","2021-02-04T16:35:45Z",{"login":521,"avatar_url":522,"html_url":523},{"url":541,"total_count":514,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":514},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F773441088\u002Freactions",{"id":543,"html_url":544,"body_html":545,"created_at":546,"updated_at":546,"author_association":404,"user":547,"reactions":548},773492630,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-773492630","\u003Cp>Perhaps consider creating a small sample app and posting the question on StackOverflow to get some eyes on it (I'll also take a look).\u003C\u002Fp>","2021-02-04T17:51:25Z",{"login":406,"avatar_url":407,"html_url":408},{"url":549,"total_count":4,"+1":4,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F773492630\u002Freactions",{"id":551,"html_url":552,"body_html":553,"created_at":554,"updated_at":554,"author_association":507,"user":555,"reactions":556},773563957,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-773563957","\u003Cp>I didn't make a 'sample app'.  I just pasted my controller and caching code.  \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F66052852\u002Fasp-net-core-web-api-checking-if-modified-since-header-not-working-because-brows\">https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F66052852\u002Fasp-net-core-web-api-checking-if-modified-since-header-not-working-because-brows\u003C\u002Fa>  Will see if anyone has ideas.\u003C\u002Fp>","2021-02-04T19:51:52Z",{"login":521,"avatar_url":522,"html_url":523},{"url":557,"total_count":514,"+1":514,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F773563957\u002Freactions",{"id":559,"html_url":560,"body_html":561,"created_at":562,"updated_at":563,"author_association":507,"user":564,"reactions":565},774326481,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F53#issuecomment-774326481","\u003Cp>FYI, I updated my stack overflow answer \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fstackoverflow.com\u002Fa\u002F66067418\u002F166231\">here\u003C\u002Fa>.  But to make this work with Swagger (maybe other clients as well), I had to put the following:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Ccode>responseHeaders.CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue\n{\n\tPublic = true,\n\tMustRevalidate = true,\n\tMaxAge = new TimeSpan( 0, 0, 0 ),\n};\nresponseHeaders.Expires = DateTime.UtcNow;\n\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>","2021-02-05T22:38:56Z","2021-02-05T22:39:16Z",{"login":521,"avatar_url":522,"html_url":523},{"url":566,"total_count":514,"+1":514,"-1":4,"laugh":4,"hooray":4,"confused":4,"heart":4,"rocket":4,"eyes":4},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F774326481\u002Freactions","2017-10-20T00:00:00+00:00",null,"How to use and implement Cache-Control, Cache-Control Immutable, E-Tag, Last-Modified and If-Modified-Since Caching HTTP headers in ASP.NET Core.","md",[572,573,574,575,576],{"depth":514,"value":68},{"depth":391,"value":146},{"depth":514,"value":247},{"depth":514,"value":315},{"depth":514,"value":373},"\u002Fimages\u002Fhero\u002FASP.NET-Core-Caching-in-Practice-1366x768.png",{},"\u002Fasp-net-core-caching-in-practice\u002F",true,"posts\u002F2017\u002Fasp-net-core-caching-in-practice\u002Findex",[583,584,585,586,587,82,588,264,328],".NET",".NET Core","ASP.NET Core","ASP.NET MVC","C#","Caching",5,[591,595,599,604,609,612,615,619,623,627,630,634,639,642,645,648,652,656,659,663,667,671,674,679,684,688,691,694,697,702,706,709,714,718,722,726,729,733,737,741,745,749,753,757,760,764,768,772,776,779,783,787,790,793,797,801,806,810,814,818,822,823,827,830,833,836,840,844,847,851,854,857,860,863,867,871,874,877,881,885,888,891,894,898,902,906,910,913,916,921,924,927,931,934,938,942,945,949,952,955,959,963,967],{"title":592,"permalink":593,"heroImage":594,"timeToRead":514},"Just Start - The First Blog Post","\u002Fjust-start-the-first-blog-post\u002F","\u002Fimages\u002Fhero\u002FJust-Start-1366x768.png",{"title":596,"permalink":597,"heroImage":598,"timeToRead":391},"ConfigureAwait in Task Parallel Library (TPL)","\u002Fconfigureawait-task-parallel-library\u002F","\u002Fimages\u002Fhero\u002FMicrosoft-.NET-1366x768.png",{"title":600,"permalink":601,"heroImage":602,"timeToRead":603},"Stop The Brace Wars, Use StyleCop","\u002Fstop-brace-wars-use-stylecop\u002F","\u002Fimages\u002Fhero\u002FStyleCop-1366x768.png",3,{"title":605,"permalink":606,"heroImage":607,"timeToRead":608},"Reactive Extensions (Rx) - Part 1 - Replacing C# Events","\u002Freactive-extensions-part1-replacing-events\u002F","\u002Fimages\u002Fhero\u002FReactive-Extensions-1366x768.png",4,{"title":610,"permalink":611,"heroImage":607,"timeToRead":603},"Reactive Extensions (Rx) - Part 2 - Wrapping C# Events","\u002Freactive-extensions-part2-wrapping-events\u002F",{"title":613,"permalink":614,"heroImage":607,"timeToRead":391},"Reactive Extensions (Rx) - Part 3 - Naming Conventions","\u002Freactive-extensions-part3-naming-conventions\u002F",{"title":616,"permalink":617,"heroImage":618,"timeToRead":603},"WPF Metro Part 1 - Modern UI for WPF","\u002Fwpf-metro-part1-modern-ui-for-wpf\u002F","\u002Fimages\u002Fhero\u002FModern-UI-for-WPF-1366x768.png",{"title":620,"permalink":621,"heroImage":622,"timeToRead":603},"WPF Metro Part 2 - MahApps Metro","\u002Fwpf-metro-part2-mahapps-metro\u002F","\u002Fimages\u002Fhero\u002FMahApps-Metro-1366x768.png",{"title":624,"permalink":625,"heroImage":626,"timeToRead":603},"Windows 8.1 TouchScreen Gaming Laptops","\u002Fwindows-8-touchscreen-gaming-laptops\u002F","\u002Fimages\u002Fhero\u002FFry-Shutup-And-Take-My-Money-1366x768.png",{"title":628,"permalink":629,"heroImage":607,"timeToRead":603},"Reactive Extensions (Rx) - Part 4 - Replacing Timers","\u002Freactive-extensions-part4-replacing-timers\u002F",{"title":631,"permalink":632,"heroImage":633,"timeToRead":391},"WPF Metro Part 3 - Elysium","\u002Fwpf-metro-part3-elysium\u002F","\u002Fimages\u002Fhero\u002FElysium-1366x768.png",{"title":635,"permalink":636,"heroImage":637,"timeToRead":638},"WPF Metro Part 4 - Elysium Extra","\u002Fwpf-metro-part4-elysium-extra\u002F","\u002Fimages\u002Fhero\u002FElysium-Extra-1366x768.png",8,{"title":640,"permalink":641,"heroImage":607,"timeToRead":608},"Reactive Extensions (Rx) - Part 5 - Awaiting Observables","\u002Freactive-extensions-part5-awaiting-observables\u002F",{"title":643,"permalink":644,"heroImage":598,"timeToRead":638},"GetHashCode Made Easy","\u002Fgethashcode-made-easy\u002F",{"title":646,"permalink":647,"heroImage":607,"timeToRead":589},"Reactive Extensions (Rx) - Part 6 - Task ToObservable","\u002Freactive-extensions-part6-task-toobservable\u002F",{"title":649,"permalink":650,"heroImage":651,"timeToRead":514},"Portable Class Library (PCL) version of NotificationsExtensions NuGet package","\u002Fportable-class-library-version-of-notificationsextensions-nuget-package\u002F","\u002Fimages\u002Fhero\u002FNuGet-1366x768.png",{"title":653,"permalink":654,"heroImage":655,"timeToRead":589},"Model-View-ViewModel (MVVM) - Part 1 - Overview","\u002Fmodel-view-viewmodel-mvvm-part1-overview\u002F","\u002Fimages\u002Fhero\u002FMVVM-1366x768.png",{"title":657,"permalink":658,"heroImage":655,"timeToRead":608},"Model-View-ViewModel (MVVM) - Part 2 - IDisposable","\u002Fmodel-view-viewmodel-mvvm-part2-idisposable\u002F",{"title":660,"permalink":661,"heroImage":655,"timeToRead":662},"Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged","\u002Fmodel-view-viewmodel-mvvm-part3-inotifypropertychanged\u002F",11,{"title":664,"permalink":665,"heroImage":666,"timeToRead":603},"Naming Conventions","\u002Fnaming-conventions\u002F","\u002Fimages\u002Fhero\u002FNaming-Conventions-1366x768.png",{"title":668,"permalink":669,"heroImage":655,"timeToRead":670},"Model-View-ViewModel (MVVM) - Part 4 - INotifyDataErrorInfo","\u002Fmodel-view-viewmodel-mvvm-part4-inotifydataerrorinfo\u002F",12,{"title":672,"permalink":673,"heroImage":637,"timeToRead":608},"Elysium Extra 1.1 Released","\u002Felysium-extra-1-1-released\u002F",{"title":675,"permalink":676,"heroImage":677,"timeToRead":678},"ASP.NET Core Boilerplate","\u002Fasp-net-mvc-boilerplate\u002F","\u002Fimages\u002Fhero\u002FASP.NET-Core-Boilerplate-1366x768.png",7,{"title":680,"permalink":681,"heroImage":682,"timeToRead":683},"Internet Favicon Madness (Updated)","\u002Finternet-favicon-madness\u002F","\u002Fimages\u002Fhero\u002FFavicons-1366x768.png",17,{"title":685,"permalink":686,"heroImage":687,"timeToRead":678},"Custom Visual Studio Project Templates","\u002Fcustom-visual-studio-project-templates\u002F","\u002Fimages\u002Fhero\u002FVisual-Studio-1366x768.png",{"title":689,"permalink":690,"heroImage":687,"timeToRead":603},"Configuration File Transforms In Visual Studio Should Be Built In","\u002Fconfiguration-file-transforms-in-visual-studio-should-be-built-in\u002F",{"title":692,"permalink":693,"heroImage":677,"timeToRead":662},"Securing the ASP.NET MVC Web.config","\u002Fsecuring-the-aspnet-mvc-web-config\u002F",{"title":695,"permalink":696,"heroImage":607,"timeToRead":391},"Reactive Extensions (Rx) - Part 7 - Sample Events","\u002Freactive-extensions-part7-sample-events\u002F",{"title":698,"permalink":699,"heroImage":700,"timeToRead":701},"NWebSec ASP.NET MVC Security Through HTTP Headers","\u002Fnwebsec-asp-net-mvc-security-through-http-headers\u002F","\u002Fimages\u002Fhero\u002FNWebSec-1366x768.png",6,{"title":703,"permalink":704,"heroImage":705,"timeToRead":60},"Content Security Policy (CSP) for ASP.NET MVC","\u002Fcontent-security-policy-for-asp-net-mvc\u002F","\u002Fimages\u002Fhero\u002FContent-Security-Policy-CSP-for-ASP.NET-MVC-1366x768.png",{"title":707,"permalink":708,"heroImage":598,"timeToRead":589},"C# 6.0 - Saving Developers From Themselves","\u002Fc-6-0-saving-developers-from-themselves\u002F",{"title":710,"permalink":711,"heroImage":712,"timeToRead":713},"Building RSS\u002FAtom Feeds for ASP.NET MVC","\u002Fbuilding-rssatom-feeds-for-asp-net-mvc\u002F","\u002Fimages\u002Fhero\u002FRSS-And-Atom-1366x768.png",19,{"title":715,"permalink":716,"heroImage":717,"timeToRead":662},"Canonical URL's for ASP.NET MVC","\u002Fcanonical-urls-for-asp-net-mvc\u002F","\u002Fimages\u002Fhero\u002FLink-Juice-1366x768.png",{"title":719,"permalink":720,"heroImage":721,"timeToRead":608},"Dynamically Generating Robots.txt Using ASP.NET MVC","\u002Fdynamically-generating-robots-txt-using-asp-net-mvc\u002F","\u002Fimages\u002Fhero\u002FRobots.txt-1366x768.jpg",{"title":723,"permalink":724,"heroImage":725,"timeToRead":608},"Minifying HTML for ASP.NET MVC","\u002Fminifying-html-for-asp-net-mvc\u002F","\u002Fimages\u002Fhero\u002FThe-Internet-Is-A-Series-Of-Tubes-1366x768.jpg",{"title":727,"permalink":728,"heroImage":677,"timeToRead":391},"Whats New in ASP.NET Core Boilerplate","\u002Fwhats-new-in-asp-net-5-mvc-6-boilerplate\u002F",{"title":730,"permalink":731,"heroImage":732,"timeToRead":678},"Dynamically Generating Sitemap.xml for ASP.NET MVC","\u002Fdynamically-generating-sitemap-xml-for-asp-net-mvc\u002F","\u002Fimages\u002Fhero\u002FSitemaps-1366x768.png",{"title":734,"permalink":735,"heroImage":736,"timeToRead":391},"So I've Been Awarded Microsoft MVP Status!","\u002Fso-ive-been-awarded-microsoft-mvp-status\u002F","\u002Fimages\u002Fhero\u002FMicrosoft-MVP-1366x768.png",{"title":738,"permalink":739,"heroImage":740,"timeToRead":514},".NET Big-O Algorithm Complexity Cheat Sheet","\u002Fnet-big-o-algorithm-complexity-cheat-sheet\u002F","\u002Fimages\u002Fhero\u002FNET-Big-O-Algorithm-Complexity-Cheat-Sheet-1366x768.jpg",{"title":742,"permalink":743,"heroImage":744,"timeToRead":603},"Logging with Serilog.Exceptions","\u002Flogging-with-serilog-exceptions\u002F","\u002Fimages\u002Fhero\u002FSerilog.Exceptions-1366x768.png",{"title":746,"permalink":747,"heroImage":748,"timeToRead":514},"Make Certificate","\u002Fmake-certificate\u002F","\u002Fimages\u002Fhero\u002FMake-Certificate-1366x768.png",{"title":750,"permalink":751,"heroImage":752,"timeToRead":391},"Colorful.Console","\u002Fcolorful-console\u002F","\u002Fimages\u002Fhero\u002FColorful.Console-1366x768.png",{"title":754,"permalink":755,"heroImage":756,"timeToRead":603},"Subresource Integrity TagHelper Using ASP.NET Core - Part 1","\u002Fsubresource-integrity-taghelper-using-asp-net-core\u002F","\u002Fimages\u002Fhero\u002FMake-Security-Easy-1366x768.png",{"title":758,"permalink":759,"heroImage":756,"timeToRead":608},"Subresource Integrity TagHelper Using ASP.NET Core - Part 2","\u002Fsubresource-integrity-taghelper-using-asp-net-core-part-2\u002F",{"title":761,"permalink":762,"heroImage":763,"timeToRead":589},"Social TagHelpers for ASP.NET Core","\u002Fsocial-taghelpers-for-asp-net-core\u002F","\u002Fimages\u002Fhero\u002FSocial-Media-1366x768.png",{"title":765,"permalink":766,"heroImage":767,"timeToRead":701},"Azure Active Directory Versus Identity Server","\u002Fazure-active-directory-versus-identity-server\u002F","\u002Fimages\u002Fhero\u002FAzure-Active-Directory-Versus-Identity-Server-1366x768.png",{"title":769,"permalink":770,"heroImage":771,"timeToRead":391},"ASP.NET Core Fluent Interface Extensions","\u002Fasp-net-core-fluent-interface-extensions\u002F","\u002Fimages\u002Fhero\u002FFluent-Interface-All-The-Things-1366x768.png",{"title":773,"permalink":774,"heroImage":775,"timeToRead":662},"NGINX for ASP.NET Core In-Depth","\u002Fnginx-asp-net-core-depth\u002F","\u002Fimages\u002Fhero\u002FNGINX-1366x768.png",{"title":777,"permalink":778,"heroImage":598,"timeToRead":391},"The Dotnet Watch Tool","\u002Fthe-dotnet-watch-tool\u002F",{"title":780,"permalink":781,"heroImage":782,"timeToRead":608},"Making Application Insights Fast & Secure","\u002Fmaking-application-insights-fast-and-secure\u002F","\u002Fimages\u002Fhero\u002FApplication-Insights-1366x768.png",{"title":784,"permalink":785,"heroImage":786,"timeToRead":678},"SEO Friendly URL's for ASP.NET Core","\u002Fseo-friendly-urls-asp-net-core\u002F","\u002Fimages\u002Fhero\u002FSearch-Engine-Optimization-SEO-1366x768.png",{"title":788,"permalink":789,"heroImage":607,"timeToRead":514},"Reactive Extensions (Rx) - Part 8 - Timeouts","\u002Freactive-extensions-rx-part-8-timeouts\u002F",{"title":791,"permalink":792,"heroImage":598,"timeToRead":608},"Custom Project Templates Using dotnet new","\u002Fcustom-project-templates-using-dotnet-new\u002F",{"title":794,"permalink":795,"heroImage":796,"timeToRead":638},"Cross-Platform DevOps for .NET Core","\u002Fcross-platform-devops-net-core\u002F","\u002Fimages\u002Fhero\u002FDotnet-Cake-AppVeyor-Travis-1366x768.png",{"title":798,"permalink":799,"heroImage":800,"timeToRead":678},"Cleaning Up CSPROJ","\u002Fcleaning-up-csproj\u002F","\u002Fimages\u002Fhero\u002FCleaning-Up-CSPROJ-1366x768.png",{"title":802,"permalink":803,"heroImage":804,"timeToRead":805},"dotnet new Feature Selection","\u002Fdotnet-new-feature-selection\u002F","\u002Fimages\u002Fhero\u002FWho-Wants-To-Be-A-Millionaire-1366x768.png",9,{"title":807,"permalink":808,"heroImage":809,"timeToRead":608},"ASP.NET Core Lazy Command Pattern","\u002Fasp-net-core-lazy-command-pattern\u002F","\u002Fimages\u002Fhero\u002FASP.NET-Core-Lazy-Command-Pattern-1366x768.png",{"title":811,"permalink":812,"heroImage":813,"timeToRead":391},"Structured Data using Schema.NET","\u002Fstructured-data-using-schema-net\u002F","\u002Fimages\u002Fhero\u002FSchema.NET-1366x768.png",{"title":815,"permalink":816,"heroImage":817,"timeToRead":701},"Keeping Up With Software Development","\u002Fkeeping-software-development\u002F","\u002Fimages\u002Fhero\u002FKeeping-up-with-Software-Development-1366x768.png",{"title":819,"permalink":820,"heroImage":821,"timeToRead":391},"A Very Generic .editorconfig File (Updated)","\u002Fgeneric-editorconfig-file\u002F","\u002Fimages\u002Fhero\u002FA-Very-Generic-Editorconfig-File-1366x768.png",{"title":39,"permalink":579,"heroImage":577,"timeToRead":589},{"title":824,"permalink":825,"heroImage":826,"timeToRead":514},"Docker Read-Only File Systems","\u002Fdocker-read-file-systems\u002F","\u002Fimages\u002Fhero\u002FDocker-1366x768.png",{"title":828,"permalink":829,"heroImage":826,"timeToRead":603},"Docker Labels in Depth","\u002Fdocker-labels-depth\u002F",{"title":831,"permalink":832,"heroImage":826,"timeToRead":608},"Useful Docker Images - Part 1","\u002Fuseful-docker-images-part1\u002F",{"title":834,"permalink":835,"heroImage":826,"timeToRead":589},"Useful Docker Images - Part 2","\u002Fuseful-docker-images-part2\u002F",{"title":837,"permalink":838,"heroImage":839,"timeToRead":608},"Writing your Webpack configuration in TypeScript","\u002Fwriting-your-webpack-configuration-in-typescript\u002F","\u002Fimages\u002Fhero\u002FTypeScript-1366x768.png",{"title":841,"permalink":842,"heroImage":843,"timeToRead":589},"Writing Code while Asleep","\u002Fwriting-code-asleep\u002F","\u002Fimages\u002Fhero\u002FWhile-Alive-Eat-Sleep-Code-Repeat-1366x768.png",{"title":845,"permalink":846,"heroImage":598,"timeToRead":391},"The Dotnet Watch Tool Revisited","\u002Fthe-dotnet-watch-tool-revisited\u002F",{"title":848,"permalink":849,"heroImage":850,"timeToRead":391},".NET Boxed","\u002Fnet-boxed\u002F","\u002Fimages\u002Fhero\u002FDotnet-Boxed-1366x768.png",{"title":852,"permalink":853,"heroImage":598,"timeToRead":391},"Migrating to Entity Framework Core Seed Data","\u002Fmigrating-to-entity-framework-core-seed-data\u002F",{"title":855,"permalink":856,"heroImage":598,"timeToRead":603},"Optimally Configuring Entity Framework Core","\u002Foptimally-configuring-entity-framework-core\u002F",{"title":858,"permalink":859,"heroImage":598,"timeToRead":514},"ASP.NET Core Hidden Gem - QueryHelpers","\u002Fasp-net-core-hidden-gem-queryhelpers\u002F",{"title":861,"permalink":862,"heroImage":598,"timeToRead":805},"Optimally Configuring ASP.NET Core HttpClientFactory","\u002Foptimally-configuring-asp-net-core-httpclientfactory\u002F",{"title":864,"permalink":865,"heroImage":866,"timeToRead":678},"PluralSight vs LinkedIn Learning vs FrontendMasters vs Egghead.io vs YouTube","\u002Fpluralsight-vs-linkedin-learning-vs-frontendmasters-vs-egghead-io-vs-youtube\u002F","\u002Fimages\u002Fhero\u002FOnline-Learning-1366x768.png",{"title":868,"permalink":869,"heroImage":870,"timeToRead":805},"Is ASP.NET Core now a Mature Platform?","\u002Fis-asp-net-core-now-a-mature-platform\u002F","\u002Fimages\u002Fhero\u002FRocket-1366x768.jpg",{"title":872,"permalink":873,"heroImage":850,"timeToRead":805},"A Simple and Fast Object Mapper","\u002Fa-simple-and-fast-object-mapper\u002F",{"title":875,"permalink":876,"heroImage":826,"timeToRead":514},"Securing ASP.NET Core in Docker","\u002Fsecuring-asp-net-core-in-docker\u002F",{"title":878,"permalink":879,"heroImage":880,"timeToRead":608},"Git Cloning the Windows OS Repo","\u002Fgit-cloning-the-windows-os-repo\u002F","\u002Fimages\u002Fhero\u002FWindows-1366x768.png",{"title":882,"permalink":883,"heroImage":884,"timeToRead":678},".gitattributes Best Practices","\u002Fgitattributes-best-practices\u002F","\u002Fimages\u002Fhero\u002FGit-1366x768.png",{"title":886,"permalink":887,"heroImage":598,"timeToRead":603},"Unit Testing dotnet new Templates","\u002Funit-testing-dotnet-new-templates\u002F",{"title":889,"permalink":890,"heroImage":850,"timeToRead":589},"What dotnet new Could Be","\u002Fwhat-dotnet-new-could-be\u002F",{"title":892,"permalink":893,"heroImage":598,"timeToRead":608},"ASP.NET Core Integration Testing & Mocking using Moq","\u002Fasp-net-core-integration-testing-mocking-using-moq\u002F",{"title":895,"permalink":896,"heroImage":897,"timeToRead":678},"Choosing a Static Site Generator","\u002Fchoosing-a-static-site-generator\u002F","\u002Fimages\u002Fhero\u002FStatic-Site-Generators-1600x900.png",{"title":899,"permalink":900,"heroImage":901,"timeToRead":391},"Spicing up your Browser Console","\u002Fspicing-up-your-browser-console\u002F","\u002Fimages\u002Fhero\u002FFiglet-Fonts-1600x900.png",{"title":903,"permalink":904,"heroImage":905,"timeToRead":589},"Racism in Software Development & Beyond","\u002Fracism-in-software-development-and-beyond\u002F","\u002Fimages\u002Fhero\u002FBlack-Glowing-Fist-1600x900.png",{"title":907,"permalink":908,"heroImage":909,"timeToRead":589},"The Easiest Way to Version NuGet Packages","\u002Fthe-easiest-way-to-version-nuget-packages\u002F","\u002Fimages\u002Fhero\u002FSemantic-Versioning-1600x900.png",{"title":911,"permalink":912,"heroImage":651,"timeToRead":701},"The Fastest NuGet Package Ever Published (Probably)","\u002Fthe-fastest-nuget-package-ever-published-probably\u002F",{"title":914,"permalink":915,"heroImage":598,"timeToRead":603},"Automating .NET Security Updates","\u002Fautomating-dotnet-security-updates\u002F",{"title":917,"permalink":918,"heroImage":919,"timeToRead":920},"Deep Dive into Open Telemetry for .NET","\u002Fdeep-dive-into-open-telemetry-for-net\u002F","\u002Fimages\u002Fhero\u002FOpen-Telemetry-1600x900.png",10,{"title":922,"permalink":923,"heroImage":919,"timeToRead":603},"Open Telemetry for ASP.NET Core","\u002Fopen-telemetry-for-asp-net-core\u002F",{"title":925,"permalink":926,"heroImage":919,"timeToRead":603},"Exporting Open Telemetry Data to Jaeger","\u002Fexporting-open-telemetry-data-to-jaeger\u002F",{"title":928,"permalink":929,"heroImage":930,"timeToRead":603},"A System for Grouping & Sorting CSS Properties","\u002Fsystem-for-grouping-and-sorting-css-properties\u002F","\u002Fimages\u002Fhero\u002FCSS-1600x900.png",{"title":932,"permalink":933,"heroImage":930,"timeToRead":701},"CSS General Rules of Thumb","\u002Fcss-general-rules-of-thumb\u002F",{"title":935,"permalink":936,"heroImage":937,"timeToRead":608},"Web Component Custom Element Gotchas","\u002Fweb-component-custom-element-gotchas\u002F","\u002Fimages\u002Fhero\u002FWeb-Components-1600x900.png",{"title":939,"permalink":940,"heroImage":941,"timeToRead":391},"Code Coverage & Frontend Testing","\u002Fcode-coverage-and-frontend-testing\u002F","\u002Fimages\u002Fhero\u002FJest-Cypress-1600x900.png",{"title":943,"permalink":944,"heroImage":687,"timeToRead":514},".NET Boxed Visual Studio Integration","\u002Fdotnet-boxed-visual-studio-integration\u002F",{"title":946,"permalink":947,"heroImage":948,"timeToRead":603},"The Windows Package Manager","\u002Fwindows-package-manager\u002F","\u002Fimages\u002Fhero\u002FWinget-1600x900.png",{"title":950,"permalink":951,"heroImage":598,"timeToRead":603},"The Problem with C# 10 Implicit Usings","\u002Fthe-problem-with-csharp-10-implicit-usings\u002F",{"title":953,"permalink":954,"heroImage":919,"timeToRead":608},"Optimally Configuring Open Telemetry Tracing for ASP.NET Core","\u002Foptimally-configuring-open-telemetry-tracing-for-asp-net-core\u002F",{"title":956,"permalink":957,"heroImage":958,"timeToRead":391},"Live Streaming .NET","\u002Flive-streaming-dotnet\u002F","\u002Fimages\u002Fhero\u002FMy-YouTube-1920x1080.jpg",{"title":960,"permalink":961,"heroImage":962,"timeToRead":391},"I Was Awarded as an Open UK Honouree","\u002Fopen-uk-honouree\u002F","\u002Fimages\u002Fhero\u002FOpen-UK-Honours-1366x768.jpg",{"title":964,"permalink":965,"heroImage":966,"timeToRead":608},"On the Etiquette of Pull Request Comments","\u002Fon-the-etiquette-of-pull-request-comments\u002F","\u002Fimages\u002Fhero\u002FPrecious-PR-1600x900.jpg",{"title":968,"permalink":969,"heroImage":970,"timeToRead":514},"AI Gone Rogue","\u002Fai-gone-rogue\u002F","\u002Fimages\u002Fhero\u002FHAL-9000-Prop-1600x900.png",{"left":4,"top":4,"width":24,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":972},"\u003Cpath fill=\"currentColor\" d=\"M352 320c-22.608 0-43.387 7.819-59.79 20.895l-102.486-64.054a96.55 96.55 0 0 0 0-41.683l102.486-64.054C308.613 184.181 329.392 192 352 192c53.019 0 96-42.981 96-96S405.019 0 352 0s-96 42.981-96 96c0 7.158.79 14.13 2.276 20.841L155.79 180.895C139.387 167.819 118.608 160 96 160c-53.019 0-96 42.981-96 96s42.981 96 96 96c22.608 0 43.387-7.819 59.79-20.895l102.486 64.054A96.3 96.3 0 0 0 256 416c0 53.019 42.981 96 96 96s96-42.981 96-96s-42.981-96-96-96\"\u002F>",{"left":4,"top":4,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":974},"\u003Cpath fill=\"currentColor\" d=\"M504 256C504 119 393 8 256 8S8 119 8 256c0 123.78 90.69 226.38 209.25 245V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48c27.14 0 55.52 4.84 55.52 4.84v61h-31.28c-30.8 0-40.41 19.12-40.41 38.73V256h68.78l-11 71.69h-57.78V501C413.31 482.38 504 379.78 504 256\"\u002F>",{"left":4,"top":4,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":976},"\u003Cpath fill=\"currentColor\" d=\"M459.37 151.716c.325 4.548.325 9.097.325 13.645c0 138.72-105.583 298.558-298.558 298.558c-59.452 0-114.68-17.219-161.137-47.106c8.447.974 16.568 1.299 25.34 1.299c49.055 0 94.213-16.568 130.274-44.832c-46.132-.975-84.792-31.188-98.112-72.772c6.498.974 12.995 1.624 19.818 1.624c9.421 0 18.843-1.3 27.614-3.573c-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319c-28.264-18.843-46.781-51.005-46.781-87.391c0-19.492 5.197-37.36 14.294-52.954c51.655 63.675 129.3 105.258 216.365 109.807c-1.624-7.797-2.599-15.918-2.599-24.04c0-57.828 46.782-104.934 104.934-104.934c30.213 0 57.502 12.67 76.67 33.137c23.715-4.548 46.456-13.32 66.599-25.34c-7.798 24.366-24.366 44.833-46.132 57.827c21.117-2.273 41.584-8.122 60.426-16.243c-14.292 20.791-32.161 39.308-52.628 54.253\"\u002F>",{"left":4,"top":4,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":978},"\u003Cpath fill=\"currentColor\" d=\"M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6c0-13.8 11.1-24.9 24.9-24.9c13.6 0 24.6 11.1 24.6 24.9c0 13.6-11.1 24.6-24.6 24.6M504 256c0 137-111 248-248 248S8 393 8 256S119 8 256 8s248 111 248 248m-132.3-41.2c-9.4 0-17.7 3.9-23.8 10c-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3l55.4 12.5c0 13.6 11.1 24.6 24.6 24.6c13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8c-6.1-6.4-14.7-10.2-24.1-10.2c-34.9 0-46.3 46.9-14.4 62.8c-1.1 5-1.7 10.2-1.7 15.5c0 52.6 59.2 95.2 132 95.2c73.1 0 132.3-42.6 132.3-95.2c0-5.3-.6-10.8-1.9-15.8c31.3-16 19.8-62.5-14.9-62.5M302.8 331c-18.2 18.2-76.1 17.9-93.6 0c-2.2-2.2-6.1-2.2-8.3 0c-2.5 2.5-2.5 6.4 0 8.6c22.8 22.8 87.3 22.8 110.2 0c2.5-2.2 2.5-6.1 0-8.6c-2.2-2.2-6.1-2.2-8.3 0m7.7-75c-13.6 0-24.6 11.1-24.6 24.9c0 13.6 11.1 24.6 24.6 24.6c13.8 0 24.9-11.1 24.9-24.6c0-13.8-11-24.9-24.9-24.9\"\u002F>",{"left":4,"top":4,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":980},"\u003Cpath fill=\"currentColor\" d=\"M512 194.8c0 101.3-82.4 183.8-183.8 183.8c-101.7 0-184.4-82.4-184.4-183.8c0-101.6 82.7-184.3 184.4-184.3C429.6 10.5 512 93.2 512 194.8M0 501.5h90v-491H0z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":982},"\u003Cpath fill=\"currentColor\" d=\"m20.216 6.415l-.132-.666c-.119-.598-.388-1.163-1.001-1.379c-.197-.069-.42-.098-.57-.241c-.152-.143-.196-.366-.231-.572c-.065-.378-.125-.756-.192-1.133c-.057-.325-.102-.69-.25-.987c-.195-.4-.597-.634-.996-.788a6 6 0 0 0-.626-.194c-1-.263-2.05-.36-3.077-.416a26 26 0 0 0-3.7.062c-.915.083-1.88.184-2.75.5c-.318.116-.646.256-.888.501c-.297.302-.393.77-.177 1.146c.154.267.415.456.692.58c.36.162.737.284 1.123.366c1.075.238 2.189.331 3.287.37q1.829.074 3.65-.118q.449-.05.896-.119c.352-.054.578-.513.474-.834c-.124-.383-.457-.531-.834-.473c-.466.074-.96.108-1.382.146q-1.767.12-3.536.006a22 22 0 0 1-1.157-.107c-.086-.01-.18-.025-.258-.036q-.364-.055-.724-.13c-.111-.027-.111-.185 0-.212h.005q.416-.09.838-.147h.002c.131-.009.263-.032.394-.048a25 25 0 0 1 3.426-.12q1.011.029 2.017.144l.228.031q.4.06.798.145c.392.085.895.113 1.07.542c.055.137.08.288.111.431l.319 1.484a.237.237 0 0 1-.199.284h-.003l-.112.015a37 37 0 0 1-4.743.295a37 37 0 0 1-4.699-.304c-.14-.017-.293-.042-.417-.06c-.326-.048-.649-.108-.973-.161c-.393-.065-.768-.032-1.123.161c-.29.16-.527.404-.675.701c-.154.316-.199.66-.267 1c-.069.34-.176.707-.135 1.056c.087.753.613 1.365 1.37 1.502a39.7 39.7 0 0 0 11.343.376a.483.483 0 0 1 .535.53l-.071.697l-1.018 9.907c-.041.41-.047.832-.125 1.237c-.122.637-.553 1.028-1.182 1.171q-.868.197-1.756.205c-.656.004-1.31-.025-1.966-.022c-.699.004-1.556-.06-2.095-.58c-.475-.458-.54-1.174-.605-1.793l-.731-7.013l-.322-3.094c-.037-.351-.286-.695-.678-.678c-.336.015-.718.3-.678.679l.228 2.185l.949 9.112c.147 1.344 1.174 2.068 2.446 2.272c.742.12 1.503.144 2.257.156c.966.016 1.942.053 2.892-.122c1.408-.258 2.465-1.198 2.616-2.657l1.024-9.995l.215-2.087a.48.48 0 0 1 .39-.426c.402-.078.787-.212 1.074-.518c.455-.488.546-1.124.385-1.766zm-1.478.772c-.145.137-.363.201-.578.233c-2.416.359-4.866.54-7.308.46c-1.748-.06-3.477-.254-5.207-.498c-.17-.024-.353-.055-.47-.18c-.22-.236-.111-.71-.054-.995c.052-.26.152-.609.463-.646c.484-.057 1.046.148 1.526.22q.865.132 1.737.212c2.48.226 5.002.19 7.472-.14q.675-.09 1.345-.21c.399-.072.84-.206 1.08.206c.166.281.188.657.162.974a.54.54 0 0 1-.169.364zm-6.159 3.9c-.862.37-1.84.788-3.109.788a6 6 0 0 1-1.569-.217l.877 9.004c.065.78.717 1.38 1.5 1.38c0 0 1.243.065 1.658.065c.447 0 1.786-.065 1.786-.065c.783 0 1.434-.6 1.499-1.38l.94-9.95a4 4 0 0 0-1.322-.238c-.826 0-1.491.284-2.26.613\"\u002F>",{"left":4,"top":4,"width":27,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":984},"\u003Cpath fill=\"currentColor\" d=\"M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134c-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9c152.3 0 165.1-3.7 204 11.4c60.1 23.3 65.6 79.5 44 140.3c-21.5 62.6-72.5 89.5-140.1 90.3c-43.4.7-69.5-7-75.3 24.2M357.1 152c-1.8-1.3-2.5-1.8-3 1.3c-2 11.4-5.1 22.5-8.8 33.6c-39.9 113.8-150.5 103.9-204.5 103.9c-6.1 0-10.1 3.3-10.9 9.4c-22.6 140.4-27.1 169.7-27.1 169.7c-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9c.7-5.4-1.1 6.1 14.4-91.3c4.6-22 14.3-19.7 29.3-19.7c71 0 126.4-28.8 142.9-112.3c6.5-34.8 4.6-71.4-23.8-92.6\"\u002F>",{"left":4,"top":4,"width":16,"height":16,"rotate":4,"vFlip":6,"hFlip":6,"body":986},"\u003Cpath fill=\"currentColor\" d=\"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8m0 448c-110.532 0-200-89.431-200-200c0-110.495 89.472-200 200-200c110.491 0 200 89.471 200 200c0 110.53-89.431 200-200 200m107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516c17.561-9.845 28.324-16.541 28.324-29.579c0-17.246-21.999-28.693-39.784-28.693c-23.189 0-33.894 10.977-48.942 29.969c-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8M298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42s18.841-42 42-42s42 18.841 42 42\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":988},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 12H5m7 7l-7-7l7-7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":990},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",1793533265568]