1

抱歉,如果这篇文章中有太多信息 - 在我解决实际问题之前有很多故事。我想我会包括所有可能相关的内容,因为我不知道出了什么问题。

我有一个有效的 Web 服务和客户端(均使用 VS 2008 用 C# 编写)用于将产品数据传递到电子商务网站。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>

ETC

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

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

ETC

正如您在上面看到的,我还更新了所有 xs:element ref 属性,为它们赋予“ecom”前缀。现在项目再次构建。

我发现客户在此之后需要进行一些修改。客户端使用 SQL 存储过程来生成 XML。然后将其反序列化为服务“get_data”方法的正确类型的对象。该对象的类型曾经是“eur”,但在更新对服务的 Web 引用后,它变成了“get_dataEur”。果然,必须将 XML 中的父元素更改为“get_dataEur”才能被接受。然后奇怪的是,我还不得不将包含我的命名空间的 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 属性放在子元素上,而不是传出文档中的父元素上?

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

客户端代码(前命名空间)调用服务方法,如下所示:

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);
4

1 回答 1

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);

这有帮助吗??

于 2010-03-10T19:06:22.867 回答