2012-03-30 68 views
10

我有像serialise bool?誤差反映型

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

類但當屬性不存在在XML這個串行化布爾的值設置爲false。 當該屬性不在xml中我希望該屬性爲null。

所以我想這

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

但隨後串行錯誤

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

請給我一個例子,我可以做到這一點。我知道這裏有一些相關的問題,但沒有任何內容顯示如何用可空布爾值來克服反射錯誤。謝謝。

回答

9

你需要使用 「*指定的」 場模式來控制這(請參閱MSDN上的「控制生成的XML」):

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

    [XmlIgnore] 
    public bool myBoolSpecified; 
} 

邏輯現在變爲:

  • 如果!myBoolSpecified,則myBool在邏輯上是null
  • 否則使用的myBool
+0

@Aliostad:我很欣賞你的方法的優點,但是如果XML結構不打開修改,它將不會工作。 – Jon 2012-03-30 12:18:42

+0

這看起來不錯,但似乎沒有工作。 「{}指定」是一個神奇的名字嗎?我需要吸氣劑中的一些邏輯嗎? – Jules 2012-03-30 12:22:51

+0

@Jules:是的,這是一個神奇的名字。在鏈接頁面上搜索「模式以propertyNameSpecified的形式創建」。如果它不起作用,請顯示您當前的代碼。 – Jon 2012-03-30 12:24:13

1

問題是,一個可空類型必須被定義爲一個元素(這是默認值),而不是屬性。

原因是當值爲空時,它可以表示爲<mybool xs:nil="true"/>,因爲不能表示爲屬性

看一看這個片段:

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

和:

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

輸出:

<?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

謝謝,但這是我收到,所以我無法控制的XML屬性。有什麼辦法可以有一個可空的布爾屬性? – Jules 2012-03-30 12:21:45

+0

@Jules Jon的回答是正確的。 – Aliostad 2012-03-30 12:33:44

2

truefalse看一看this信息有關處理可空字段和XML屬性。這裏也有類似的question。基本上,序列化程序無法處理定義爲空的XML屬性字段,但有一個解決方法。

I.e 2屬性,一個包含可空(不是XML存儲),另一個用於讀/寫(XML屬性存儲爲字符串)。也許這可能是你需要的?

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

您可以使用XmlElementAttribute.IsNullable

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

只有當您可以選擇序列化爲元素而不是屬性時,這纔可行 – 2015-05-14 15:02:42