2012-06-03 187 views
2

我有喜歡XML反序列化給空WCF對象

<?xml version="1.0"?> 
<FullServiceAddressCorrectionDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <AuthenticationInfo xmlns="http://www.usps.com/postalone/services/UserAuthenticationSchema"> 
    <UserId xmlns="">FAPushService</UserId> 
    <UserPassword xmlns="">Password4Now</UserPassword> 
    </AuthenticationInfo> 
</FullServiceAddressCorrectionDelivery> 

一個XML字符串,以便與類節點圖,我有在WCF類結構像

[DataContract] 
[Serializable] 
public class FullServiceAddressCorrectionDelivery 
{ 
    [XmlElement("AuthenticationInfo", Namespace = "http://www.usps.com/postalone/services/UserAuthenticationSchema")] 
    [DataMember] 
    public AuthenticationInfo AuthenticationInfo { get; set; } 
} 

[DataContract] 
[Serializable] 
public class AuthenticationInfo 
{ 
    [DataMember] 
    [XmlElement("UserId", Namespace = "")] 
    public string UserId { get; set; } 

    [DataMember] 
    [XmlElement("UserPassword", Namespace = "")] 
    public string UserPassword { get; set; } 
} 

對於反序列化,我用xmlserializer去反序列化對象

XmlSerializer xs = new XmlSerializer(typeof(FullServiceAddressCorrectionDelivery)); 
var result = (FullServiceAddressCorrectionDelivery)xs.Deserialize(stream); 

這個方法返回了一個NULL FullServiceAddres sCorrectionDelivery對象.. 但是當我使用的DataContractSerializer ..像

DataContractSerializer xs = new DataContractSerializer(typeof(FullServiceAddressCorrectionDelivery)); 
var result = (FullServiceAddressCorrectionDelivery)xs.ReadObject(stream); 

然後下面的異常出來..

錯誤在第2行位置46期望來自名字空間元素 'FullServiceAddressCorrectionDelivery' 的「http:// schemas.datacontract.org/2004/07/WcfService1'..遇到名爲'FullServiceAddressCorrectionDelivery',名稱空間''的'Element'。

我堅持這個... 我以某種方式與RENE(StackOverFlow成員)的幫助成功反序列化,如果類在同一個項目..但是當我將它們轉換爲WCF Datacontracts ..我碰到問題.....請指導我在哪裏做錯了這裏...

+0

從哪裏得到XML?這是從您的服務返回? –

+0

nops ...它是用戶輸入爲一個字符串,我必須從這個XML字符串填充一個WCF datacontract對象 – Hassam

+0

請幫助..我真的需要做這件事情.... – Hassam

回答

1

根據你想要如何使用數據合約序列化器(DCS)的輸入,你可能會也可能不會這樣做。 DCS中的數據成員的名稱空間由它們所屬協定的名稱空間定義,除非它是根元素(在這種情況下,[DC]名稱空間也定義元素的名稱空間)。

