在XSD中引入targetNamespace后,客户端不再从Web Service获取数据

时间:2010-03-10 18:44:13

标签: web-services xsd xml-namespaces

很抱歉,如果这篇文章中有太多信息 - 在我遇到实际问题之前有一堆故事。我以为我会包含一些可能相关的内容,因为我不太了解什么是错误的。

我有一个有效的网络服务和客户端(都是用C#编写的VS 2008),用于将产品数据传递到电子商务网站。 XSD的开头是这样的:

<xs:schema id="Ecommerce"
    elementFormDefault="qualified"
    xmlns:mstns="http://tempuri.org/Ecommerce.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="eur">
  <xs:complexType>
   <xs:sequence>
    <xs:element ref="sec" minOccurs="1" maxOccurs="1"/>
   </xs:sequence>

以下是从客户端发送到服务的示例文档:

<eur xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" class="ECommerce_WebService" type="product" method="GetLastDateSent" chunk_no="1" total_chunks="1" date_stamp="2010-03-10T17:16:34.523" version="1.1">
  <sec guid="BFBACB3C-4C17-4786-ACCF-96BFDBF32DA5" company_name="Company" version="1.1">
    <data />
  </sec>
</eur>

然后,我必须给服务一个targetNamespace。实际上我不知道我是否“有”设置它,但我添加了(到同一个VS项目)一些代码作为一个完全不相关的服务(也没有命名空间)的客户端,并且该项目不会构建,直到我给我的服务命名空间。

现在XSD就像这样开始:

<xs:schema id="Ecommerce"
    elementFormDefault="qualified"
    xmlns:mstns="http://tempuri.org/Ecommerce.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.company.com/ecommerce"
    xmlns:ecom="http://www. company.com/ecommerce">
 <xs:element name="eur">
  <xs:complexType>
   <xs:sequence>
    <xs:element ref="ecom:sec" minOccurs="1" maxOccurs="1" />
   </xs:sequence>

如上所示,我还更新了所有xs:element ref属性,为它们提供了“ecom”前缀。现在项目再次建立。

我发现客户端在此之后需要进行一些修改。客户端使用SQL存储过程来生成XML。然后将其反序列化为服务的“get_data”方法的正确类型的对象。该对象的类型曾经是“eur”,但在更新了对该服务的Web引用后,它变为“get_dataEur”。当然,XML中的父元素必须更改为“get_dataEur”才能被接受。然后奇怪的是我还必须将包含my命名空间的xmlns属性放在“sec”元素(父元素的直接子元素)而不是父元素上。这是现在从客户端发送到服务的示例文档:

<get_dataEur xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" class="ECommerce_WebService" type="product" method="GetLastDateSent" chunk_no="1" total_chunks="1" date_stamp="2010-03-10T18:23:20.653" version="1.1">
  <sec xmlns="http://www.company.com/ecommerce" guid="BFBACB3C-4C17-4786-ACCF-96BFDBF32DA5" company_name="Company" version="1.1">
    <data />
  </sec>
</get_dataEur>

如果在服务的get_data方法中,我然后序列化传入的对象,我看到这个(父元素是“eur”,xmlns属性在父元素上):

<eur xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.company.com/ecommerce" class="ECommerce_WebService" type="product" method="GetLastDateSent" chunk_no="1" total_chunks="1" date_stamp="2010-03-10T18:23:20.653" version="1.1">
  <sec guid="BFBACB3C-4C17-4786-ACCF-96BFDBF32DA5" company_name="Company" version="1.1">
    <data />
  </sec>
</eur>

然后服务准备回复以返回客户端。 XML看起来像这样(发送回的重要数据是last_sent元素中的date_stamp属性):

<eur xmlns="http://www.company.com/ecommerce" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" class="ECommerce_WebService" type="product" method="GetLastDateSent" chunk_no="1" total_chunks="1" date_stamp="2010-03-10T18:22:57.530" version="1.1">
  <sec version="1.1" xmlns="">
    <data>
      <last_sent date_stamp="2010-02-25T15:15:10.193" />
    </data>
  </sec>
</eur>

现在终于,这就是问题!!! 客户端看不到任何数据 - 它看到的只是父元素,里面没有任何内容。如果我在客户端代码中序列化回复对象,它看起来像这样:

<get_dataResponseEur xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" class="ECommerce_WebService" type="product" method="GetLastDateSent" chunk_no="1" total_chunks="1" date_stamp="2010-03-10T18:22:57.53" version="1.1" />

所以,我的问题是:

  1. 为什么我的客户看不到回复文件的内容?

  2. 我该如何解决?

  3. 为什么我必须将xmlns属性放在子元素而不是传出文档中的父元素上?

  4. 这里有一些可能相关的信息:

    客户端代码(pre-namespace)称为服务方法,如下所示:

    XmlSerializer serializer = new XmlSerializer(typeof(eur));
        XmlReader reader = xml.CreateReader();
        eur eur = (eur)serializer.Deserialize(reader);            
        service.Credentials = new NetworkCredential(login, pwd);
        service.Url = url;
        rc = service.get_data(ref eur);
    

    添加名称空间后,我不得不将其更改为:

    XmlSerializer serializer = new XmlSerializer(typeof(get_dataEur));
        XmlReader reader = xml.CreateReader();
        get_dataEur eur = (get_dataEur)serializer.Deserialize(reader);
        get_dataResponseEur eur1 = new get_dataResponseEur();
        service.Credentials = new NetworkCredential(login, pwd);
        service.Url = url;
        rc = service.get_data(eur, out eur1);
    

1 个答案:

答案 0 :(得分:0)

  
    

添加名称空间后,我不得不将其更改为:

  

你似乎没有在这里添加任何命名空间......尝试将默认命名空间添加到XmlSerializer的构造函数中,如下所示:

XmlSerializer serializer = new XmlSerializer(typeof(get_dataEur), "http://www.company.com/ecommerce"
);
XmlReader reader = xml.CreateReader();
get_dataEur eur = (get_dataEur)serializer.Deserialize(reader);
get_dataResponseEur eur1 = new get_dataResponseEur();
service.Credentials = new NetworkCredential(login, pwd);
service.Url = url;
rc = service.get_data(eur, out eur1);

这有帮助??