A common bug in .Net 2.0 may cause the following exception when compiling a proxy:
Microsoft did not fix this bug for Wcf so it also gives a similar exception:
Is this error limited to DateTime?
Not at all. You may also get any of these:
Or with your custom types.
What does this error mean?
For you – nothing. This is a .Net/Wcf bug.
When does this happen?
When the following conditions apply:
1. The wsdl (schema) declares a complex type C.
2. C contains a single element with maxOccures>1 (an array).
3. The wsdl declares an element e of type X with maxOccures>1.
Example:
What is the .Net bug?
The proxy will generate something like this:
This line declares an array of type DateTime[][], but also specifies that each item of the array is of type DateTime. Which is clearly an error since the array items are of type DateTime[] (this is a multidimentional array).
This is the reason why the proxy does not compile.
Workaround #1
Manually edit the proxy and change “typeof(DateTime)” to “typeof(DateTime[])”. This workaround is also described here.
Limitation: This change will be overridden every time you regenerate the proxy (update web/service reference).
Workaround #2
We mentioned that the bug only happens when the type C has one child element. Why not add it some friend so it would not be alone? This means we need to manually edit the wsdl. For example:
Now you may say this changes the schema and makes our proxy not valid. But note we have added an optional field only (minOccurs=0) so as long as we do not assign any value to it in our client this change is non-breaking.
Now let’s see how the proxy generated from the updated wsdl looks like:
Now .Net does not generate the multidimensional array in one shot, but declares the mediating type C. The proxy will in turn use this type as an array:
which gives us the multidimensional effect.
This compiles immediately so we’re free to go.
What's next? get this blog rss updates or register for mail updates!
10 comments:
Yaron, I appreciate you very much for you post!
It helps me to fix the issue and saves great deal of time!
This bug bit me as well. It was a shame, since I was starting with XML, and after I made my class with xsd.exe, it would not accept the XML used to make it.
I actually stumbled across a nicer solution to this problem. I found that by moving the cardinality rules onto the sequence element rather than the child, .NET code generation does not collapse the sequences.
Rather than
< xsd:complexType name="C">
< xsd:sequence>
< xsd:element maxOccurs="unbounded" minOccurs="0" name="someDate" type="xsd:date"/>
< /xsd:sequence>
< /xsd:complexType>
Try
< xsd:complexType name="C">
< xsd:sequence maxOccurs="unbounded" minOccurs="0">
< xsd:element name="someDate" type="xsd:date"/>
< /xsd:sequence>
< /xsd:complexType>
James
@James - Thanks for the tip!
Is this problem solved in the actual .NET 4.5?
not really sure, but if you still get the exception the workaround should be valid
I tried this with the ImageSet[][] problem and set the typeof(ImageSet) to typeof(ImageSet[]) but I got a 400: bad Request exception. I also tried changing ImageSet[][] to ImageSet[] and got the same error.
I tried the first option with ImageSet[][] by changing the Serialization with typeof(ImageSet) to typeof(ImageSet[]) and got a 400: Bad Request exception. I also tried changing ImageSet[][] to ImageSet[] and got the same error.
Hi Robert
If you were able to send out a soap request you should compare it to the expected soap (e.g. by a working clinet or the service owner sample). Use Fiddler to get your message
solved the problem for us, thanks!
Post a Comment