没有DataMember属性的DataContract序列化

时间:2012-07-03 10:29:12

标签: c# wcf linq-to-sql serialization datacontractserializer

我使用FreezeAllAccountsForUser函数生成以下XML。我需要为此函数仅序列化以下两列。如何将序列化限制为两列?

  1. BankAccountID
  2. 状态
  3. 注意:关键点是,制定此限制的范围应仅在FreezeAllAccountsForUser函数内; 不是全球

    参考

    1. Serializing IEnumerable Containing Derived classes: Circular Reference Issue
    2. XML

       <ArrayOfBankAccount xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" z:Size="1" 
                      xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" 
                      xmlns="http://schemas.datacontract.org/2004/07/DBML_Project">
      
        <BankAccount z:Id="2" i:type="FixedBankAccount">
      
      <AccountOwnerID>2</AccountOwnerID>
      <AccountType z:Id="3">Fixed     </AccountType>
      <BankAccountID>2</BankAccountID>
      
      <BankUser z:Id="4">
        <BankAccounts z:Id="5" z:Size="1">
          <BankAccount z:Ref="2" i:nil="true" />
        </BankAccounts>
        <Name z:Id="6">TestP1    </Name>
        <UserID>2</UserID>
        <UserType z:Id="7">Ordinary  </UserType>
      </BankUser>
      
      <OpenedDate i:nil="true" />
      
      <Status z:Id="8">FrozenFA</Status>
      
         </BankAccount>
      
      </ArrayOfBankAccount>
      

      序列化

      public class BankAccountAppService
      {
          public RepositoryLayer.ILijosBankRepository AccountRepository { get; set; }
      
          public void FreezeAllAccountsForUser(int userId)
          {
              IEnumerable<DBML_Project.BankAccount> accounts = AccountRepository.GetAllAccountsForUser(userId);
              foreach (DBML_Project.BankAccount acc in accounts)
              {
      
                  string typeResult = Convert.ToString(acc.GetType());
                  string baseValue = Convert.ToString(typeof(DBML_Project.BankAccount));
      
                  if (String.Equals(typeResult, baseValue))
                  {
                      throw new Exception("Not correct derived type");
                  }
      
                  acc.Freeze();
              }
      
      
      
              System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
              System.Xml.XPath.XPathNavigator nav = xmlDoc.CreateNavigator();
      
              using (System.Xml.XmlWriter writer = nav.AppendChild())
              {
                  System.Runtime.Serialization.DataContractSerializer serializer = new System.Runtime.Serialization.DataContractSerializer(typeof(List<DBML_Project.BankAccount>), null, int.MaxValue, false, true, null);
                  serializer.WriteObject(writer, accounts);
              }
      
              xmlDoc.Save("C:\\DevTEST\\FileName.txt");
      
      
      
          }
      
      }
      

      域类

      namespace DBML_Project
      {
      [KnownType(typeof(FixedBankAccount))]
      [KnownType(typeof(SavingsBankAccount))]
      public  partial class BankAccount
      {
          //Define the domain behaviors
          public virtual void Freeze()
          {
              //Do nothing
          }
      }
      
      public class FixedBankAccount : BankAccount
      {
      
          public override void Freeze()
          {
              this.Status = "FrozenFA";
          }
      }
      
      public class SavingsBankAccount : BankAccount
      {
      
          public override void Freeze()
          {
              this.Status = "FrozenSB";
          }
      }  
      }
      

      LINQ to SQL自动生成的类

      [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.BankAccount")]
      [InheritanceMapping(Code = "Fixed", Type = typeof(FixedBankAccount), IsDefault = true)]
      [InheritanceMapping(Code = "Savings", Type = typeof(SavingsBankAccount))]
      public partial class BankAccount : INotifyPropertyChanging, INotifyPropertyChanged
      

1 个答案:

答案 0 :(得分:7)

这听起来很难听(我知道你在两个序列化器之间蹦蹦跳跳),但是:XmlSerializer 支持这两种方式:a)by使用XmlAttributeOverrides在运行时指定属性,b)通过“条件序列化”(public bool ShouldSerializeFoo()成员Foo)。 DataContractSerializer不支持这些。不同的序列化器:不同的功能。

我的建议:停止尝试将序列化纳入您的域模型。那可以工作,但是当它变得混乱停止对抗的那一刻,并创建一个简单的单独DTO模型,旨在被序列化作为它的主要目的< / em>,只需根据需要在域模型和DTO模型之间进行映射。