2011-06-18 33 views
6

Tôi đang cố tạo một tài liệu xml theo một định dạng cụ thể. Tôi muốn bỏ qua việc tuần tự hóa thuộc tính tùy thuộc vào giá trị của thuộc tính.Xml Serialization Dynamic Ignore

public class Parent 
{ 
    public Parent() 
    { 
     myChild = new Child(); 
     myChild2 = new Child() { Value = "Value" }; 
    } 
    public Child myChild { get; set; } 
    public Child myChild2 { get; set; } 
} 

public class Child 
{ 
    private bool _set; 
    public bool Set { get { return _set; } } 

    private string _value = "default"; 
    [System.Xml.Serialization.XmlText()] 
    public string Value 
    { 
     get { return _value; } 
     set { _value = value; _set = true; } 
    } 
} 

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(Parent)); 
x.Serialize(Console.Out, new Parent()); 

Nếu Set là sai, tôi muốn toàn bộ tài sản để không đăng, xml kết quả của tôi nên

<Parent> 
    <myChild2>default</myChild2> 
</Parent> 

Thay vì

<Parent> 
    <myChild/> 
    <myChild2>default</myChild2> 
</Parent> 

Có một số cách tôi có thể làm này sạch với IXmlSerializable hoặc bất cứ điều gì khác?

Cảm ơn!

Trả lời

6

Có một mô hình ShouldSerialize * (được giới thiệu bởi TypeDescriptor, nhưng được công nhận bởi một vài khu vực khác của mã, chẳng hạn như XmlSerializer):

public bool ShouldSerializemyChild() { 
    return myChild != null && myChild.Set; 
} 

Điều đó sẽ sắp xếp nó.

Một tùy chọn đơn giản hơn là gán giá trị rỗng.

+0

Tôi có nhiều thuộc tính có kiểu con, tôi không muốn có ShouldSerialize cho từng đơn lẻ. Tôi có thể thiết lập tất cả các thuộc tính của tôi thành null mà không được thiết lập trước khi tôi tuần tự hóa. – TrevDev

+0

Tôi đã đăng câu trả lời để tự động đặt giá trị thành null thông qua một phương thức sẽ được gọi trước khi tuần tự hóa. Bạn có một ý tưởng rõ ràng hơn cho việc gán một giá trị null không? – TrevDev

+0

@Thx không thực sự ... –

0

Nếu "mychild" được định nghĩa bởi mảng, tôi nghĩ rằng nó có thể làm tốt ...

public class Parent 
{ 
    public Parent() 
    { 
     myChild = new Child[]{ new Child(){Value = "Value"}}; 
     //myChild2 = new Child() { Value = "Value" }; 
    } 
    public Child[] myChild { get; set; } 
    //public Child myChild2 { get; set; } 
} 
0

Tôi nghĩ rằng điều này có thể làm việc, mặc dù bạn migh phải overide Equals phương pháp

[DefaultValue(new Child())] 
public Child myChild{ get; set; } 
+0

Thuộc tính đối số phải là một hằng số – TrevDev

0

Chỉ cần viết mã này cho vui và có thể tìm hiểu điều gì đó trong quá trình này. Nó sẽ đặt bất kỳ thuộc tính nào thành rỗng nếu thuộc tính đó chứa một phương thức có tên là Set trả về bool và giá trị hiện tại của nó là false. Bằng cách thiết lập các giá trị thành false, nó sẽ giải quyết vấn đề serializer. Bất kỳ đề xuất nào:

public static void RemoveUnsetObjects(object currentObject) 
{ 
    var type = currentObject.GetType(); 
    if (currentObject is IEnumerable) 
    { 
     IEnumerable list = (currentObject as IEnumerable); 
     foreach (object o in list) 
     { 
      RemoveUnsetObjects(o); 
     } 
    } 
    else 
    { 
     foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) 
     { 
      var propertyValue = p.GetValue(currentObject, null); 
      if (propertyValue == null) 
       continue; 
        var setPropInfo = p.PropertyType.GetProperty("Set", typeof(bool)); 
      if (setPropInfo != null) 
      { 
       var isSet = (bool)setPropInfo.GetValue(propertyValue, null); 
       if (!isSet) 
       { 
        p.SetValue(currentObject, null, null); 
       } 
      } 
      else 
      { 
       RemoveUnsetObjects(propertyValue); 
      } 
     } 
    } 
}