对象匹配对象和字符串

本文关键字:对象 字符串 | 更新日期: 2023-09-27 18:16:00

我从XML文件中读取销售订单,并将DTO发送到一个rest式API,其中客户是一个字符串。返回的DTO包含一个客户对象,因此与输入对象中的字符串不匹配。

是否有一种方法来创建客户对象,使客户字符串作为DTO和返回的客户对象工作?

基本上,我想把字符串customer读入customer对象,让API认为它只是一个customer字符串,而不是customer对象。

XML文件:

<SalesOrder>
  <orderType>SO</orderType>
  <customer>10000</customer>
</SalesOrder>

客户对象从API返回:

 <customer>
      <number>10000</number>
      <internalId>2462</internalId>
      <lastModifiedDateTime>0001-01-01</lastModifiedDateTime>
     </customer>

SalesOrder中的客户get和set方法

[XmlElement("customer")]
public Customer customer
{
    get { return Get("customer", new Customer()); }
    set { Set(value); }
}

对象匹配对象和字符串

为了澄清您的问题,您希望能够设计您的Customer DTO,以便它可以用于反序列化以下简单的XML:

<SalesOrder>
  <orderType>SO</orderType>
  <customer>10000</customer>
</SalesOrder>

以及以下更复杂的XML:

<SalesOrder>
  <orderType>SO</orderType>
  <customer>
      <number>10000</number>
      <internalId>2462</internalId>
      <lastModifiedDateTime>0001-01-01</lastModifiedDateTime>
  </customer>
</SalesOrder>

但是,下面的XML将是无效的,并且尝试反序列化它应该抛出异常,因为它既有简单的客户编号,也有复杂的客户值集:

<SalesOrder>
  <orderType>SO</orderType>
  <customer>10000<number>10000</number>
      <internalId>2462</internalId>
      <lastModifiedDateTime>0001-01-01</lastModifiedDateTime>
  </customer>
</SalesOrder>

您还希望能够选择客户是否应该以简单格式或复杂格式重新序列化。

这可以在XmlSerializer中完成,但是对于可能具有文本值或可能具有子元素序列的元素类型(但不能同时具有文本值和子元素序列),没有内置支持。因此,您需要在类本身中支持此逻辑。下面的代码是这样做的:

[XmlRoot(ElementName = "customer")]
public class Customer
{
    bool? isSimpleFormat;
    [XmlIgnore]
    public bool IsSimpleFormat { get { return isSimpleFormat == true; } set { isSimpleFormat = value; } }
    [XmlIgnore]
    bool IsSimpleFormatDefined { get { return isSimpleFormat != null; } }
    [XmlIgnore]
    bool IsComplexPropertySpecified
    {
        get
        {
            return !IsSimpleFormat;
        }
        set
        {
            if (IsSimpleFormatDefined && IsSimpleFormat)
            {
                throw new InvalidOperationException("Cannot set a complex property on a simple customer");
            }
            IsSimpleFormat = !value;
        }
    }
    [XmlElement(ElementName = "number")]
    public string Number { get; set; }
    [XmlIgnore]
    public bool NumberSpecified { get { return IsComplexPropertySpecified; } set { IsComplexPropertySpecified = value; } }
    [XmlElement(ElementName = "internalId")]
    public string InternalId { get; set; }
    [XmlIgnore]
    public bool InternalIdSpecified { get { return IsComplexPropertySpecified; } set { IsComplexPropertySpecified = value; } }
    [XmlElement(ElementName = "lastModifiedDateTime")]
    public string LastModifiedDateTime { get; set; }
    [XmlIgnore]
    public bool LastModifiedDateTimeSpecified { get { return IsComplexPropertySpecified; } set { IsComplexPropertySpecified = value; } }
    [XmlText]
    public string SimpleNumber
    {
        get 
        {
            return IsSimpleFormat ? Number : null; 
        }
        set
        {
            IsComplexPropertySpecified = false;
            Number = value;
        }
    }
}
[XmlRoot(ElementName = "SalesOrder")]
public class SalesOrder
{
    [XmlElement(ElementName = "orderType")]
    public string OrderType { get; set; }
    [XmlElement(ElementName = "customer")]
    public Customer Customer { get; set; }
}

一些注意事项:

  1. 初始构造时,Customer默认为复杂格式,但将根据反序列化过程中是否遇到子元素或文本值进行调整。一旦设置了格式,它将不再适应,如果遇到格式错误的其他节点,将抛出异常。

  2. 在构造之后的任何时候,您的代码都可以通过设置布尔属性Customer.IsSimpleFormat来更改Customer是以简单格式序列化还是以复杂格式序列化。

  3. 该类型利用XmlSerializer*Specified模式来跟踪和控制Customer的子属性是否被反序列化,是否应该被序列化。

  4. 对应于复杂POCO的元素的XML文本值可以通过将该POCO的属性标记为[XmlText]来映射到该POCO的属性。

样本小提琴。

考虑使用Newtonsoft。Json用于序列化&反序列化

序列化的例子:

var customer = new Customer();
var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(Customer); 

反序列化@服务器端

var customer = Newtonsoft.Json.JsonConvert.DeserializeObject(serializedObject);

其中serializedObject是从请求中获得的字符串。