如何在XML序列化期间区分not set和set为null?

时间:2014-04-08 16:07:30

标签: c# .net wcf xml-serialization

我有一个允许外部应用程序更新我的数据库的WCF服务。我有一个更新操作合同,它接受外部应用程序应该设置的数据合同。我的问题是我无法区分设置为null的内容和实际未设置的内容,因为在序列化数据协定时,值始终为null。请考虑以下数据合同:

[DataContract, XmlRoot("Person")]
public class Person: BaseEntity
{
    [DataMember, XmlElement]
    public string Prefix { get; set; }
    [DataMember, XmlElement]
    public string FirstName { get; set; }
    [DataMember, XmlElement]
    public string MiddleName { get; set; }
    [DataMember, XmlElement]
    public string LastName { get; set; }
    [DataMember, XmlElement]
    public string MaidenName { get; set; }
    [DataMember, XmlElement]
}

一个外部应用程序只能设置FirstName和LastName,并忽略其余属性。但是当我的WCF服务收到请求时,其他属性将设置为null。所以我的WCF服务中的更新statememt会认为这些属性设置为null。我希望找到一种方法来确定未设置的属性,以便我的更新语句可以忽略这些属性。

2 个答案:

答案 0 :(得分:0)

你无法区分这两种情况。每个变量的初始值都以初始值开始,null表示引用类型,0表示整数和浮点数等等。因此,

之间绝对没有区别
String firstName;

String firstName;

firstName = null;

这意味着如果您需要此信息,则必须手动执行跟踪。

String firstName;
Boolean firstNameSet;

firstName = null;
firstNameSet = true;

请注意,手动操作我的意思是您必须手动跟踪这些信息,当然您可以向属性设置者添加一些跟踪代码,以便您的班级用户不必了解这一点。 / p>

public class Person
{
   private String firstName = null;

   private Boolean firstNameSet = false;

   private String lastName = null;

   private Boolean lastNameSet = false;

   public String FirstName
   {
      get { return this.firstName; }
      set
      {
         this.firstName = value;
         this.firstNameSet = true;
      }
   }

   public String LastName
   {
      get { return this.lastName; }
      set
      {
         this.lastName = value;
         this.lastNameSet = true;
      }
   }
}

实现此功能还有很多其他选择,例如,您可以使用集合来跟踪集合属性。最好的解决方案显然取决于您的要求。

public class Person
{
   private readonly ISet<String> setProperties = new HashSet<String>();

   private String firstName = null;

   private String lastName = null;

   public String FirstName
   {
      get { return this.firstName; }
      set
      {
         this.firstName = value;
         this.setProperties.Add("FirstName");
      }
   }

   public String LastName
   {
      get { return this.lastName; }
      set
      {
         this.lastName= value;
         this.setProperties.Add("LastName");
      }
   }
}

答案 1 :(得分:0)

我最终创建了自定义类:

[DataContract, XmlRoot("Person")]
public class Person: BaseEntity
{
    [DataMember, XmlElement]
    public DomainString Prefix { get; set; }
    [DataMember, XmlElement]
    public DomainString FirstName { get; set; }
    [DataMember, XmlElement]
    public DomainString MiddleName { get; set; }
    [DataMember, XmlElement]
    public DomainString LastName { get; set; }
    [DataMember, XmlElement]
    public DomainString MaidenName { get; set; }
}

public class DomainString{
    public string Value {get; set;}
    public bool IsNull {get; set;}
}

因此在我的wcf客户端中,我可以执行ff。分化:

如果person.LastName == null,则表示未设置姓氏。 如果person.LastName.IsNull,则将lastname设置为null。