WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

After creating simple WCF service I've got strange errors (see below).
 
The issue was in the names of the response messages.
I used the simple custom rule to name request and response messages (.NET DataContract classes):
<OperationName>Request and <OperationName>Response
For instance I created GetTokenResponse class for the response message of the GetToken operation.
 
And this is the wrong rule!
Why? Because the WCF creates these names for the WSDL metadata files:
 
For instance I've got:
...
<wsdl:message name="ITokenStore_GetToken_OutputMessage">
  <wsdl:part name="parameters" element="tns:GetTokenResponse" /> ...
 
....<wsdl:operation name="GetToken">
  <wsdl:input wsaw:Action=http://MyServices/TokenStore/2008-05-29/ITokenStore/GetToken message="tns:ITokenStore_GetToken_InputMessage" />
  <wsdl:output wsaw:Action=http://MyServices/TokenStore/2008-05-29/ITokenStore/GetTokenResponse message="tns:ITokenStore_GetToken_OutputMessage" />
 
 
When I changed the name to the GetToken_Response the errors disappeared.
It is not an error in the WCF it is just undocumented feature.
The problem is the error text gives us unhelpful and ambiguous information.
 
See the article in MSDN: http://msdn.microsoft.com/en-us/library/ms731045.aspx
Not a clue about these rules.
 
Conclusion:
Don't use the messages names with suffixes Response, Solicit, Request.
Don't use the name convention for the request and response messages (.NET classes) like <OperationName>Request and <OperationName>Response !
 
ADDITION [2009-07-26]: This behavior is because of the WSDL standard.
"

2.4.5 Names of Elements within an Operation

The name attribute of the input and output elements provides a unique name among all input and output elements within the enclosing port type.

In order to avoid having to name each input and output element within an operation, WSDL provides some default values based on the operation name. If the name attribute is not specified on a one-way or notification message, it defaults to the name of the operation. If the name attribute is not specified on the input or output messages of a request-response or solicit-response operation, the name defaults to the name of the operation with "Request"/"Solicit" or "Response" appended, respectively.

"

Error in SoapUI
, when we've tried to get the metadata:
... ERROR:javax.wsdl.WSDLException: WSDLException (at /HTML): faultCode=INVALID_WSDL: Expected element '{http://schemas.xmlsoap.org/wsdl/}definitions'.
 

Error in IE: by address the <ServiceAddressURL>

