Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.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#Castle ActiveRecord:如何优雅地(XML)序列化ActiveRecord对象?_C#_Xml Serialization_Castle Activerecord - Fatal编程技术网

C#Castle ActiveRecord:如何优雅地(XML)序列化ActiveRecord对象?

C#Castle ActiveRecord:如何优雅地(XML)序列化ActiveRecord对象?,c#,xml-serialization,castle-activerecord,C#,Xml Serialization,Castle Activerecord,我很难找到有关如何优雅地序列化ActiveRecord对象的信息 我们希望使用XML作为格式,因为我们需要以另一个程序能够切实解析的方式输出对象 XML序列化通常非常容易实现,但在尝试序列化ActiveRecord数据库返回的对象时会出现问题。数据库返回一个对象的代理类,该类的类型不能通过[xmlclude]属性明确预期 例如: public class Foo : ActiveRecordLinqBase<Foo> { public virtual string Bar{ge

我很难找到有关如何优雅地序列化ActiveRecord对象的信息

我们希望使用XML作为格式,因为我们需要以另一个程序能够切实解析的方式输出对象

XML序列化通常非常容易实现,但在尝试序列化ActiveRecord数据库返回的对象时会出现问题。数据库返回一个对象的代理类,该类的类型不能通过
[xmlclude]
属性明确预期

例如:

public class Foo : ActiveRecordLinqBase<Foo>
{
   public virtual string Bar{get;set;}

   public virtual int FooId{get;set;}

   public Foo(string bar)
   {
      Bar = bar;
   }

   public static void FooSerializeExample()
   {
      Foo tehFoozor = new Foo("omgFoo!");
      tehFoozor.SaveAndFlush();
      int id = tehFoozor.FooId;

      //...
      //Assume new ActiveRecord session.

      XmlSerializer serializer = new XmlSerializer(typeof(Foo));

      Foo tehFoozorToSerialize = Foo.Find(id);

      using(Stream stream = File.OpenWrite("tehFoozor.xml"))
      {
         serializer.Serialize(stream, tehFoozorToSerialize); //Will fail
      }
   }
}
公共类Foo:ActiveRecordLinqBase
{
公共虚拟字符串栏{get;set;}
公共虚拟int FooId{get;set;}
公共Foo(字符串栏)
{
巴=巴;
}
公共静态void示例()
{
Foo-tehFoozor=新的Foo(“omgFoo!”);
tehFoozor.SaveAndFlush();
int id=tehFoozor.FooId;
//...
//假设新的ActiveRecord会话。
XmlSerializer serializer=新的XmlSerializer(typeof(Foo));
Foo-tehFoozorToSerialize=Foo.Find(id);
使用(Stream=File.OpenWrite(“tehFoozor.xml”))
{
serializer.Serialize(stream,tehFoozorToSerialize);//将失败
}
}
}
在这里序列化时,我们将收到一条消息:
“类型fooproxy2e24df9be42909d13a67fdb00b981不是预期的。请使用xmlclude或SoapInclude属性指定静态未知的类型。”

其中代理类型将完全不可预测(至少据我所知)

作为一个临时解决方案,我的团队将每个AR对象的属性剔除到接口中。然后,我们为每个对象实现了“容器”对象,它们本质上是对象的Xml可序列化非AR版本。考虑到我们目前有18个不同的AR对象被序列化,我们的解决方案中还有36个文件!有些东西(一切)告诉我这是一个糟糕的解决方案,但我还没有找到更好的办法


我们还尝试使用Soap格式化程序,但由于ActiveRecrodLinqBase没有“标记为可序列化”,这也是一条死胡同。

获取您迫切需要的所有内容,然后使用它将其映射到DTO并序列化这些DTO

您收到的代理错误表明您的DTO实际上使用的是NHibernate的代理集合,而他们应该使用普通的
列表
或数组。确保使用
ToList()
或类似工具


此外,您不需要使用接口来映射DTO。

尝试DataContractSerializer

它与[XmlInclude]的等价物是[KnownType],其中包含一个版本,该版本可以动态地提供类型,以便在第一次反映类型时包含该类型。看

另外,我认为(尽管不是100%确定)在DataContractSerializer中.NET4.0将包含一个“类型映射器”功能,这特别使类似这样的场景更容易


如果您最终尝试DCS并遇到问题,请将其作为评论发布到此答案,我将尝试回答这些问题。

经过更多搜索,我发现出现这种情况的原因是因为我们使用了“延迟加载”。这不是我们可以妥协的,因为我们将要加载的对象将具有深层层次结构,有时包含数千个要通过Microsoft MVC加载和显示的部分。一位高级开发人员排队寻找反射作为可能的解决方案。还有其他人经历过吗?我同意。。切勿尝试通过导线发送实际对象。Ayende写过一次,我同意他的观点:我可能弄错了,但我相信这是我们已经在做的事情:将对象映射到对象的基本克隆(不使用AutoMapper,因为在这种情况下它无法简化映射过程),然后序列化它们。正如我前面提到的,这为我们的解决方案添加了36个文件,其中不包括单元测试文件@Tigraine:我们不是通过电线发送实际的对象,但是我们需要在获取通过电线发送的数据时加载每个对象的一部分。这就是我们需要延迟加载的原因。没错,您已经在使用DTO,但DTO映射似乎不太正确。请参阅我的更新答案。问题不取决于对象中集合的类型。我使用了[XmlIgnore]来忽略每个实际的集合,并在一个单独的包装器属性上使用了[XmlArray(“”)和[XmlArrayItem(“”),该属性将集合转换为可序列化数组或从可序列化数组转换为可序列化数组。当前的解决方案映射到/从对象和序列化都很好,但它不是我们想要的优雅解决方案。一位高级开发人员正在研究使用一种使用深度反射的自定义XmlSerialization解决方案。不需要xml属性或自定义序列化。您只需要确保DTO没有代理,并且是普通列表/数组。检查任何可以使用代理的地方。如果不是集合,请检查lazy[BelongsTo]将测试此解决方案是否可行,并在此处更新结果。谢谢