I'm developing a BizTalk application to query a number of web services that have been written and maintained by a third party, and I'm having some trouble getting the namespaces right on the Schemas.
Basically, I can't consume the wsdl to automatically generate the schemas because the namespaces and element names are all wrong within the generated schemas (due lazy C# wsdl generation), so I'm having to write them from scratch. This would be fine, but the Web Service endpoints are requiring that the elements within the schema all be qualified with specific namespaces, and none of them match the namespace of the overall schema.
I have figured out how to import other namespaces/schemas into my schema, but I can't figure out how to change the namespace of the elements to anything but the default. Does anyone know how to do this?
For example, the Schema root has to have a namespace of "http:/tempuri.org/"
, but one of the elements requires the namespace "http://schemas.datacontract.org/2004/07/ReadService.DTO.Inbound.Supplier"
, but within BizTalk, I can't edit the namespace of that element to change it.
The body of one of the requests looks like this:
<tem:GetSupplierIdWithExternalId>
<tem:request>
<com:Header>
<com1:Username></com1:Username>
<com1:Locale></com1:Locale>
</com:Header>
<read:ExternalSupplierId></read:ExternalSupplierId>
</tem:request>
</tem:GetSupplierIdWithExternalId>
"tem" in this case is http://tempuri.org/". "com", "com1" and "read" are all different namespaces, which, as Gruff has pointed out, are all default namespaces for WCF projects.
Generating from WSDL in Biztalk creates 2 issues:
The default namespace applied to the root note is not tempuri.org (as it recognises this as a default), it's the standard Biztalk http://..Folder.SchemaName namespace. Changing this to tempuri.org causes a cascade of errors that have to be fixed, and it doesn't resolve the more major issue which is:
Because of the way the WCF functions the WSDL has been generated from are written, the major element names (GetSupplierIdWithExternalId
above) are all named incorrectly - in most cases, something like "GetSupplierIdWithExternalIdRequest", because that's the name of the function that schema is generate from. Again it's due to lazy programming on the endpoints, because the name of the element isn't being properly defined, it's just assumed by the generation process.
If I try and create a single flat file schema, I can only define a single namespace for the whole file, and if I set that to tempuri.org I get:
<ns0:GetSupplierWithExternalId xmlns:ns0="http://tempuri.org/">
<Header>
<Username>Username_0</Username>
<Locale>Locale_0</Locale>
</Header>
<ExternalSupplierId>ExternalSupplierId_0</ExternalSupplierId>
</ns0:GetSupplierWithExternalId>
...which fails the a SOAP request because the namespaces on the internal elements aren't correct.
Thanks in advance!
You will need to define the element with the namespace of "http://schemas.datacontract.org/2004/07/ReadService.DTO.Inbound.Supplier" in its own schema file, and import it into the schema root and compose the root that way. The element will keep the namespace it was defined as.
Looking at the namespace "http://schemas.datacontract.org/2004/07/ReadService.DTO.Inbound.Supplier", it seems it is the default namespace that WCF gives the data contract because it was not explicitly defined. (The CLR namespace of the class is ReadService.DTO.Inbound.Supplier) When the DataContractSerializer serializes the message when sending the request, it will serialize it with that namespace. You should not try and change it in the BizTalk schema, otherwise there will be a schema mismatch.
UPDATE: In your update you mention 2 issues when generating the schema from the WSDL.
GetSupplierIdWithExternalIdRequest
is incorrect? If you search in the WSDL for that term, can you find it?
The operation's request and response wrappers typically get suffixed with -Request and -Response, so this might be perfectly correct.