OutputCache возвращает неверную версию с PostBack - PullRequest
2 голосов
/ 11 февраля 2010

У меня странная проблема с выходным кэшем. У меня есть несколько пользовательских элементов управления на странице, одним из которых является элемент управления для входа. Страница и элемент управления для входа НЕ кэшируются, но другие пользовательские элементы управления кэшируются с помощью VaryByParam. Теперь все это работает вместе с кэшированием, когда я нажимаю на разные страницы. Но как только я войду в систему, другие пользовательские элементы управления на этой странице отобразят старые кэшированные версии. Если я обновлю страницу, я получу правильную кэшированную версию всех пользовательских элементов управления. Проблема только в том, когда происходит обратная передача. По какой-то причине при обратной передаче возвращаемая кэшированная версия не учитывает строку VaryByParam. При поиске в Интернете я обнаружил похожую проблему на asp.net, в которой был код, объясняющий это.

Почему при обратной передаче кэш возвращает неверную версию?

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<%@ Register src="WebUserControl1.ascx" tagname="WebUserControl1" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>  
</head>
<body>
    <form id="form1" runat="server">       
        <uc1:WebUserControl1 ID="WebUserControl11" runat="server" EnableViewState="false" />           
    </form>
</body>
</html>

WebUserControl1.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplication1.WebUserControl1" %>
<%@ OutputCache Duration="3600" VaryByParam="MenuID" %>
<asp:LinkButton ID="test" runat="server" Text="PostBack"></asp:LinkButton>
<br /><br />
<a href="Default.aspx?menuid=1">1</a> - <a href="Default.aspx?menuid=2">2</a> - <a href="Default.aspx?menuid=3">3</a>
<br /><br />
MenuID: <%= Request.QueryString["MenuID"] != null ? Request.QueryString["MenuID"].ToString() : "null" %>

Запустите демонстрацию, и вы увидите, что нажатие между страницами возвращает правильную кешированную версию. Но попробуйте щелкнуть страницу и вызвать обратную передачу, и тогда вы увидите, что иногда вы получаете неверную версию кэша.

Ответы [ 3 ]

2 голосов
/ 12 февраля 2010

Я думаю, что это ошибка в ASP .Net, и пока она не устранена, есть обходной путь.

Для каждого постбэка я хочу свежую версию, а не кэшированную. Но в остальном я хочу кешированную версию. Так что я могу посмотреть, что это за запрос. Если это «POST», я получу новую версию, если это «GET», я получу версию из кеша. Для этого я настраиваю настройку кэша VaryByCustom в пользовательском контроле. И в моем global.asax сделал это:

public override string GetVaryByCustomString(HttpContext context, string arg)
{
    if (arg.Trim().ToLower() == "getorpost")
    {
           //for a POST request (postback) force to return back a non cached output
            if (context.Request.RequestType.Equals("POST"))
            {
                return "post" + DateTime.Now.Ticks;
            }
            return "get";
     }
     return base.GetVaryByCustomString(context, arg);
}
0 голосов
/ 12 июня 2015

Я согласен с Гарфилдом в отношении причины и думаю, что предложение использовать VaryByCustom также является разумной идеей. Для этого вы можете просто использовать Response.Cache.SetNoServerCaching () в Global.asax, который просто требует определения в Global.asax, является ли страница постбэк или нет. Здесь - пример кода.

0 голосов
/ 10 марта 2010

От кого-то внутри MS:

Поведение выходного кэша для элементов управления было первоначально записано (и все еще записано) для отключения либо коллекции строк запроса, либо коллекции значений формы. Внутренняя логика определяет, какую коллекцию нужно просматривать, основываясь на том, является ли запрос GET или POST. Я согласен с тем, что такое поведение менее чем очевидно, но это, очевидно, было первоначальной целью поведения кэширования управляющего вывода.

Два обходных пути для включения значений строки запроса являются частью решений кеша вывода:

  1. Зеркально отразить значения строки запроса в скрытые переменные формы, если это возможно.
  2. Альтернативно используйте обходной путь, который вы уже обнаружили - что использовать VaryByCustom и GetVaryByCustomString. Обычай реализация GetVaryByCustomString может вернуть строка, содержащая одно или несколько значений читать из Request.Querystring для POST-запросы, чтобы получить желаемое эффект.
...