2012-06-03 246 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