标签: datacontractserializer

树结构的序列化/ Derialization

我试图找出保存(序列化)和以后打开(反序列化)树结构的最佳方法.我的结构由具有不同属性的各种对象类型组成,但每个都继承自基本抽象"Node"类.

每个节点都有唯一的ID(GUID),并有一个AddSuperNode(Node nd)方法,用于设置节点的父节点.这反过来调用其他方法,允许父节点知道它具有哪些子节点.但是,某些节点还使用AddAuxSuperNode()方法向节点添加辅助父节点.

我正在使用二进制序列化,但现在我想我想使用一些我有更多控制的东西,并且序列化数据更容易访问.我还希望在反序列化时保留Type信息,并能够序列化私有值.所以DataContractSerializer似乎是最好的方式.

我不能只序列化的根节点直接因为有多个父节点.我不想创建重复的对象.所以我似乎需要将树解构为一个平面列表,然后将其序列化.然后在序列化该列表后重建树.这听起来不错吗?

就像我之前说的,每个节点都有一个唯一的GUID标识符,但是现在节点直接引用它们的父节点/子节点而不存储它们的id.我可以更新AddSuperNode()AddAuxSuperNode()方法,以便除了直接引用之外还更新要序列化的父ID列表.但是我宁愿只在序列化对象时更新/创建这个列表.所以我想在节点中创建一个UpdateSuperNodeIDRefs()方法,该方法将在序列化之前调用.

以下是我计划对此结构进行序列化和反序列化的操作.任何人都可以建议更好/更清洁/更有效的方法吗?

序列化

1)提供树结构的根节点

2)细分树结构成扁平字典(GUID ID,节点ND)其中IDGUIDND.

3)调用UpdateSuperNodeIDRefs() ; 为每个节点更新为其父节点保存的ID.

4)使用DataContractSerializer序列化节点字典

反序列化

1)反序列化节点字典

2)遍历字典中的每个节点,将每个节点重新连接到其父节点.对于存储的任何父ID,查找具有匹配ID 的字典中的相应节点调用AddSuperNode()AddAuxSuperNode()以将节点重新连接到其父节点.

3)从Dictionary中的任何节点找到结构的根

4)返回根节点

c# serialization datacontract datacontractserializer

5
推荐指数
1
解决办法
4718
查看次数

为什么WCF将请求/响应类型包装在另一个XML元素中,以及如何防止这种情况?

我有一个简单的echo服务,我已经为请求/响应定义了一个操作方法和一对类型:

[ServiceContract(Name = "EchoService", 
                 Namespace = "http://example.com/services", 
                 SessionMode = SessionMode.NotAllowed)]
public interface IEchoService
{
    [OperationContract(IsOneWay = false,
                       Action = "http://example.com/services/EchoService/Echo", 
                       ReplyAction = "http://example.com/services/EchoService/EchoResponse")]
    EchoResponse Echo(EchoRequest value);
}
Run Code Online (Sandbox Code Playgroud)

数据类型:

[Serializable]
[DataContract(Namespace = "http://example.com/services/EchoService", 
              Name = "EchoRequest")]
public class EchoRequest
{
    public EchoRequest() { }

    public EchoRequest(String value)
    {
        Value = value;
    }

    [DataMember]
    public String Value { get; set; }
}

[Serializable]
[DataContract(Namespace = "http://example.com/services/EchoService", 
              Name = "EchoResponse")]
public class EchoResponse
{
    public EchoResponse() { }