您的根元素FullServiceAddressCorrectionDelivery在示例XML(空)中有一個名稱空間,其成員AuthenticationInfo具有另一個名稱空間(http://www.usps.com/postalone ...)。這意味着除非你真的改變了序列化器的創建方式,否則你將無法使用這種類型的DCS。

但是,XmlSerializer(XS)應該工作得很好 - 類型的成員可以有不同的名稱空間。正如你在下面的代碼中看到的那樣,我可以將你提供的XML逐字地發佈到一個操作,該操作將FullServiceAddressCorrectionDelivery作爲輸入,並且該對象被正確填充 - 您需要使用[XmlSerializerFormat ]屬性來獲得這種行爲。

public class Post_6fc3a1bd_b3ca_48da_b4d2_35271135ed8a 
{ 
    const string XML = @"<?xml version=""1.0""?> 
<FullServiceAddressCorrectionDelivery xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> 
    <AuthenticationInfo xmlns=""http://www.usps.com/postalone/services/UserAuthenticationSchema""> 
    <UserId xmlns="""">FAPushService</UserId> 
    <UserPassword xmlns="""">Password4Now</UserPassword> 
    </AuthenticationInfo> 
</FullServiceAddressCorrectionDelivery>"; 

    [XmlRoot(ElementName = "FullServiceAddressCorrectionDelivery", Namespace = "")] 
    public class FullServiceAddressCorrectionDelivery 
    { 
     [XmlElement("AuthenticationInfo", Namespace = "http://www.usps.com/postalone/services/UserAuthenticationSchema")] 
     [DataMember] 
     public AuthenticationInfo AuthenticationInfo { get; set; } 
    } 

    public class AuthenticationInfo 
    { 
     [XmlElement("UserId", Namespace = "")] 
     public string UserId { get; set; } 

     [XmlElement("UserPassword", Namespace = "")] 
     public string UserPassword { get; set; } 
    } 

    [ServiceContract(Namespace = "")] 
    public interface ITest 
    { 
     [XmlSerializerFormat] 
     [OperationContract] 
     FullServiceAddressCorrectionDelivery Echo(FullServiceAddressCorrectionDelivery input); 
    } 

    public class Service : ITest 
    { 
     public FullServiceAddressCorrectionDelivery Echo(FullServiceAddressCorrectionDelivery input) 
     { 
      return input; 
     } 
    } 

    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     WebClient c = new WebClient(); 
     c.Headers[HttpRequestHeader.ContentType] = "text/xml"; 
     Console.WriteLine(c.UploadString(baseAddress + "/Echo", XML)); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 

爲了完整起見,這是你將怎樣改變串行創建(通過根名稱和命名空間),才能反序列化您使用數據合同串行提供的XML。

public class Post_6fc3a1bd_b3ca_48da_b4d2_35271135ed8a_b 
{ 
    const string XML = @"<?xml version=""1.0""?> 
<FullServiceAddressCorrectionDelivery xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> 
    <AuthenticationInfo xmlns=""http://www.usps.com/postalone/services/UserAuthenticationSchema""> 
    <UserId xmlns="""">FAPushService</UserId> 
    <UserPassword xmlns="""">Password4Now</UserPassword> 
    </AuthenticationInfo> 
</FullServiceAddressCorrectionDelivery>"; 

    [DataContract(Name = "FullServiceAddressCorrectionDelivery", Namespace = "http://www.usps.com/postalone/services/UserAuthenticationSchema")] 
    public class FullServiceAddressCorrectionDelivery 
    { 
     [DataMember] 
     public AuthenticationInfo AuthenticationInfo { get; set; } 
    } 

    [DataContract(Name = "AuthenticationInfo", Namespace = "")] 
    public class AuthenticationInfo 
    { 
     [DataMember] 
     public string UserId { get; set; } 

     [DataMember] 
     public string UserPassword { get; set; } 
    } 

    static string Serialize(object obj, bool useDataContractSerializer) 
    { 
     MemoryStream ms = new MemoryStream(); 
     XmlWriterSettings ws = new XmlWriterSettings 
     { 
      Indent = true, 
      IndentChars = " ", 
      OmitXmlDeclaration = false, 
      Encoding = new UTF8Encoding(false) 
     }; 
     XmlWriter w = XmlWriter.Create(ms, ws); 
     if (useDataContractSerializer) 
     { 
      var dcs = new DataContractSerializer(obj.GetType(), "FullServiceAddressCorrectionDelivery", ""); 
      dcs.WriteObject(w, obj); 
     } 
     else 
     { 
      new XmlSerializer(obj.GetType()).Serialize(w, obj); 
     } 

     w.Flush(); 
     string result = Encoding.UTF8.GetString(ms.ToArray()); 
     Console.WriteLine(result); 

     w.Close(); 
     ms.Close(); 
     return result; 
    } 

    public static void Test() 
    { 
     Console.WriteLine("Serialization:"); 
     MemoryStream ms = new MemoryStream(); 
     XmlWriterSettings ws = new XmlWriterSettings 
     { 
      Indent = true, 
      IndentChars = " ", 
      OmitXmlDeclaration = false, 
      Encoding = new UTF8Encoding(false) 
     }; 
     XmlWriter w = XmlWriter.Create(ms, ws); 
     var dcs = new DataContractSerializer(typeof(FullServiceAddressCorrectionDelivery), "FullServiceAddressCorrectionDelivery", ""); 

     var obj = new FullServiceAddressCorrectionDelivery 
     { 
      AuthenticationInfo = new AuthenticationInfo 
      { 
       UserId = "FAPushService", 
       UserPassword = "Password4Now" 
      } 
     }; 

     dcs.WriteObject(w, obj); 

     w.Flush(); 
     string result = Encoding.UTF8.GetString(ms.ToArray()); 
     Console.WriteLine(result); 
     Console.WriteLine(); 

     Console.WriteLine("Deserialization:"); 
     ms = new MemoryStream(Encoding.UTF8.GetBytes(XML)); 

     var obj2 = (FullServiceAddressCorrectionDelivery)dcs.ReadObject(ms); 
     Console.WriteLine("{0} - {1}", obj2.AuthenticationInfo.UserId, obj2.AuthenticationInfo.UserPassword); 
    } 
} 
+0

謝謝你這麼多carlosfigueira !. 。您的解決方案有效。 – Hassam