Отключить кеширование при частичном представлении в MVC 3

У меня проблема с кешированием частичного представления, хотя этого быть не должно. Это частичное представление используется для отображения входа / выхода на странице. Он использует приведенный ниже простой код, чтобы выяснить, какую ссылку отображать.

@if(Request.IsAuthenticated) {    
    <a href="@Url.Action("LogOff", "Account", new { area = "" })">Log Off</a> 
}
else {
    <a href="@Url.Action("LogOn", "Account", new { area = "" })">Log On</a>
}

Это частичное представление вызывается со всеми страницами в моем приложении MVC3, используя

@Html.Partial("_HeaderView")  

В большинстве моих контроллеров у меня определен кеш вывода, поэтому я могу воспользоваться преимуществами кеширования своего контента.

[OutputCache(Duration = 86400, VaryByParam = "*")]

Теперь моя проблема в том, что вся страница кэшируется, когда я не хочу, чтобы было частичное представление. Это вызывает неправильное поведение, когда в нем иногда отображается LogOff, даже если пользователь не вошел в систему и т. Д. Есть ли способ кэшировать все содержимое, кроме рассматриваемого частичного представления?


person SimpleUser    schedule 09.01.2012    source источник
comment
Ник, извини, что пришлось добавить сюда комментарий. Во всяком случае, это работает, когда я удаляю Nostore и изменяю продолжительность на 1. Единственная проблема теперь заключается в том, что когда пользователь входит в систему, они переносятся на домашнюю страницу, но я должен явно обновить ее, чтобы изменения вступили в силу (чтобы показать выход из системы). вместо входа в систему).   -  person SimpleUser    schedule 09.01.2012


Ответы (5)


То, что вы ищете, называется кэшированием пончиков. Вот отличная статья, объясняющая, что это такое и как заставить его работать http://www.devtrends.co.uk/blog/donut-output-caching-in-asp.net-mvc-3

person Paweł Staniec    schedule 09.01.2012
comment
Я пробовал это, но у меня не получилось, как ожидалось. У меня остались те же проблемы, что и при использовании атрибута outputcache в частичном действии, а именно при обновлении домашней страницы вручную. - person SimpleUser; 09.01.2012
comment
Я бы с удовольствием помог, но не увидеть код, который у вас был, будет сложно :) Но у меня это сработало. При тестировании помните о правильных настройках браузера (иногда они отменяют настройки сервера, и в случае ложного впечатления что-то не работает) - person Paweł Staniec; 09.01.2012
comment
Нет, просто у меня был очень медленный момент. Очевидно, что работать с гриппом - не лучшая идея. Но сейчас это работает. Спасибо за вашу помощь - person SimpleUser; 09.01.2012

Вы можете отключить кеширование, украсив контроллер, который отображает ваш партиал _HeaderView, следующим:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult HeaderView()
{
    return PartialView("_HeaderView");
}
person Nick    schedule 09.01.2012
comment
Привет, Ник. Спасибо за ваш вклад. Но у меня нет действия контроллера, связанного с частичным представлением (по крайней мере, на данный момент). Я вызываю это с помощью Html.Partial (). Это единственный обходной путь для действия контроллера с указанным выше? - person SimpleUser; 09.01.2012
comment
Возможно, вы могли бы добавить общий контроллер и действие HeaderView, которое возвращает PartialView (_HeaderView); и украшен аннотацией в моем ответе выше. Надеюсь, это даст вам необходимый контроль и не станет серьезным изменением. Сообщите мне, работает ли это для вас или вам нужны дополнительные разъяснения. - person Nick; 09.01.2012
comment
Спасибо, Ник. Я внесу изменения и дам вам знать, как это происходит. - person SimpleUser; 09.01.2012
comment
Привет, Ник. Когда я добавляю аннотацию кэша вывода, частичное представление вообще не отображается. Вот как выглядят мои 2 действия контроллера [OutputCache (Duration = 86400, VaryByParam = )] public ActionResult Index () {return View (); } [OutputCache (Duration = 0, VaryByParam =)] [ChildActionOnly] общедоступный ActionResult HeaderView () {return PartialView (_HeaderView); } На странице индекса я вызываю Html.Action для отображения частичного представления - person SimpleUser; 09.01.2012
comment
Используйте @ Html.Partial (HeaderView) для отображения части и убедитесь, что _HeaderView.cshtml находится в вашей папке общих представлений. Кроме того, убедитесь, что вы используете свойство NoStore, поскольку оно используется для информирования прокси-серверов и браузеров о том, что они не должны хранить постоянную копию представления. - person Nick; 09.01.2012
comment
Ник, если я использую Html.Partial, он не коснется действия контроллера, не так ли? Тогда аннотация кеша не будет использоваться? - person SimpleUser; 09.01.2012
comment
Синдром понедельника утром! @ Html.RenderAction (HeaderView); Какой результат вы получаете сейчас? - person Nick; 09.01.2012
comment
Первоначальное тестирование предполагает, что вам нужно только указать параметры NoStore и Duration. На самом деле я сначала указал только NoStore = true, но получил сообщение об ошибке, что требуется Duration. После размещения Duration = 0 все вроде уже работает как задумано. Вы можете это подтвердить? Мне нравится иметь как можно меньше кода, особенно когда мы имеем дело с жестко запрограммированными строками. - person julealgon; 07.10.2014
comment
Просто сделал еще несколько тестов и кажется, что я могу использовать Location = OutputCacheLocation.None вместо Duration = 0, что еще более понятно :) - person julealgon; 07.10.2014
comment
Я получаю System.InvalidOperationException: OutputCacheAttribute for child actions only supports Duration, VaryByCustom, and VaryByParam values. Please do not set CacheProfile, Location, NoStore, SqlDependency, VaryByContentEncoding, or VaryByHeader values for child actions. - person SepehrM; 15.06.2016
comment
И System.InvalidOperationException: Duration must be a positive number - person SepehrM; 15.06.2016
comment
@SepehrM, вы можете взглянуть на комментарий julealgon, он должен вас разобрать - person stoic; 24.06.2016
comment
Он не позволяет использовать Location, как указано в сообщении об ошибке. В итоге мы использовали технику кэширования пончиков. - person SepehrM; 25.06.2016