    public EchoResponse(String value)
    {
        Value …
Run Code Online (Sandbox Code Playgroud)

wcf message datacontractserializer

5
推荐指数
1
解决办法
1万
查看次数

XML序列化 - 何时使用DataContractSerializer/Binary/XMLSerialiser

我已经看了一会儿了

似乎不鼓励使用二进制序列化,因为对字段名称的任何更改都会破坏序列化=?不好

XMLSerializer是有问题的,因为您必须提供无参数构造函数和公共字段,尽管您可以更多地控制元素属性或元素及其命名

DataContractSerializer很好,但需要明确添加所有的分类,这是一种耻辱

但是我偶然发现NetDataContractSerializer没有这个限制.

如果你的目标是C#序列化并且对xml的大小没有很大的限制,那么NetDataContractSerializer总是可以去这里吗?

c# datacontractserializer xmlserializer

5
推荐指数
1
解决办法
5939
查看次数

如何在同一主机上同时支持DataContractSerializer和XMLSerializer?

在我们的生产环境中,我们的WCF服务使用XMLSerializer进行序列化.为此,我们的服务接口具有[XMLSerializerFormat]属性.现在,我们需要更改为DataContractSerializer,但我们必须与现有客户端保持兼容.因此,我们必须使用两个序列化程序公开每个服务.

我们有一个约束:我们不想重新定义每个合同接口两次,我们有50个服务合同接口,我们不希望有

IIncidentServiceXml 
IIncidentServiceDCS
IEmployeeServiceXml 
IEmployeeServiceDCS
IContractServiceXml 
IContractServiceDCS
Run Code Online (Sandbox Code Playgroud)

我们怎么做?


更多信息

这是对我们迄今为止所尝试的内容的描述,但我愿意尝试完全不同的方法:

我们尝试通过自己的ServiceHostFactory类中的代码创建所有端点.基本上我们创建两个端点两次.问题是在运行时,WCF抱怨该服务有两个具有相同联系人名称但具有不同ContractDescription实例的端点.消息说我们应该使用不同的合同名称或重用相同的ContractDescription实例.

其他尝试:

我们还尝试通过为每个ContractDescription实例使用不同的命名空间来实现.这样我们将保持相同的合同接口(IIncidentService),但有两个不同的命名空间:

http://ourcompany/XML/IIncidentService
http://ourcompany/DCS/IIncidentService
Run Code Online (Sandbox Code Playgroud)

有了这个,我们能够得到更远,但服务崩溃与一个奇怪的例外:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.XmlSerializerOperationBehavior
contract: http://ourcompany.cs/XML:IUserServiceWCF ----> System.NullReferenceException: Object reference not set to an instance of an object.
   at System.ServiceModel.Description.XmlSerializerMessageContractExporter.ExportFaults(Object state)
   at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract()
   at System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext)
   at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
Run Code Online (Sandbox Code Playgroud)

.net c# wcf xml-serialization datacontractserializer

5
推荐指数
1
解决办法
3400
查看次数

停止DataContractSerializer放入命名空间?

我想将datacontract类序列化为XMl,但没有命名空间.

我已经添加:

[DataContract(Namespace="")]
Run Code Online (Sandbox Code Playgroud)

但我仍然得到:

<Person xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Title>Mr</Title>
...
</Person>
Run Code Online (Sandbox Code Playgroud)

有没有办法阻止这种情况发生,因为我只想将干净的xml传递给遗留组件.

datacontract datacontractserializer

5
推荐指数
0
解决办法
2830
查看次数

DataContractSerializer与BinaryFormatter性能

我正在阅读文章,以了解有关datacontractserializer和binaryformatter序列化器的更多信息.基于到目前为止所做的阅读,我的印象是binaryformatter应该比datacontractserializer的占用空间小.原因是DataContractSerializer序列化为xml信息集,而binaryformatter序列化为专有二进制格式.

以下是测试

