2012-03-30 29 views
10

tôi có một lớp nhưbool serialise? lỗi phản ánh loại

[Serializable] 
    public class MyClass 
    { 
     [XmlAttribute] 
     public bool myBool { get; set; } 
    } 

Nhưng điều này serializes giá trị của bool false khi thuộc tính là không có mặt trong xml. Khi thuộc tính không nằm trong xml, tôi muốn thuộc tính rỗng.

Vì vậy, tôi đã cố gắng này

[Serializable] 
public class MyClass 
{ 
    [XmlAttribute] 
    public bool? myBool { get; set; } 
} 

Nhưng sau đó các lỗi serializer

Type t = Type.GetType("Assembly.NameSpace.MyClass"); 
       XmlSerializer mySerializer = new XmlSerializer(t); //error "There was an error reflecting type" 

Xin vui lòng cho tôi một ví dụ về tôi có thể làm điều này. Tôi biết có một số câu hỏi liên quan đến SO nhưng không có gì cho thấy làm thế nào để vượt qua các lỗi phản ánh với một bool nullable. Cảm ơn.

Trả lời

9

Bạn cần phải sử dụng mô hình trường "* rõ" để kiểm soát này (xem "Kiểm soát XML đã tạo" trên MSDN):

[Serializable] 
public class MyClass 
{ 
    [XmlAttribute] 
    public bool myBool { get; set; } 

    [XmlIgnore] 
    public bool myBoolSpecified; 
} 

Logic lúc này là:

  • Nếu !myBoolSpecified, sau đó myBool là logic null
  • Else sử dụng true hoặc false của myBool
+0

@Aliostad: Tôi đánh giá cao giá trị của cách tiếp cận của bạn, nhưng nếu cấu trúc XML không mở để sửa đổi nó sẽ không hoạt động trong khi điều này sẽ xảy ra. – Jon

+0

điều này có vẻ tuyệt vời nhưng dường như không hoạt động. Tên '{} được chỉ định' có phải là một tên ma thuật không? Tôi có cần một số logic trong getter? – Jules

+0

@Jules: Vâng, đó là một cái tên kỳ diệu. Tìm kiếm "Mẫu được tạo dưới dạng propertyNameSpecified" trên trang được liên kết. Nếu nó không hoạt động, vui lòng hiển thị mã hiện tại của bạn. – Jon

1

Vấn đề là loại không thể xác định được xác định là phần tử (mặc định) và không phải Thuộc tính.

Lý do là khi giá trị rỗng, nó có thể được biểu diễn là <mybool xs:nil="true"/> vì vậy không thể được biểu diễn dưới dạng thuộc tính.

Hãy nhìn vào đoạn mã này:

[Serializable] 
public class MyClass 
{ 
    // removed the attribute!!! 
    public bool? myBool { get; set; } 
} 

Và:

XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
var stream = new MemoryStream(); 
serializer.Serialize(stream, new MyClass(){myBool = null}); 
Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray())); 

Output:

<?xml version="1.0"?> 
<MyClass xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.o 
rg/2001/XMLSchema-instance"> 
    <myBool xsi:nil="true" /> <!-- NOTE HERE !!! --> 
</MyClass> 
+0

Cảm ơn, nhưng đây là thuộc tính trong xml tôi nhận được vì vậy tôi không thể kiểm soát đó.Có cách nào để có một thuộc tính bool nullable? – Jules

+0

@Jules Câu trả lời của Jon là chính xác. – Aliostad

2

Có một cái nhìn tại this để biết thông tin liên quan đến xử lý các trường nullable và thuộc tính XML. Có một số question tương tự ở đây. Về cơ bản serializer không thể xử lý một trường thuộc tính XML được định nghĩa là nullable, nhưng có một work-around.

I.e 2 thuộc tính, một thuộc tính có chứa giá trị rỗng (không phải XML được lưu trữ) và thuộc tính khác được sử dụng trong đọc/ghi (thuộc tính XML được lưu trữ dưới dạng chuỗi). Có lẽ đây có thể là những gì bạn cần?

private bool? _myBool; 
[XmlIgnore] 
public bool? MyBool 
{ 
    get 
    { 
     return _myBool; 
    } 
    set 
    { 
     _myBool = value; 
    } 
} 

[XmlAttribute("MyBool")] 
public string MyBoolstring 
{ 
    get 
    { 
     return MyBool.HasValue 
     ? XmlConvert.ToString(MyBool.Value) 
     : string.Empty; 
    } 
    set 
    { 
     MyBool = 
     !string.IsNullOrEmpty(value) 
     ? XmlConvert.ToBoolean(value) 
     : (bool?)null; 
    } 
} 
2

Bạn có thể sử dụng XmlElementAttribute.IsNullable:

[Serializable] 
public class MyClass 
{ 
    [XmlElement(IsNullable = true)] 
    public bool? myBool { get; set; } 
} 
+0

Điều đó chỉ có thể thực hiện được khi bạn có thể chọn thay thế hàng loạt làm phần tử thay vì thuộc tính –

Các vấn đề liên quan