[C#] 특성을 사용하여 특정 작업에 대해 ASP.NET MVC에서 캐싱 방지

ASP.NET MVC 3 응용 프로그램이 있습니다. 이 애플리케이션은 jQuery를 통해 레코드를 요청합니다. jQuery는 JSON 형식으로 결과를 반환하는 컨트롤러 작업을 다시 호출합니다. 나는 이것을 증명할 수 없었지만 내 데이터가 캐시 될지도 모른다.

캐싱을 특정 작업에만 적용하고 모든 작업에 적용하려는 것은 아닙니다.

데이터가 캐시되지 않도록 조치를 취할 수있는 속성이 있습니까? 그렇지 않은 경우 캐시 된 세트 대신 브라우저가 매번 새로운 레코드 세트를 받도록하려면 어떻게해야합니까?



답변

JQuery가 결과를 캐싱하지 않도록하려면 ajax 메소드에서 다음을 입력하십시오.

$.ajax({
    cache: false
    //rest of your ajax setup
});

또는 MVC에서 캐싱을 방지하기 위해 자체 속성을 만들었습니다. 코드는 다음과 같습니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

그런 다음으로 컨트롤러를 장식하십시오 [NoCache]. 또는 우리가 여기에있는 것처럼 컨트롤러를 상속받은 기본 클래스의 클래스에 속성을 넣을 수 있습니다.

[NoCache]
public class ControllerBase : Controller, IControllerBase

전체 컨트롤러를 장식하는 대신 캐시 할 수없는 경우이 속성을 사용하여 일부 작업을 장식 할 수도 있습니다.

클래스 또는 액션이 NoCache브라우저에서 렌더링 될 때 클래스가 없거나 작동하지 않는지 확인하려면 변경 사항을 컴파일 한 후 브라우저에서 “하드 리프레시”(Ctrl + F5)를 수행해야합니다. 그렇게 할 때까지 브라우저는 이전에 캐시 된 버전을 유지하며 “일반 새로 고침”(F5)으로 새로 고치지 않습니다.


답변

내장 캐시 속성을 사용하여 캐싱을 방지 할 수 있습니다.

.net Framework의 경우 : [OutputCache(NoStore = true, Duration = 0)]

.net Core의 경우 : [ResponseCache(NoStore = true, Duration = 0)]

브라우저가 강제로 캐싱을 사용하지 않도록 설정하는 것은 불가능합니다. 당신이 할 수있는 최선의 방법은 대부분의 브라우저가 일반적으로 헤더 나 메타 태그의 형태로 존중할 것을 제안하는 것입니다. 이 데코레이터 속성은 서버 캐싱을 비활성화하고이 헤더를 추가합니다 Cache-Control: public, no-store, max-age=0. 메타 태그를 추가하지 않습니다. 원하는 경우 뷰에서 수동으로 추가 할 수 있습니다.

또한 JQuery 및 기타 클라이언트 프레임 워크는 타임 스탬프 또는 GUID와 같이 URL에 항목을 추가하여 브라우저의 캐시 된 버전의 리소스를 사용하지 않도록 브라우저를 속이려고 시도합니다. 이것은 브라우저가 리소스를 다시 요청하도록하는 데 효과적이지만 실제로 캐싱을 막지는 않습니다.

마지막 메모. 서버와 클라이언트간에 리소스를 캐시 할 수도 있습니다. ISP, 프록시 및 기타 네트워크 장치도 리소스를 캐시하며 실제 리소스를 보지 않고 내부 규칙을 사용하는 경우가 많습니다. 이것에 대해 할 수있는 일은 많지 않습니다. 좋은 소식은 일반적으로 초 또는 분과 같은 짧은 시간 동안 캐시한다는 것입니다.


답변

필요한 것은 다음과 같습니다.

[OutputCache(Duration=0)]
public JsonResult MyAction(

또는 전체 컨트롤러에 대해 비활성화하려면 :

[OutputCache(Duration=0)]
public class MyController

여기 주석에 대한 토론에도 불구하고 브라우저 캐싱을 비활성화하기에 충분합니다. 그러면 ASP.Net이 브라우저에 문서가 즉시 만료되었음을 알리는 응답 헤더를 생성합니다.

OutputCache Duration = 0 응답 헤더 : max-age = 0, s-maxage = 0


답변

컨트롤러 조치에서 헤더에 다음 행을 추가하십시오.

    public ActionResult Create(string PositionID)
    {
        Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
        Response.AppendHeader("Expires", "0"); // Proxies.


답변

다음 NoCache은 Chris Moschini의 답변 정보를 사용하여 단순화 한 mattytommo가 제안한 속성입니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
    public NoCacheAttribute()
    {
        this.Duration = 0;
    }
}


답변

MVC6 ( DNX )의 경우System.Web.OutputCacheAttribute

참고 : NoStore지속 시간 매개 변수 를 설정하면 고려되지 않습니다. 첫 등록의 초기 기간을 설정하고이를 사용자 정의 속성으로 대체 할 수 있습니다.

그러나 우리는 Microsoft.AspNet.Mvc.Filters.ResponseCacheFilter

 public void ConfigureServices(IServiceCollection services)
        ...
        services.AddMvc(config=>
        {
            config.Filters.Add(
                 new ResponseCacheFilter(
                    new CacheProfile() {
                      NoStore=true
                     }));
        }
        ...
       )

사용자 정의 속성으로 초기 필터를 재정의 할 수 있습니다

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class NoCacheAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            var filter=filterContext.Filters.Where(t => t.GetType() == typeof(ResponseCacheFilter)).FirstOrDefault();
            if (filter != null)
            {
                ResponseCacheFilter f = (ResponseCacheFilter)filter;
                f.NoStore = true;
                //f.Duration = 0;
            }

            base.OnResultExecuting(filterContext);
        }
    }

유스 케이스는 다음과 같습니다.

    [NoCache]
    [HttpGet]
    public JsonResult Get()
    {
        return Json(new DateTime());
    }


답변

MVC의 출력 캐싱

[OutputCache (NoStore = true, Duration = 0, Location = "None", VaryByParam = "*")]

또는
[OutputCache (NoStore = true, Duration = 0, VaryByParam = "없음")]