    [Serializable]
    [DataContract]
    public class Packet
    {
        [DataMember]
        public DataSet Data { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Description { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

DataSet填充了表中的121317[AdventureWorks].[Sales].[SalesOrderDetail]

    using (var fs = new FileStream("test1.txt", FileMode.Create))
    {
        var dcs = new DataContractSerializer(typeof(Packet));
        dcs.WriteObject(fs, packet);
        Console.WriteLine("Total bytes with dcs = " + fs.Length);
    }



    using(var fs = new FileStream("test2.txt", FileMode.Create))
    {
       var bf = new BinaryFormatter();
       bf.Serialize(fs, packet);
       Console.WriteLine("Total bytes with binaryformatter = …
Run Code Online (Sandbox Code Playgroud)

c# datacontractserializer binaryformatter c#-4.0

5
推荐指数
1
解决办法
5222
查看次数

为什么DataContractSerializer被截断的StringWriter?

DataContractSerializer如果有异常,我正在使用序列化EF4对象到xml.在我的调试日志中,我可以看到当出现问题时想要的是数据内容.

我有两个版本的代码:一个版本序列化为一个文件,一个版本序列化为一个字符串使用StringWriter.

将大项目序列化到文件时,我获得大约16kb的有效xml.当序列化相同的项目到字符串时,xml在12kb之后被截断.知道导致截断的原因吗?

    ...
    var entity = ....
    SaveAsXml(entity, @"c:\temp\EntityContent.xml"); // ok size about 16100 btes
    var xmlString = GetAsXml(entity); // not ok, size about 12200 bytes

    // to make shure that it is not Debug.Writeline that causes the truncation
    // start writing near the end of the string
    // only 52 bytes are written although the file is 16101 bytes long
    System.Diagnostics.Debug.Writeline(xml.Substring(12200)); 
Run Code Online (Sandbox Code Playgroud)

我的字符串被截断的任何想法?

这是序列化到文件的代码,可以正常工作

  public static void SaveAsXml(object objectToSave, string filenameWithPath)
  {
     string directory = Path.GetDirectoryName(filenameWithPath); …
Run Code Online (Sandbox Code Playgroud)

.net c# serialization datacontractserializer stringwriter

5
推荐指数
1
解决办法
2786
查看次数

自定义类包含另一个自定义类时,DataContractResolver/KnownType问题

我正在尝试使用DataContractJsonSerializer类将对象列表输出为json格式,但是我一直遇到以下错误.

Type 'Castle.Proxies.JokeCategoryProxy' with data contract name 
'JokeCategoryProxy:http://schemas.datacontract.org/2004/07/Castle.Proxies' 
is not expected. Consider using a DataContractResolver or add any types not 
known statically to the list of known types - for example, by using the
KnownTypeAttribute attribute or by adding them to the list of known 
types passed to DataContractSerializer.
Run Code Online (Sandbox Code Playgroud)

我知道这已经得到了回答,但只有在我的对象中有一个属性是另一个自定义对象时才会发生.

[DataContract]
[KnownType(typeof(ModelBase<int>))]
public class Joke : ModelBase<int>
{
    [DataMember]
    public virtual string JokeText { get; set; }

    [DataMember]
    public virtual JokeCategory JokeCategory { get; set; }
}

[DataContract]
[KnownType(typeof(ModelBase<int>))]
public …
Run Code Online (Sandbox Code Playgroud)

.net c# fluent-nhibernate datacontractserializer known-types

5
推荐指数
1
解决办法
7547
查看次数

事先不知道派生类型时使用DataContractSerializer反序列化派生类型

在大会A中:

[DataContract]    
        public class Base
        {
            [DataMember]
            public string SomeText { get; set; }
        }
Run Code Online (Sandbox Code Playgroud)

在大会B中:

internal class Helper
        {
           internal static Base Deserialize(string serializedInstanceOfTypeBase)
    {
                   DataContractSerializer serializer = new DataContractSerializer(typeof (Base));
                    XmlReader reader = XmlReader.Create(new StringReader(serializedInstanceOfTypeBase));
                    return (Base)serializer.ReadObject(reader);
    }
    }
Run Code Online (Sandbox Code Playgroud)

在程序集C中:

[DataContract]    
        public class Derived : Base
        {
            [DataMember]
            public string SomeMoreText { get; set; }
        }
Run Code Online (Sandbox Code Playgroud)

如果我序列化一个类型的实例Derived并将其传递给Helper.Deserialize()方法,它将失败SerializationException:

第1行位置错误2.期望命名空间'http://schemas.datacontract.org/2004/07'中的元素'Base'.遇到名为'Derived'的'Element',命名空间'http://schemas.datacontract .ORG/2004/07' .

我该怎样摆脱这个问题?

我知道KnownType属性,但在程序集A和B编码时,我完全不知道它的派生类型.所以我不能使用那个解决方案.

我的产品设计比较复杂,我不能完全在这里发布.Helper.Desrialize()方法只是得到一个string参数.Base即使在运行时,也无法(至少目前)对程序集A或B了解类的派生类型.

程序集B引用程序集A.但A&B不能引用程序集C. …

c# datacontractserializer deserialization

5
推荐指数
1
解决办法
3134
查看次数

序列化Observable Collection时出错

我有一个可观察的集合,我正在尝试序列化到磁盘.收到的错误是:

 Type 'VisuallySpeaking.Data.GrammarList' with data contract name
 'GrammarList:http://schemas.datacontract.org/2004/07/VisuallySpeaking.Data'
 is not expected. Consider using a DataContractResolver or add any
 types not known statically to the list of known types - for example,
 by using the KnownTypeAttribute attribute or by adding them to the
 list of known types passed to
 DataContractSerializer."}  System.Exception
 {System.Runtime.Serialization.SerializationException}
Run Code Online (Sandbox Code Playgroud)

这是我的数据对象:

namespace VisuallySpeaking.Data
{

    [CollectionDataContract]
    public class GrammarList : ObservableCollection<GrammarDataObject>
{
    public GrammarList() : base()
    {
        Add(new GrammarDataObject("My Name", "My name is","Assets/SampleAssets/MyName.png"));
        Add(new GrammarDataObject("Where is", "Where is",""));
        Add(new GrammarDataObject("Dog", …
Run Code Online (Sandbox Code Playgroud)

c# wcf observablecollection datacontractserializer windows-store-apps

5
推荐指数
1
解决办法
981
查看次数