To demonstrate the problem let’s take a look into generated Reference.cs:
public partial class getSalesItemsV3 {
// skipped
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=2)]
public WsdlDuplicateName.SalesItemService.hsSimpleDate start;
// skipped
}
public partial class setSalesItems {
// skipped
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=3)]
public System.DateTime start;
// skipped
}
Please note that these elements have the same name (start
) and the same namespace declared by the MessageBodyMember attribute (""
, empty namespace). This cause "The top XML element 'start' from namespace '' references distinct types" serializer exception.
If we have this option:
(b) the changes I can make to the generated proxies to make the
serializer happy
... we can set namespaces for elements start
, end
and return
(they all cause troubles) manually. I did it by myself and put the result here. You can paste it into your Reference.cs and serializer exception will gone.
But it seems that the root cause of your issue is that this service (http://services.hotschedules.com/api/services/SalesService?wsdl) is intended to be used through WebServices (and this problem is some kind of incompatibilities).
If you add reference to this server as a Web Reference (Add -> Service Reference... -> Advanced... -> Add Web Reference...) and write the same web method call, no problems with serialization will occur. Actually, in my case I received another kind of server exceptions in my test example, but it will solve your immediate serialization problem.
The mirror copy of your code, but using Web Service Reference (and not requires any changes in generated files) can be found here.
Hope this will help.
UPDATE: To found what is actually cause this problem we need to deep delve in XmlReflectionImporter
source code. First, our WSDL using XSD schemas to define namespaces: http://www.w3.org/2001/XMLSchema for xsd
and http://services.hotschedules.com/api/services/SalesService for tns
. XmlReflectionImporter
using NameTable
(this is a wrapper for Hashtable
) to store "accessors". Accessor is a pair of Namespace
and Name
.
Let's see source code that throws exception:
private Accessor ReconcileAccessor(Accessor accessor, NameTable accessors)
{
// initial check skipped
// look for accessor by name and namespace, add to accessors hash if not found and return
Accessor accessor1 = (Accessor) accessors[accessor.Name, accessor.Namespace];
if (accessor1 == null)
{
accessor.IsTopLevelInSchema = true;
accessors.Add(accessor.Name, accessor.Namespace, (object) accessor);
return accessor;
}
// accessor ("start" in our case) found!
// check if mappings is the same and return accessor. This is not our case, we have two accessors with the same name but different mappings (despite that this mappings is have the same type)!
if (accessor1.Mapping == accessor.Mapping)
return accessor1;
// next I skipped some reconciliations for MembersMapping and ArrayMapping. Please note that it performed by types, for example:
// if (accessor.Mapping is ArrayMapping) { /* some logic */}
// Our mapping is not MembersMapping or ArrayMapping and we finally got there:
throw new InvalidOperationException(Res.GetString("XmlCannotReconcileAccessor", (object) accessor.Name, (object) accessor.Namespace, (object) XmlReflectionImporter.GetMappingName((Mapping) accessor1.Mapping), (object) XmlReflectionImporter.GetMappingName((Mapping) accessor.Mapping)));
// Resource definition is: XmlCannotReconcileAccessor=The top XML element '{0}' from namespace '{1}' references distinct types {2} and {3}. Use XML attributes to specify another XML name or namespace for the element or types.
// using this resource template you can see that string representations of mappings are "WsdlDuplicateName.SalesItemService.hsSimpleDate" and "System.DateTime".
}
So, the main reconciliation logic is we can't have two accessors with the same name but different namespaces! There're may be some exceptions for MembersMapping
and ArrayMapping
types, but it is not our case.
I believe that this is some kind of a bug. The WSDL is correct and will pass validation, but due to this generic implementation of ReconcileAccessor
from XmlReflectionImporter
class we got an exception. Not sure if this is exact problem of XmlReflectionImporter
, or may be there's another problem on a higher abstract layer. And, source generated by "Web Reference" is not using XmlReflectionImporter
.
Another thing is worth to mention: generator puts a Namespace=""
value for MessageBodyMemberAttribute, what is effectively break the reconciliation process. So, I believe there's some inconsistency or incompatibility.