The service encountered an error.

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
 contract: http://MyServices/TokenStore/2008-05-29:ITokenStore ----> System.Xml.Schema.XmlSchemaException: The global element 'http://MyServices/TokenStore/2008-05-29:GetTokenResponse' has already been declared.
   at System.Xml.Schema.XmlSchemaSet.InternalValidationCallback(Object sender, ValidationEventArgs e)
   at System.Xml.Schema.BaseProcessor.AddToTable(XmlSchemaObjectTable table, XmlQualifiedName qname, XmlSchemaObject item)
   at System.Xml.Schema.Preprocessor.Preprocess(XmlSchema schema, String targetNamespace, ArrayList imports)
   at System.Xml.Schema.Preprocessor.Execute(XmlSchema schema, String targetNamespace, Boolean loadExternals)
   at System.Xml.Schema.XmlSchemaSet.PreprocessSchema(XmlSchema& schema, String targetNamespace)
   at System.Xml.Schema.XmlSchemaSet.Reprocess(XmlSchema schema)
   at System.ServiceModel.Description.MessageContractExporter.Compile()
   at System.ServiceModel.Description.DataContractSerializerMessageContractExporter.Compile()
   at System.ServiceModel.Description.MessageContractExporter.ExportMessage(Int32 messageIndex, Object state)
   at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract()
   at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
   --- End of inner ExceptionDetail stack trace ---
   at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
   at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleDocumentationRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
   at SyncInvokeGet(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

Error in IE: by address the <ServiceAddressURL>?wsdl

The service encountered an error.

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
 contract: http://MyServices/TokenStore/2008-05-29:ITokenStore ----> System.Xml.Schema.XmlSchemaException: The global element 'http://MyServices/TokenStore/2008-05-29:GetTokenResponse' has already been declared.
   at System.Xml.Schema.XmlSchemaSet.InternalValidationCallback(Object sender, ValidationEventArgs e)
   at System.Xml.Schema.BaseProcessor.AddToTable(XmlSchemaObjectTable table, XmlQualifiedName qname, XmlSchemaObject item)
   at System.Xml.Schema.Preprocessor.Preprocess(XmlSchema schema, String targetNamespace, ArrayList imports)
   at System.Xml.Schema.Preprocessor.Execute(XmlSchema schema, String targetNamespace, Boolean loadExternals)
   at System.Xml.Schema.XmlSchemaSet.PreprocessSchema(XmlSchema& schema, String targetNamespace)
   at System.Xml.Schema.XmlSchemaSet.Reprocess(XmlSchema schema)
   at System.ServiceModel.Description.MessageContractExporter.Compile()
   at System.ServiceModel.Description.DataContractSerializerMessageContractExporter.Compile()
   at System.ServiceModel.Description.MessageContractExporter.ExportMessage(Int32 messageIndex, Object state)
   at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract()
   at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
   --- End of inner ExceptionDetail stack trace ---
   at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
   at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleMetadataRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
   at SyncInvokeGet(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

 


 

Print | posted on Monday, June 2, 2008 3:43 PM

Feedback

# re: WCF: Data contract names: don't use names with "Response" suffix!

left by Luke Venediger at 7/26/2009 8:11 AM Gravatar
You wont believe how long this took me to find. I renamed FooResponse to FooResp and I could then see my WSDL. Thanks for posting this!!

# re: WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

left by Chris at 9/22/2009 1:16 PM Gravatar
Life saver! Thanks very much!

# re: WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

left by Victor Kornov at 4/12/2010 3:23 PM Gravatar
You have not specified namespace for your data contracts, so you get this name clash. Use different namespaces for webservice and request/response types and you are set. E.g:

[ServiceContract(Namespace="http://cglessner.de/wcf/")] for the service contract (and ServiceBehavior)
and
[DataContract(Namespace="http://cglessner.de/wcf/entities/")] for data contracts

# re: WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

left by Heating Boilers at 4/24/2010 3:28 AM Gravatar
Thanks man! I've been encountering the same problems. Been stuck for a couple of days now!

# re: WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

left by Leonid Ganeline at 4/24/2010 2:09 PM Gravatar
To Victor Kornov: Namespaces for all Contracts are specified. In BizTalk world there is no way to live without namaspaces. :) It does not depends of the namespaces.

# re: WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

left by Benjy at 5/29/2010 6:55 AM Gravatar
Leonid,
According to another article, it seems that namespaces are indeed the problem. They need to be unique.
http://geekswithblogs.net/SoftwareDoneRight/archive/2010/04/14/solving-ldquoxmlschemaexception-the-global-element-ltelementnamegt-has-already-been-declared.rdquo.aspx

cheers
benjy

# re: WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

left by Leonid Ganeline at 5/29/2010 11:23 AM Gravatar
To benjy:
Thank you for participating!
As you can see above in the text of exceptions the namespaces are all defined. We should never work without xml namespaces at all!

# re: WCF: Data contract names: don't use names with "Response" and "Request" suffixes!

left by Ostati at 11/15/2013 11:41 AM Gravatar
Why not just adding different namespace to ServiceContract and DataContract like:

[ServiceContract(Namespace = "http://www.company.com/product/v1/service")]

[DataContract(Namespace = "http://www.company.com/product/v1/entity")]

It would the needful without forcing you to change class names. ;)
Post A Comment
Title:
Name:
Email:
Comment:
Verification: