当前位置:编程学习 > C#/ASP.NET >>

崩溃中。。。“验证视图状态 MAC 失败”求高手解决!送上100分

我做的这个程序,在家用(firefox,IE等)调试都没有问题,但在单位调试,用firefox调试,总是报这个错!

“验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。”

但IE和Maxthon都没有问题!试了网上的方法,有时候是不报了,但查询出的结果就是不对!我用的是Treeview帮定的数据显示在Gridview中,出错的时候,Gridview绑定出的数据都是显示一半。。。崩溃中,出这个问题,我没办法继续往下进行了。




--------------------编程问答-------------------- 试着设一下 machineKey

<machineKey
    validationKey="1ADE6B5F46DF1758542EBA36854770FB8E189732606E94D43551E9410F05821410952A06A49655AEA4C0C1D2012DC2A768582CC68559794FC3AC4B75ADBA3274"
    decryptionKey="AE984B436F73D6ADC1F45F5F5E0FD793EDA8C390CC87A9C63567342DA2C3F68E"
    validation="SHA1"
    decryption="AES"
/>
--------------------编程问答-------------------- 试过,不管用。关键是Gridview加载,为什么数据总是和家里加载的不一样呢。 --------------------编程问答-------------------- 难道是风水问题?

--------------------编程问答-------------------- 把临时文件什么的都删删 --------------------编程问答-------------------- ViewState太巨大了,超过了asp.net的Post数据的限制,或者是你的浏览器的Post数据的限制。

ViewState可以不输出到页面上。你可以把这个类用来作为各种Page的父类:
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Web.UI;

public class VPage : Page
{
    static private DirectoryInfo _Dir;

    private static DirectoryInfo Dir
    {
        get
        {
            if (_Dir == null)
            {
                _Dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data"));
                if (!_Dir.Exists)
                    _Dir.Create();
                _Dir = new DirectoryInfo(Path.Combine(_Dir.FullName, "ViewState"));
                if (!_Dir.Exists)
                    _Dir.Create();
            }
            return _Dir;
        }
    }

    protected override object LoadPageStateFromPersistenceMedium()
    {
        PageStatePersister ps = this.PageStatePersister;
        ps.Load();
        if (ps.ControlState != null)
            ps.ControlState = 反序列化对象((string)ps.ControlState);
        if (ps.ViewState != null)
            ps.ViewState = 反序列化对象((string)ps.ViewState);
        return new Pair(ps.ControlState, ps.ViewState);
    }

    protected override void SavePageStateToPersistenceMedium(object state)
    {
        PageStatePersister ps = this.PageStatePersister;
        if (state is Pair)
        {
            ps.ControlState = ((Pair)state).First;
            ps.ViewState = ((Pair)state).Second;
        }
        else
            ps.ViewState = state;
        if (ps.ControlState != null)
            ps.ControlState = 序列化对象(ps.ControlState);
        if (ps.ViewState != null)
            ps.ViewState = 序列化对象(ps.ViewState);
        ps.Save();
    }

    private object 反序列化对象(string stateID)
    {
        if (stateID == null)
            return null;

        object state = Cache[stateID];
        string fname = Path.Combine(Dir.FullName, stateID);
        if (state == null)
            using (var stream = File.OpenRead(fname))
                state = new BinaryFormatter().Deserialize(stream);
        this.Page.SaveStateComplete += (s, e) =>    //当发生异常时,此方法不会执行,因此可以保证不会误删ViewState文件
        {
            Cache.Remove(stateID);
            File.Delete(fname);     //这个方法恰好可以禁止浏览器端的“刷新”。
        };
        return state;
    }

    static long seed1 = DateTime.Now.Ticks;
    static ulong seed2 = 0;
    static object lockflag = new object();

