Search code examples
c#xmlwcfsoapwcf-binding

WCF request without namespace alias


I have a WCF service that works with a test client generated with SvcUtil.exe. But my real client is another company that used different technology.

With the generated test client the XML looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <PostModel xmlns="http://tempuri.org/">
         <model xmlns:a="http://schemas.datacontract.org/2004/07/SomeName.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:Items>
               <a:Item>
                  <a:SomeElement1>SomeValue</a:SomeElement1>
                  <a:SomeElement2>SomeValue</a:SomeElement2>
               </a:Item>
               <a:Item>
                  <a:SomeElement1>SomeValue</a:SomeElement1>
                  <a:SomeElement2>SomeValue</a:SomeElement2>
               </a:Item>
            </a:Items>
            <a:MoreItems>
               <a:MoreItem>
                  <a:SomeElement3>binary</a:SomeElement3>
               </a:MoreItem>
            </a:MoreItems>
         </model>
      </PostModel>
   </s:Body>
</s:Envelope>

But the real client sends the xml without alias:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <SOAP-ENV:Body>
      <PostModel xmlns="http://tempuri.org/">
         <model xmlns="http://schemas.datacontract.org/2004/07/SomeName.Models">
            <Items>
               <Item>
                  <SomeElement1>SomeValue</SomeElement1>
                  <SomeElement2>SomeValue</SomeElement2>
               </Item>
               <Item>
                  <SomeElement1>SomeValue</SomeElement1>
                  <SomeElement2>SomeValue</SomeElement2>
               </Item>
            </Items>
            <MoreItems>
               <MoreItem>
                  <SomeElement3>binary</SomeElement3>
               </MoreItem>
            </MoreItems>
         </model>
      </PostModel>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The result is that the model that I receive in the endpoint is NULL. If I catch the request in fiddler and edit it, add nothing but the alias for the model namespace and add it to the child-elements it works.

Is there a solution for this problem, as far as I know the XML that the client sends is valid XML, aliases are not mandatory.


Solution

  • The difference between the test client XML and the real client XML lies in the namespace of the element model. From the test client:

      <PostModel xmlns="http://tempuri.org/">
         <model xmlns:a="http://schemas.datacontract.org/2004/07/SomeName.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    

    This defines an element with local name "model". It has no namespace prefix so exists in the default namespace. However, it does not define a default namespace for itself -- instead it defines namespaces with prefixes "a" and "i". Thus it belongs in whatever default namespace its parent hierarchy defines, in this case "http://tempuri.org/" from its immediate parent.

    In the real client's XML, the model element again has no prefix but does have its own default namespace declaration:

      <PostModel xmlns="http://tempuri.org/">
         <model xmlns="http://schemas.datacontract.org/2004/07/SomeName.Models">
    

    Thus model falls into the namespace "http://schemas.datacontract.org/2004/07/SomeName.Models" rather than the parent's default namespace.

    All the child elements of model are in the same namespace in both XML versions. It's only the model element itself which is inconsistent.

    This inconsistency would explain the null model in the endpoint.