Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列化然后反序列化对象,得到与原始对象不同的结果_C#_Serialization - Fatal编程技术网

C# 序列化然后反序列化对象,得到与原始对象不同的结果

C# 序列化然后反序列化对象,得到与原始对象不同的结果,c#,serialization,C#,Serialization,我会尽力提供我能提供的信息,我不完全确定什么对理解这个问题有帮助 我注意到我在代码上有一些奇怪的行为,我认为这些行为在功能上应该是相同的。我从会话中提取数据,因为它比每次访问数据库都要快,但每当我保存到会话时,我也会保存到数据库中(我可以确认这是100%正确的) 我发现,在某些情况下,从会话中提取数据时,我会遇到奇怪的行为,但从数据库中提取相同的数据时,我没有遇到这个问题 //Good: string data = DashboardDatabaseRepository.Instance.Get

我会尽力提供我能提供的信息,我不完全确定什么对理解这个问题有帮助

我注意到我在代码上有一些奇怪的行为,我认为这些行为在功能上应该是相同的。我从会话中提取数据,因为它比每次访问数据库都要快,但每当我保存到会话时,我也会保存到数据库中(我可以确认这是100%正确的)

我发现,在某些情况下,从会话中提取数据时,我会遇到奇怪的行为,但从数据库中提取相同的数据时,我没有遇到这个问题

//Good:
string data = DashboardDatabaseRepository.Instance.GetWebLayoutData("PaneStates");

if (!string.IsNullOrEmpty(data))
{
    byte[] dataAsArray = System.Convert.FromBase64String(data);
    MemoryStream stream = new MemoryStream(dataAsArray);
    _paneStates = serializer.Deserialize(stream) as SerializableDictionary<string, RadPaneSetting>;
}

//Bad:

if (!object.Equals(DashboardSessionRepository.Instance.GetSession("PaneStates"), null))
{
    _paneStates = DashboardSessionRepository.Instance.GetSession("PaneStates") as SerializableDictionary<string, RadPaneSetting>;
}
现在,事情变得很奇怪。下面的代码将上面的“坏”代码转换为“好”代码

//WorkAround - Good
get
{
    SerializableDictionary<string, RadPaneSetting> _paneStates = new SerializableDictionary<string, RadPaneSetting>();

    if (!object.Equals(DashboardSessionRepository.Instance.GetSession("PaneStates"), null))
    {
        _paneStates = DashboardSessionRepository.Instance.GetSession("PaneStates") as SerializableDictionary<string, RadPaneSetting>;

        System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
        System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(_paneStates.GetType());
        xmlSerializer.Serialize(memoryStream, _paneStates);
        string data = System.Convert.ToBase64String(memoryStream.ToArray());

        if (!string.IsNullOrEmpty(data))
        {
            XmlSerializer serializer = new XmlSerializer(_paneStates.GetType());
            byte[] dataAsArray = System.Convert.FromBase64String(data);// System.Text.Encoding.UTF8.GetBytes(data);
            MemoryStream stream = new MemoryStream(dataAsArray);

            _paneStates = serializer.Deserialize(stream) as SerializableDictionary<string, RadPaneSetting>;
        }
        else
        {
            XmlSerializer serializer = new XmlSerializer(_paneStates.GetType());

            string data = DashboardDatabaseRepository.Instance.GetWebLayoutData("PaneStates");

            if (!string.IsNullOrEmpty(data))
            {
                byte[] dataAsArray = System.Convert.FromBase64String(data);// System.Text.Encoding.UTF8.GetBytes(data);
                MemoryStream stream = new MemoryStream(dataAsArray);
                _paneStates = serializer.Deserialize(stream) as SerializableDictionary<string, RadPaneSetting>;
            }

            DashboardSessionRepository.Instance.SetSession("PaneStates", _paneStates);
        }

    return _paneStates;
}
//解决方法-很好
得到
{
SerializableDictionary _paneStates=新建SerializableDictionary();
如果(!object.Equals(DashboardSessionRepository.Instance.GetSession(“PaneStates”),则为null)
{
_paneStates=DashboardSessionRepository.Instance.GetSession(“paneStates”)作为SerializableDictionary;
System.IO.MemoryStream MemoryStream=新的System.IO.MemoryStream();
System.Xml.Serialization.XmlSerializer XmlSerializer=new System.Xml.Serialization.XmlSerializer(_paneStates.GetType());
序列化(memoryStream,_paneStates);
字符串数据=System.Convert.ToBase64String(memoryStream.ToArray());
如果(!string.IsNullOrEmpty(数据))
{
XmlSerializer serializer=新的XmlSerializer(_paneStates.GetType());
byte[]dataAsArray=System.Convert.FromBase64String(数据);//System.Text.Encoding.UTF8.GetBytes(数据);
MemoryStream stream=新的MemoryStream(dataAsArray);
_paneStates=serializer.反序列化(流)为SerializableDictionary;
}
其他的
{
XmlSerializer serializer=新的XmlSerializer(_paneStates.GetType());
字符串数据=DashboardDatabaseRepository.Instance.GetWebLayoutData(“PaneStates”);
如果(!string.IsNullOrEmpty(数据))
{
byte[]dataAsArray=System.Convert.FromBase64String(数据);//System.Text.Encoding.UTF8.GetBytes(数据);
MemoryStream stream=新的MemoryStream(dataAsArray);
_paneStates=serializer.反序列化(流)为SerializableDictionary;
}
DashboardSessionRepository.Instance.SetSession(“PaneStates”,_PaneStates);
}
归还财产;
}
我很好奇,通过序列化和反序列化从会话中检索到的对象,会发生什么样的清理?这里有什么明显的遗漏吗

谢谢你抽出时间

编辑:我相信这两个字典具有相同的数据。我在S.O.上查找了一个字典相等比较器,并且正在使用那里提供的代码。请注意调试器是如何进入if语句的,但屏幕截图左侧的对象似乎相等。为什么会发生这种情况


问题在于您使用的是UTF-8反向编码。当您认为正在解码时,您正在编码,而当您认为正在编码时,您正在解码

UTF-8编码不用于将任何二进制数据表示为字符串,而是用于将字符串表示为二进制数据。当您获取任何二进制数据并通过
encoding.UTF8.GetString
发送时,您可能会损坏数据。它将适用于恰好对应于任何ch的任何字节码以UTF-8编码的字符数据,但一旦获得UTF-8编码数据中不存在的字节组合,该方法就无法将其转换为字符。此外,即使可以将数据转换为字符串而不丢失数据,也不能保证在再次编码字符串时给出相同的二进制结果

您应该改用base64编码。使用
Convert.ToBase64String
将二进制数据转换为字符串表示形式,使用
Convert.FromBase64String
将二进制数据取回:

string data = Convert.ToBase64String(memoryStream.ToArray());
以及:


你的数据有什么不同?唯一让我感到吃惊的是UTF8序列化。你文本中的某些内容在http上下文中的编码是否不同?我一直在试图找到一种比较这两个字典的好方法。上面的代码受到了很多攻击,我无法通过查看我的lo来分析差异给我一点时间,试着找出物体的实际差异(希望我能找到)啊,太常见了:嗨。我要重新打开这个。我实现了你的解决方案,虽然我同意这样做更好,但这不是我问题的根源。谢谢。我确定问题在于,在会话中存储整个对象时,对象上存储了额外的信息,但没有持久化序列化/反序列化时。
string data = Convert.ToBase64String(memoryStream.ToArray());
byte[] dataAsArray = Convert.FromBase64String(data);