    private string 序列化对象(object obj)
    {
        lock (lockflag)
        {
            string stateID = seed1.ToString() + "_" + (seed2++).ToString();
            Cache.Insert(stateID, obj, null, DateTime.Now.AddMinutes(5), TimeSpan.Zero);
            var stream = new MemoryStream();
            new BinaryFormatter().Serialize(stream, obj);
            File.WriteAllBytes(Path.Combine(Dir.FullName, stateID), stream.ToArray());
            return stateID;
        }
    }

    static VPage()
    {
        var et = DateTime.Now.AddMinutes(-30);
        Dir.GetFiles()
            .Where(f => f.LastAccessTime < et)
            .ToList()
            .ForEach(f =>
            {
                try
                {
                    f.Delete();
                }
                catch { }
            });
    }
}
--------------------编程问答-------------------- 5楼说得有道理  你可以试试看下是不是你的VIEWSTATE里面的数据太多,而且没有清空的 --------------------编程问答-------------------- 不知道firefox里有没有相关的设置,刚才我试了把gridview treeview的EnableViewState设为false,问题似乎解决,但实际查询的结果还是有的正确有的错误!真的不理解,为什么两个环境,两种同样的软件,却有两种效果!唉。5楼的方法看上去对我来说太专业了。。。动作太大了。还没敢试。
现在我打算重新找两台单位的机器试试! --------------------编程问答-------------------- http://topic.csdn.net/u/20100208/13/2d22efd3-215a-4301-abe9-afbef1ad3b40.html --------------------编程问答--------------------
引用 7 楼 givemeakiss 的回复:
不知道firefox里有没有相关的设置,刚才我试了把gridview treeview的EnableViewState设为false,问题似乎解决,但实际查询的结果还是有的正确有的错误!真的不理解,为什么两个环境,两种同样的软件,却有两种效果!唉。5楼的方法看上去对我来说太专业了。。。动作太大了。还没敢试。
现在我打算重新找两台单位的机器试试!


如果有某一个控件不需要回发、或者回发时不需要访问其属性,就可以关闭其ViewState。但是你如果需要状态数据以及因状态而触发的事件,那么关闭ViewState显然程序的行为就乱了。

使用VPage并不是很大的动作啊?!比如你原来的代码是
public partial class MyPage : System.Web.UI.Page
{
  .......
}
改成
public partial class MyPage : VPage
{
  .......
}
就成了。改不改在你,但是改过去和改回来只是举手之劳,没有什么风险。 --------------------编程问答-------------------- GridView这个控件的VIEWSTATE产生的量真的太大了啊,而且如果你一次把数据全取出绑定,那更是恐怖,所以我觉得,如果你用可能,还是自己用table+css自己来绑定数据,这样的页面真的太简洁了,也不会太大。还有这样的话,你可以选在当前要显示的数据,这样对于页面的响应也是很好的。 --------------------编程问答--------------------
引用 10 楼 chen_ya_ping 的回复:
GridView这个控件的VIEWSTATE产生的量真的太大了啊,而且如果你一次把数据全取出绑定,那更是恐怖,所以我觉得,如果你用可能,还是自己用table+css自己来绑定数据,这样的页面真的太简洁了,也不会太大。还有这样的话,你可以选在当前要显示的数据,这样对于页面的响应也是很好的。


嗯,不光 grid view, 整个 webform 都是越看越烦人 --------------------编程问答--------------------
引用 11 楼 phil999 的回复:
引用 10 楼 chen_ya_ping 的回复:

GridView这个控件的VIEWSTATE产生的量真的太大了啊,而且如果你一次把数据全取出绑定,那更是恐怖,所以我觉得,如果你用可能,还是自己用table+css自己来绑定数据,这样的页面真的太简洁了,也不会太大。还有这样的话,你可以选在当前要显示的数据,这样对于页面的响应也是很好的。


嗯,不光 grid view, 整个 w……

所以以后mvc会大行其道啊 --------------------编程问答-------------------- 传送门 --------------------编程问答--------------------
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,