问题:我必须在.NET 1.1下的HttpModule中获取所有会话的内容... (不要问我为什么某些人仍然使用它)
我可以写模块,我可以得到会话。 但是......会话存储为
session["SomeString"] = object
如何将包含对象的类序列化为XML的成员? 具体来说,我尝试了一个DataTable的例子。
条件:它必须适用于.NET 1.1所以没有泛型
由于1.1没有System.Web.SessionState,所以不是这样:
private string Serialize(System.Web.SessionState.SessionStateItemCollection items)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms);
if (items != null)
items.Serialize(writer);
writer.Close();
return Convert.ToBase64String(ms.ToArray());
} // End Function Serialize
下面是我的尝试,它在对象中仅对文本值有效,但在DataTable上失败。有趣的是:DataTable是可序列化的,所以它“应该”工作......
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionModuleUnitTest
{
public class Program
{
[Serializable()]
public class kvp
{
[System.Xml.Serialization.XmlElement(ElementName = "key")]
public string key = "";
[System.Xml.Serialization.XmlElement(ElementName = "value")]
public object value = new object();
public kvp()
{ }
public kvp(string strKey, object obj)
{
this.key = strKey;
this.value = obj;
}
}
[Serializable()]
public class whatever
{
[System.Xml.Serialization.XmlArrayItem(Type = typeof(kvp))]
public kvp[] MyKeyValueCollection;
}
public static void Serialization()
{
// http://www.java2s.com/Tutorial/CSharp/0220__Data-Structure/SerializeanArrayListobjecttoabinaryfile.htm
// http://www.java2s.com/Tutorial/CSharp/0220__Data-Structure/DeserializeanArrayListobjectfromabinaryfile.htm
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("abc", typeof(string));
dt.Columns.Add("def", typeof(int));
System.Data.DataRow dr = dt.NewRow();
dr["abc"] = "test1";
dr["def"] = 123;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["abc"] = "test2";
dr["def"] = 456;
dt.Rows.Add(dr);
System.Data.DataSet ds = new System.Data.DataSet();
ds.Tables.Add(dt);
Console.WriteLine("Type: " + dt.GetType().FullName + ", Serializable: " + dt.GetType().IsSerializable);
kvp ObjectToSerialize1 = new kvp("key1", "value1");
kvp ObjectToSerialize2 = new kvp("key2", "value2");
kvp ObjectToSerialize3 = new kvp("key3", dt);
System.Collections.ArrayList al = new System.Collections.ArrayList();
al.Add(ObjectToSerialize1);
al.Add(ObjectToSerialize2);
al.Add(ObjectToSerialize3);
whatever what = new whatever();
what.MyKeyValueCollection = new kvp[3];
what.MyKeyValueCollection[0] = ObjectToSerialize1;
what.MyKeyValueCollection[1] = ObjectToSerialize2;
what.MyKeyValueCollection[2] = ObjectToSerialize3;
Type[] theExtraTypes = new Type[2];
//theExtraTypes[0] = typeof(System.Collections.ArrayList);
theExtraTypes[0] = typeof(kvp);
//theExtraTypes[2] = typeof(System.Data.DataTable);
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(what.GetType());
//System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(what.GetType(), theExtraTypes);
//System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(al.GetType());
//System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(System.Collections.ArrayList), theExtraTypes);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.IO.StringWriter writer = new System.IO.StringWriter(sb);
//ser.Serialize(writer, al); // Here Classes are converted to XML String.
ser.Serialize(writer, what); // Here Classes are converted to XML String.
// This can be viewed in SB or writer.
// Above XML in SB can be loaded in XmlDocument object
string strSerializedItem = sb.ToString();
Console.WriteLine(strSerializedItem);
/*
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
xmlDoc.LoadXml(sb.ToString());
System.IO.StringWriter sw = new System.IO.StringWriter();
System.Xml.XmlTextWriter xw = new System.Xml.XmlTextWriter(sw);
xmlDoc.WriteTo(xw);
string strSerialized = sw.ToString();
xw.Close();
sw.Close();
//sw.Dispose();
*/
}
static void Main(string[] args)
{
Serialization();
Console.WriteLine(Environment.NewLine);
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey(true);
}
}
}
修改
显然,运行时序列化和XML序列化之间存在差异
在这里阅读:
http://www.codeproject.com/KB/aspnet/Serialization.aspx
在这里
http://manishagrahari.blogspot.com/2011/08/serialization-in-net-part-4.html
在这里
http://blog.kowalczyk.info/article/Serialization-in-C.html
在这里
http://www.codeproject.com/KB/XML/Serialization_Samples.aspx
这里有核心方法:
http://www.15seconds.com/issue/020903.htm
而这个
http://www.codeproject.com/KB/XML/Serialization_Samples.aspx
对于SOAP序列化,您需要添加对以下内容的引用:
System.Runtime.Serialization.Formatters.Soap
答案 0 :(得分:1)
一般情况下,你不能这样做。可以将事物置于无法进行XML序列化的会话状态。
答案 1 :(得分:-1)
这很可能
这是一场艰苦的战斗,但这是有可能的。
简言之77:
使用属性,将对象序列化为字符串,然后将两个字符串(以及类型信息,INCLUDING assemblyname)保存在arraylist中的容器类型中,然后序列化此ArrayList。
然后是反序列化的反向技巧。 第三方请注意,我可能没有正确捕获对象可能无法序列化的情况。例如,使用非可序列化类型(如字典)来测试它。
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionModuleUnitTest
{
public class Program
{
[Serializable()]
[System.Xml.Serialization.XmlRoot(ElementName = "SessionData")]
public class cSessionData
{
[System.Xml.Serialization.XmlElement(ElementName = "key")]
public string key;
[System.Xml.Serialization.XmlElement(ElementName = "assembly")]
public string AssemblyQualifiedName;
[System.Xml.Serialization.XmlElement(ElementName = "value")]
public string m_value;
[System.Xml.Serialization.XmlIgnore()]
public object value
{
get
{
object obj = null;
if (m_value == null)
return obj;
// Type.GetType only looks in the currently executing assembly and mscorlib
// unless you specify the assembly name as well.
//Type T = Type.GetType(this.datatype);
Type T = Type.GetType(this.AssemblyQualifiedName);
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(T);
System.IO.StringReader sr = new System.IO.StringReader(m_value);
obj = ser.Deserialize(sr);
sr.Close();
//sr.Dispose();
sr = null;
ser = null;
return obj;
} // End Get
set
{
//this.m_value = value;
//Console.WriteLine("Type: " + obj.GetType().FullName + ", Serializable: " + obj.GetType().IsSerializable);
if (value != null)
{
//this.datatype = value.GetType().FullName;
this.AssemblyQualifiedName = value.GetType().AssemblyQualifiedName;
if (value.GetType().IsSerializable)
{
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(value.GetType());
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.IO.StringWriter writer = new System.IO.StringWriter(sb);
ser.Serialize(writer, value);
this.m_value = sb.ToString();
writer.Close();
//writer.Dispose();
sb = null;
writer = null;
ser = null;
}
else
this.m_value = null;
}
else
{
this.AssemblyQualifiedName = null;
this.m_value = null;
}
} // End Set
} // End Property value
public cSessionData()
{
} // End Constructor
public cSessionData(string strKey, object obj)
{
this.key = strKey;
this.value = obj;
} // End Constructor
} // End Class cSessionData
public static string Serialize(System.Collections.ArrayList al)
{
Type[] theExtraTypes = new Type[2];
theExtraTypes[0] = typeof(System.Collections.ArrayList);
theExtraTypes[1] = typeof(cSessionData);
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(System.Collections.ArrayList), theExtraTypes);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.IO.StringWriter writer = new System.IO.StringWriter(sb);
ser.Serialize(writer, al);
string strSerializedItem = sb.ToString();
sb = null;
writer.Close();
//writer.Dispose();
writer = null;
ser = null;
/*
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
xmlDoc.LoadXml(sb.ToString());
System.IO.StringWriter sw = new System.IO.StringWriter();
System.Xml.XmlTextWriter xw = new System.Xml.XmlTextWriter(sw);
xmlDoc.WriteTo(xw);
string strSerialized = sw.ToString();
xw.Close();
sw.Close();
//sw.Dispose();
*/
return strSerializedItem;
}
public static void Serialization()
{
// http://www.java2s.com/Tutorial/CSharp/0220__Data-Structure/SerializeanArrayListobjecttoabinaryfile.htm
// http://www.java2s.com/Tutorial/CSharp/0220__Data-Structure/DeserializeanArrayListobjectfromabinaryfile.htm
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("abc", typeof(string));
dt.Columns.Add("def", typeof(int));
System.Data.DataRow dr = dt.NewRow();
dr["abc"] = "test1";
dr["def"] = 123;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["abc"] = "test2";
dr["def"] = 456;
dt.Rows.Add(dr);
System.Data.DataSet ds = new System.Data.DataSet();
ds.Tables.Add(dt);
Console.WriteLine("tname: " + dt.GetType().FullName);
cSessionData ObjectToSerialize1 = new cSessionData("key1", "value1");
cSessionData ObjectToSerialize2 = new cSessionData("key2", "value2");
cSessionData ObjectToSerialize3 = new cSessionData("key3", dt);
System.Collections.ArrayList al = new System.Collections.ArrayList();
al.Add(ObjectToSerialize1);
al.Add(ObjectToSerialize2);
al.Add(ObjectToSerialize3);
string strSerializedItem = Serialize(al);
Console.WriteLine(strSerializedItem);
Deserialize(strSerializedItem);
}
static void Deserialize(string strXML)
{
Type[] theExtraTypes = new Type[2];
theExtraTypes[0] = typeof(System.Collections.ArrayList);
theExtraTypes[1] = typeof(cSessionData);
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(System.Collections.ArrayList), theExtraTypes);
System.IO.StringReader sr = new System.IO.StringReader(strXML);
System.Collections.ArrayList myal = (System.Collections.ArrayList ) ser.Deserialize(sr);
foreach (cSessionData SessionData in myal)
{
Console.WriteLine(SessionData.key + "=" + SessionData.value);
}
cSessionData MySessionData = (cSessionData) myal[2];
Console.WriteLine(MySessionData.key + "=" + MySessionData.value);
System.Data.DataTable d = (System.Data.DataTable)MySessionData.value;
Console.WriteLine(d.Rows[0]["def"]);
} // End Sub Deserialize
static void Main(string[] args)
{
Serialization();
Console.WriteLine(Environment.NewLine);
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey(true);
} // End Sub Main
} // End Class Program
} // Namespace SessionModuleUnitTest
编辑: 第1版:
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionModuleUnitTest
{
public class Program
{
[Serializable()]
[System.Xml.Serialization.XmlRoot(ElementName = "SessionData")]
public class cSessionData
{
[System.Xml.Serialization.XmlElement(ElementName = "key")]
public string key;
[System.Xml.Serialization.XmlElement(ElementName = "assembly")]
public string AssemblyQualifiedName;
[System.Xml.Serialization.XmlElement(ElementName = "value")]
public string m_value;
[System.Xml.Serialization.XmlIgnore()]
public object value
{
get
{
object obj = null;
if (m_value == null)
return obj;
// Type.GetType only looks in the currently executing assembly and mscorlib
// unless you specify the assembly name as well.
//Type T = Type.GetType(this.datatype);
Type T = Type.GetType(this.AssemblyQualifiedName);
obj = DeSerializeSOAP(m_value);
return obj;
} // End Get
set
{
//this.m_value = value;
//Console.WriteLine("Type: " + obj.GetType().FullName + ", Serializable: " + obj.GetType().IsSerializable);
if (value != null)
{
//this.datatype = value.GetType().FullName;
this.AssemblyQualifiedName = value.GetType().AssemblyQualifiedName;
if (value.GetType().IsSerializable)
{
this.m_value = SerializeSOAP(value);
}
else
this.m_value = null;
}
else
{
this.AssemblyQualifiedName = null;
this.m_value = null;
}
} // End Set
} // End Property value
public cSessionData()
{
} // End Constructor
public cSessionData(string strKey, object obj)
{
this.key = strKey;
this.value = obj;
} // End Constructor
} // End Class cSessionData
//public static void InsertSessionData(cSessionData SessionData)
public static void InsertSessionData(string strSessionUID, string strSessionID, string strKey, string strValue, string strDataType)
{
strSessionUID = strSessionUID.Replace("'", "''");
strSessionID = strSessionID.Replace("'", "''");
strKey = strKey.Replace("'", "''");
strValue = strValue.Replace("'", "''");
strDataType = strDataType.Replace("'", "''");
string strSQL = @"
INSERT INTO dbo.T_SessionValues
(
Session_UID
,Session_ID
,Session_Key
,Session_Value
,Session_DataType
)
VALUES
(
'" + strSessionUID + @"' --<Session_UID, uniqueidentifier, newid()>
,N'" + strSessionID + @"' --<Session_ID, nvarchar(84), NULL>
,N'" + strKey + @"' --<Session_Key, nvarchar(100), NULL>
,N'" + strValue + @"' --<Session_Value, nvarchar(max),NULL>
,N'" + strDataType + @"' --<Session_DataType, nvarchar(4000),NULL>
)
";
//System.Runtime.Serialization.Formatters.Binary.
COR.SQL.MS_SQL.Execute(strSQL);
}
// Add reference to System.Runtime.Serialization.Formatters.Soap
public static string SerializeSOAP(object obj)
{
string strSOAP = null;
System.Runtime.Serialization.Formatters.Soap.SoapFormatter serializer = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
using (System.IO.MemoryStream memStream = new System.IO.MemoryStream())
{
serializer.Serialize(memStream, obj);
long pos = memStream.Position;
memStream.Position = 0;
using (System.IO.StreamReader reader = new System.IO.StreamReader(memStream))
{
strSOAP = reader.ReadToEnd();
memStream.Position = pos;
reader.Close();
}
}
return strSOAP;
}
public static object DeSerializeSOAP(string SOAP)
{
if (string.IsNullOrEmpty(SOAP))
{
throw new ArgumentException("SOAP can not be null/empty");
}
using (System.IO.MemoryStream Stream = new System.IO.MemoryStream(UTF8Encoding.UTF8.GetBytes(SOAP)))
{
System.Runtime.Serialization.Formatters.Soap.SoapFormatter Formatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
return Formatter.Deserialize(Stream);
}
}
public static System.Collections.ArrayList GetData()
{
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("abc", typeof(string));
dt.Columns.Add("def", typeof(int));
System.Data.DataRow dr = dt.NewRow();
dr["abc"] = "test1";
dr["def"] = 123;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["abc"] = "test2";
dr["def"] = 456;
dt.Rows.Add(dr);
System.Data.DataSet ds = new System.Data.DataSet();
ds.Tables.Add(dt);
cSessionData ObjectToSerialize1 = new cSessionData("key1", "value1");
cSessionData ObjectToSerialize2 = new cSessionData("key2", "value2");
cSessionData ObjectToSerialize3 = new cSessionData("key3", dt);
System.Collections.ArrayList al = new System.Collections.ArrayList();
al.Add(ObjectToSerialize1);
al.Add(ObjectToSerialize2);
al.Add(ObjectToSerialize3);
return al;
}
public static void Deserialize(string strSOAP)
{
System.Collections.ArrayList myal = (System.Collections.ArrayList)DeSerializeSOAP(strSOAP);
foreach (cSessionData SessionData in myal)
{
Console.WriteLine(SessionData.key + "=" + SessionData.value);
}
cSessionData MySessionData = (cSessionData)myal[2];
Console.WriteLine(MySessionData.key + "=" + MySessionData.value);
System.Data.DataTable d = (System.Data.DataTable)MySessionData.value;
Console.WriteLine(d.Rows[0]["def"]);
}
public static string Serialize(System.Collections.ArrayList al)
{
// http://www.java2s.com/Tutorial/CSharp/0220__Data-Structure/SerializeanArrayListobjecttoabinaryfile.htm
// http://www.java2s.com/Tutorial/CSharp/0220__Data-Structure/DeserializeanArrayListobjectfromabinaryfile.htm
string strSerializedItem = SerializeSOAP(al);
Console.WriteLine(strSerializedItem);
return strSerializedItem;
}
static void Main(string[] args)
{
//InsertSessionData(System.Guid.NewGuid().ToString(), "fdslfkjsdalfj", "Key1", "Value1", typeof(System.Data.DataTable).AssemblyQualifiedName);
string strSOAP = Serialize(GetData());
Deserialize(strSOAP);
Console.WriteLine(Environment.NewLine);
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey(true);
} // End Sub Main
} // End Class Program
} // Namespace SessionModuleUnitTest