Мы должны установить профиль кеша в файле Web.config вместо того, чтобы устанавливать значения кеша по отдельности на страницах, чтобы избежать избыточного кода. Мы можем ссылаться на профиль, используя свойство CacheProfile атрибута OutputCache. Этот профиль кеша будет применяться ко всем страницам, если страница / метод не переопределяют эти настройки.

<system.web>
  <caching>
    <outputCacheSettings>
      <outputCacheProfiles>
        <add name="CacheProfile" duration="60" varyByParam="*" />
      </outputCacheProfiles>
    </outputCacheSettings>
  </caching>
</system.web>

И если вы хотите отключить кеширование для своего действия, которое возвращает частичное представление [_HeaderView], вы можете переопределить настройки кеширования конфигурации, украсив этот конкретный метод действия, как показано ниже:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult RenderPartialView()
{
    return PartialView("_HeaderView");
}

Надеюсь, это поможет вам!

person Swati Gupta    schedule 02.09.2014

это работает для меня ..

 public ActionResult LogOff()
 {
     AuthenticationManager.SignOut();  
     var url = Url.Action("Index", "Web"); 
     HttpResponse.RemoveOutputCacheItem(url);           
     return RedirectToAction("Index", "Web");
 }
person Miroslav    schedule 08.01.2015
comment
+1 Я пробовал все другие решения, они не работали, это сработало для меня ... Спасибо :) Примечание: мне не нужно было использовать AuthenticationManager.Signout () .; - person Prince Ashitaka; 25.11.2016

Потребовалось некоторое время, чтобы понять это после возвращения в MVC. Просто поместите параметр Cache прямо в представление частичного заголовка. Как при отображении имени пользователя. Нет необходимости в глобальном или серверном коде. Проблема только в том, что после кэширования страницы она не обновляется сразу после входа в систему. Но мы сохраняем скорость, когда это необходимо при первоначальном просмотре продуктов. Хорошо, компромисс в нашем случае.


    @if ( Request.IsAuthenticated)
    {
            @* when we are authenticated, don't cache any more! *@
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Cache.SetNoStore();
    HttpContext.Current.Response.Cache.SetNoServerCaching();
            @*@Html.Raw(DateTime.Now.ToString())*@
    @Html.ActionLink("Welcome " + ( String.IsNullOrEmpty(((System.Security.Claims.ClaimsIdentity)User.Identity).FindFirstValue("UserName")) ? User.Identity.Name : ((System.Security.Claims.ClaimsIdentity)User.Identity).FindFirstValue("UserName")), "Index", "Manage", routeValues: new { Area = "Store" }, htmlAttributes: new { title = "Manage"})
    }
    else
    {
    }

person Jeff    schedule 10.02.2017