Solving “XmlSchemaException: The global element '<elementName>' has already been declare

Posted by ChrisD on Geeks with Blogs See other posts from Geeks with Blogs or by ChrisD
Published on Wed, 14 Apr 2010 15:01:53 GMT Indexed on 2010/04/14 15:13 UTC
Read the original article Hit count: 233

Filed under:

I recently encountered this error when I attempted to consume a new hosted WCF service.  The service used the Request/Response model and had been properly decorated.  The response and request objects were marked as DataContracts and had a specified namespace.   My WCF service interface was marked as a ServiceContract and shared the namespace attribute value.   Everything should have been fine, right?

[ServiceContract(Namespace = "http://schemas.myclient.com/09/12")]
   public interface IProductActivationService
   {
       [OperationContract]
       ActivateSoftwareResponse ActivateSoftware(ActivateSoftwareRequest request);
   }

well, not exactly.  Apparently the WSDL generator was having an issue:

System.Xml.Schema.XmlSchemaException: The global element 'http://schemas.myclient.com/09/12:ActivateSoftwareResponse' has already been declared.

After digging I’ve found the problem; the WSDL generator has some reserved suffixes for its entities, including Response, Request, Solicit (see http://msdn.microsoft.com/en-us/library/ms731045.aspx).  The error message is actually the result of a naming conflict.  The WSDL generator uses the namespace of the service to build its reserved types.  The service contract and data contract share a namespace, which coupled with the response/request name suffixes I was using in my class names, resulted in the SchemaException.

The Fix:

Two options:

  1. Rename my data contract entities to use a non-reserved keyword suffix (i.e.  change ActivateSoftwareResponse to ActivateSoftwareResp). or;
  2. Change the namespace of the data contracts to differ from the service contract namespace.

I chose option 2 and changed all my data contracts to use a “http://schemas.myclient.com/09/12/datanamespace value. This avoided a name collision and I was able to produce my WSDL and consume my service.

© Geeks with Blogs or respective owner