让asp.net在会话中存储视图状态而不是增加html

时间:2011-01-07 02:24:18

标签: c# asp.net session viewstate

我正在尝试让asp.net在会话中存储viewstate而不是填充html。

现在我已经读过asp.net附带了SessionPageStatePersister,可以使用它来代替默认的HiddenFieldPageStatePersister来执行此操作。我想知道我该如何放弃它?

这是我到目前为止所得到的: 我想我需要创建一个从其GetStatePersister方法返回SessionPageStatePersister的PageAdapter,并以某种方式让页面使用此pageadapter。但是Page.PageAdapter只有一个getter,所以我不确定你是如何设置它的。

请在此处查看“备注”标题:http://msdn.microsoft.com/en-us/library/system.web.ui.hiddenfieldpagestatepersister.aspx

谢谢!

3 个答案:

答案 0 :(得分:9)

你确定要这样做吗?有问题

  1. 如何将各个页面分开?当然,您可以在会话状态名称前加上页面,例如。会话[“/ default.aspx-Viewstate”]但是当用户打开多个页面实例时会发生什么?
  2. 所以要解决这个问题,你在每个页面中放置一个带有GUID的隐藏字段,然后将其用作关键字。所以你的会话规模会增长。并且成长。并且成长。您如何知道是否/何时可以安全地移除物品?
  3. 如果你坚持按下这个读取,那么你需要做的就是从页面派生一个类并覆盖LoadPageStateFromPersistenceMedium()和SavePageStateToPersistenceMedium()。但是你会恨自己并最终把它撕掉。

    只需确保您的服务器上已打开HTTP压缩,请相信其他内容。

答案 1 :(得分:7)

对于它的价值,这里是我最终用于解决手头的大图片问题的代码:将视图状态移出html。只需将其弹出到mypage.aspx.cs:

// Inspired by: http://aspalliance.com/72
const string ViewStateFieldName = "__VIEWSTATEKEY";
const string RecentViewStateQueue = "RecentViewStateQueue";
const int RecentViewStateQueueMaxLength = 5;

protected override object LoadPageStateFromPersistenceMedium()
{
    // The cache key for this viewstate is stored where the viewstate normally is, so grab it
    string viewStateKey = Request.Form[ViewStateFieldName] as string;
    if (viewStateKey == null) return null;

    // Grab the viewstate data from the cache using the key to look it up
    string viewStateData = Cache[viewStateKey] as string;
    if (viewStateData == null) return null;

    // Deserialise it
    return new LosFormatter().Deserialize(viewStateData);
}

protected override void SavePageStateToPersistenceMedium(object viewState)
{
    // Serialise the viewstate information
    StringBuilder _viewState = new StringBuilder();
    StringWriter _writer = new StringWriter(_viewState);
    new LosFormatter().Serialize(_writer, viewState);

    // Give this viewstate a random key
    string viewStateKey = Guid.NewGuid().ToString();

    // Store the viewstate in the cache
    Cache.Add(viewStateKey, _viewState.ToString(), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(Session.Timeout), CacheItemPriority.Normal, null);

    // Store the viewstate's cache key in the viewstate hidden field, so on postback we can grab it from the cache
    ClientScript.RegisterHiddenField(ViewStateFieldName, viewStateKey);

    // Some tidying up: keep track of the X most recent viewstates for this user, and remove old ones
    var recent = Session[RecentViewStateQueue] as Queue<string>;
    if (recent == null) Session[RecentViewStateQueue] = recent = new Queue<string>();
    recent.Enqueue(viewStateKey); // Add this new one so it'll get removed later
    while (recent.Count > RecentViewStateQueueMaxLength) // If we've got lots in the queue, remove the old ones
    Cache.Remove(recent.Dequeue());
}

对于使用SessionPageStatePersister的超简单方法,再次将其放在mypage.aspx.cs中:

protected override PageStatePersister PageStatePersister
{
    get
    {
        return new SessionPageStatePersister(this);
    }
}

答案 2 :(得分:5)

要使用自定义PageAdapter类,您必须使用.browser文件注册它。您需要添加(如果您还没有)App_Browsers目录。然后添加带有以下XML的.browser文件

<browsers>
    <browser refID="Default">
        <controlAdapters>
           <adapter controlType="System.Web.UI.Page" adapterType="{Your adapter type}" />
        </controlAdapters>
    </browser>
</browsers> 

用您的适配器类型替换{您的适配器类型}。

更多信息here

希望这有帮助。