.net 序列化为XML私有属性

.net 序列化为XML私有属性,.net,xml-serialization,poco,.net,Xml Serialization,Poco,我正在寻找一种方法来序列化包含一些只读属性的POCO。在一些Google和StackOverflow搜索中,我看到了以下建议: 使用DataContractSerializer;或 使用SoapFormatter或BinaryFormatter;或 将我的只读属性替换为读/写属性 我的课程非常简单,它们看起来像: public class MyClass { public int Id { get; private set; } public string Name { ge

我正在寻找一种方法来序列化包含一些只读属性的POCO。在一些Google和StackOverflow搜索中,我看到了以下建议:

  • 使用DataContractSerializer;或
  • 使用SoapFormatter或BinaryFormatter;或
  • 将我的只读属性替换为读/写属性
我的课程非常简单,它们看起来像:

public class MyClass
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public MyClass(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
所以

  • 我不想让我的属性读/写。如果它们是只读的,那是因为我的域模型要求只读属性。域模型不能因此而更改
  • 我不想使用
    DataContractSerializer
    ,因为这会用序列化相关的东西污染我的域模型
  • BinaryFormatter
    不是一个很好的选项,因为结果是一个
    byte[]
    ,我想将其视为
    string
    (在反序列化对象时,我不想处理Enconding和类似的问题)
我真正想要的是一个能够序列化只读属性的XmlSerializer类

你知道有这样的实施吗?还是其他方便的解决方案


谢谢

嗯,通常
XmlSerializer
无法序列化只读属性。。。但是,可以使用内部集合序列化属性:您需要生成XML序列化程序集,并使用
InternalsVisibleTo
属性将其声明为“友元”程序集。通过将以下代码添加到项目文件中,可以自动执行此操作:

  <Target Name="AfterBuild"
          DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
          Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
          Outputs="$(OutputPath)$(_SGenDllName)">
    <SGen BuildAssemblyName="$(TargetFileName)"
          BuildAssemblyPath="$(OutputPath)"
          References="@(ReferencePath)"
          ShouldGenerateSerializer="true"
          UseProxyTypes="false"
          KeyContainer="$(KeyContainerName)"
          KeyFile="$(KeyOriginatorFile)"
          DelaySign="$(DelaySign)"
          ToolPath="$(SGenToolPath)">
      <Output TaskParameter="SerializationAssembly"
              ItemName="SerializationAssembly" />
    </SGen>
  </Target>

当然,您可能不希望属性具有内部集,但如果您这样做,上述解决方案应该会起作用。

如果serialize可以访问私有属性,这将是一件好事。不幸的是,到目前为止,还没有简单的方法

但在架构解决方案方面还有另一种选择。 不要破坏您的业务领域需求,而是像nTeir设计一样分离您的层,并实现DTO的

如果您将您的业务、datafacade/DataAdapter(工厂模式非常适合这里)和DataAccess层分离为3个项目,您可以通过引用业务部门从不知道您的DTO来控制这些项目。 Hense如果您决定删除或实现序列化,或将其交换为保存到SQL server,则不会影响业务层中的任何内容

总有一个缺点,还有很多代码要写: *对于要转到Dataaccess的每个实体,必须双向编写对象转换器 *您可能会破坏一些隐藏的OO,因为业务中的.Save方法需要在转到dataaccess之前转换为Dataface中的正确类型

你可以用nHybinate或类似的东西使这一切变得更容易。 干杯
Choco是否应该是System.Xml.Serialization可见的内部构件?这是我第一次尝试这样做时的想法。。。但是,实际执行(反)序列化的程序集不是System.Xml,而是一个特定的序列化程序集。通常,此程序集是由XmlSerializer在运行时动态生成的,具有随机名称(因此您不能将其与InternalsVisibleTo一起使用),但您可以使用sgen.exe命令行工具或sgen build任务预生成它。在这种情况下,序列化程序集将被命名为YourAssemblyName.XMLSerializer非常有趣。我从来没有想过。然而,我想保留我的私人setter属性。谢谢@marc_s:我认为这不是一个简单的问题,而是一个依赖性的问题:将[DataMember]属性放在属性上会在业务领域引入对DataContractSerializer的依赖性你看过marc Gravell的“proto-buf”了吗?不确定它是否可以处理私有字段,但它是一个独立的、可扩展的序列化机制。
[assembly: InternalsVisibleTo("MyAssembly.XmlSerializers")]