gpt4 book ai didi

c# - ExtensionDataObject 未标记为可序列化

转载 作者:行者123 更新时间:2023-12-02 13:32:34 26 4
gpt4 key购买 nike

喂!

我在序列化 session 状态时遇到问题。我们有 2 个组件:WCF 和 Web。基于我们的 AdministrationPartial.cs 和 Administration.svc,我们使用以下 .bat 文件为我们的 Web 项目生成“Administration.cs”代码:

svcutil.exe http://wcf_url.local/Administration.svc?wsdl /r:"{Path}\{Namespace}.dll" /d:"{Path}\{Namespace}\Code"

我从上述语句中删除了个人数据,并将其替换为 {path} 和 {namespace}。 Administration.cs 将位于代码映射内。

在部分中我们有:

[Serializable]
public partial class MyObject
{
<Some code>
}

它生成了以下代码:

namespace {mynamespace}
{
using System.Runtime.Serialization

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="MyObject", Namespace="http://schemas.datacontract.org/2004/07/{namespace}")]
public partial class MyObject : object, System.Runtime.Serialization.IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
...... generated code

我做错了什么?

蒂姆

编辑:实际错误是:在程序集“System.Runtime.Serialization,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”中键入“System.Runtime.Serialization.ExtensionDataObject”未标记为可序列化.

最佳答案

看来您的问题是,如何为BinaryFormatter创建一个[Serializable]并且还实现IExtensibleDataObject的类> 对于 DataContractSerializer

答案是,这不能开箱即用,因为正如您所注意到的,ExtensionDataObject未标记为可序列化。不过,这可以通过一些额外的编码来完成。无论出于何种原因,微软选择将ExtensionDataObject设为完全不透明的指针,没有公共(public)属性或其他方式来访问其中的数据。除了可以通过使用 DataContractSerializer 重新序列化为 XML 来访问内部数据。 。这建议了一种使您的 MyObject 类可序列化的方法:将扩展数据存储在实现 ISerializable 的代理容器字段中。并在内部将扩展数据序列化和反序列化为 XML。

以下代理包装器完成此任务:

[Serializable]
public struct ExtensionDataObjectSerializationProxy : ISerializable
{
public static implicit operator ExtensionDataObjectSerializationProxy(ExtensionDataObject data) { return new ExtensionDataObjectSerializationProxy(data); }

public static implicit operator ExtensionDataObject(ExtensionDataObjectSerializationProxy proxy) { return proxy.ExtensionData; }

private readonly System.Runtime.Serialization.ExtensionDataObject extensionDataField;

public ExtensionDataObject ExtensionData { get { return extensionDataField; } }

[DataContract(Name = "ExtensionData", Namespace = "")]
sealed class ExtensionDataObjectSerializationContractProxy : IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

#region IExtensibleDataObject Members

public ExtensionDataObject ExtensionData
{
get
{
return extensionDataField;
}
set
{
extensionDataField = value;
}
}

#endregion
}

public ExtensionDataObjectSerializationProxy(ExtensionDataObject extensionData)
{
this.extensionDataField = extensionData;
}

public ExtensionDataObjectSerializationProxy(SerializationInfo info, StreamingContext context)
{
var xml = (string)info.GetValue("ExtensionData", typeof(string));
if (!string.IsNullOrEmpty(xml))
{
var wrapper = DataContractSerializerHelper.LoadFromXML<ExtensionDataObjectSerializationContractProxy>(xml);
extensionDataField = (wrapper == null ? null : wrapper.ExtensionData);
}
else
{
extensionDataField = null;
}
}

#region ISerializable Members

void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (ExtensionData != null)
{
var xml = DataContractSerializerHelper.GetXml(new ExtensionDataObjectSerializationContractProxy { ExtensionData = this.ExtensionData });
info.AddValue("ExtensionData", xml);
}
else
{
info.AddValue("ExtensionData", (string)null);
}
}

#endregion
}

public static class DataContractSerializerHelper
{
public static string GetXml<T>(T obj, DataContractSerializer serializer = null)
{
using (var textWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(textWriter))
{
(serializer ?? new DataContractSerializer(typeof(T))).WriteObject(xmlWriter, obj);
}
return textWriter.ToString();
}
}

public static T LoadFromXML<T>(string xml, DataContractSerializer serializer = null)
{
using (var textReader = new StringReader(xml ?? ""))
using (var xmlReader = XmlReader.Create(textReader))
{
return (T)(serializer ?? new DataContractSerializer(typeof(T))).ReadObject(xmlReader);
}
}
}

然后手动修改您的 MyObject 类,如下所示:

public partial class MyObject : object, System.Runtime.Serialization.IExtensibleDataObject
{
private ExtensionDataObjectSerializationProxy extensionDataField; // Use the proxy not ExtensionDataObject directly

public ExtensionDataObject ExtensionData
{
get
{
return extensionDataField;
}
set
{
extensionDataField = value;
}
}
}

关于c# - ExtensionDataObject 未标记为可序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32056762/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com