Solving “XmlSchemaException: The global element '<elementName>' has already been declare
- by ChrisD
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:
Rename my data contract entities to use a non-reserved keyword suffix (i.e. change ActivateSoftwareResponse to ActivateSoftwareResp). or;
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/data” namespace value. This avoided a name collision and I was able to produce my WSDL and consume my service.