Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dotnet-svcutil cannot handle recursively nested XSD structures #5404

Open
schneoka opened this issue Jan 15, 2024 · 9 comments
Open

dotnet-svcutil cannot handle recursively nested XSD structures #5404

schneoka opened this issue Jan 15, 2024 · 9 comments
Assignees
Labels

Comments

@schneoka
Copy link

schneoka commented Jan 15, 2024

Here is an excerpt from our WSDL definition. The structure oel_CmisExtensionTypeList is recursively nested:

<xsd:complexType name="oel_CmisExtensionTypeList">
 <xsd:sequence>
  <xsd:element name="item" minOccurs="0" maxOccurs="unbounded" nillable="true" type="s0:oel_CmisExtensionType"/>
 </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="oel_CmisExtensionType">
 <xsd:sequence>
   <xsd:element name="key" minOccurs="0" maxOccurs="1" type="xsd:string"> </xsd:element>
   <xsd:element name="value" minOccurs="0" maxOccurs="1" type="xsd:string"> </xsd:element>
   <xsd:element name="any" minOccurs="0" maxOccurs="1" type="s0:oel_CmisExtensionTypeList"> </xsd:element>
 </xsd:sequence>
</xsd:complexType>

<xsd:element name="ObjectService__performTaskActionRequest">
 <xsd:complexType>
  <xsd:sequence>
   <xsd:element name="username" minOccurs="1" maxOccurs="1" type="xsd:string"> </xsd:element>
   <xsd:element name="extension" minOccurs="0" maxOccurs="1" type="s0:oel_CmisExtensionTypeList"> </xsd:element>
  </xsd:sequence>
 </xsd:complexType>
</xsd:element>

To generate the WCF class this command was used:
dotnet-svcutil http://localhost:17089/wsdl --namespace "*, COI.SOAPConnector" --internal --sync --reference "c:\Program Files\dotnet\sdk\8.0.100\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Collections.dll" --noStdLib --outputFile BflowWSDL.cs --targetFramework "net8.0"

The generated class (I also tried dotnet-svcutil 2.1.0, it does not work either) looks like this:

  [System.Diagnostics.DebuggerStepThroughAttribute()]
   [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.2.0-preview1.23462.5")]
   [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
   [System.ServiceModel.MessageContractAttribute(WrapperName="ObjectService__performTaskActionRequest", WrapperNamespace="http://www.coi.de/bflowsoap", IsWrapped=true)]
   internal partial class ObjectService__performTaskActionRequest
   {
       [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.coi.de/bflowsoap", Order=0)]
       public string username;
       
       [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.coi.de/bflowsoap", Order=3)]
       [System.Xml.Serialization.XmlArrayItemAttribute("item")]
       public COI.SOAPConnector.COI.SOAPConnector.oel_CmisExtensionType[] extension;

The definition of extension contains two errors: Firstly, the namespace COI.SOAPConnector appears twice:
COI.SOAPConnector.COI.SOAPConnector.oel_CmisExtensionType[]
and secondly, the XSD definition contains a reference to oel_CmisExtensionTypeList, not to oel_CmisExtensionType

The svcutil used with .NET6 has generated the correct code here.
Even if the duplicate namespace is corrected manually, the transfer of values in extension.any no longer works.

@imcarolwang
Copy link
Contributor

Update:

  1. the double namespace issue doesn't repro on my side
  2. svcutil.exe behaves the same as dotnet-svcuitl.exe
  3. As reproduced base on the given information, oel_CmisExtensionTypeList type contains only one property, so the tool extracted that single member type (oel_CmisExtensionType[]) to the container type oel_CmisExtensionType, it doesn't seem to affect service op functionality if invoke by passing the required operation parameter. If type oel_CmisExtensionTypeList contains more than 1 property, type oel_CmisExtensionTypeList will be generated separately and be referenced as defined by the container type.

@imcarolwang
Copy link
Contributor

@schneoka , since I was unable to reproduce the first "double namespace" problem, the example serivce/wsdl I created to reproduce the issue may be missing some key information compared to yours. Therefore, the conclusion mentioned in my previous comments for the second issue may not apply to you. Can you provide a fully constructed simplified wsdl file that reproduces the issue?

@schneoka
Copy link
Author

schneoka commented Mar 8, 2024

@imcarolwang, i used this command to create the file:
dotnet-svcutil http://localhost:17089/wsdl --namespace "*, COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector" --internal --sync --reference "c:\Program Files\dotnet\sdk\8.0.100\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Collections.dll" --noStdLib --outputDir .\CmisClient\Binding\SOAPConnector --outputFile BflowWSDL.cs --targetFramework "net8.0"

  1. For example, in the created file, line 5414:

public COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.oel_CmisExtensionType[] extension;

  1. Example with svcutil:
internal partial class ObjectService__performTaskActionRequest
{
 ...
 [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.coi.de/bflowsoap", Order=3)]
  public COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.oel_CmisExtensionTypeList extension;
   ..     
  public ObjectService__performTaskActionRequest(string username, string actionId, COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.oel_CmisPropertiesType properties, COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.oel_CmisExtensionTypeList extension)

Example with dotnet-svcutil:

internal partial class ObjectService__performTaskActionRequest
{
 ...
 [System.Xml.Serialization.XmlArrayItemAttribute("item")]
 public COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.oel_CmisExtensionType[] extension;
 ... 
 public ObjectService__performTaskActionRequest(string username, string actionId, COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.oel_CmisPropertiesType properties, COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.COI.BusinessFlow.API.CmisClient.Binding.SOAPConnector.oel_CmisExtensionType[] extension)

It was a lot of work to change the access to member extension from list to array type, but it still doesn't work. The extension parameter provides no data.

The WSDL WSDL.xml
This is the created file BflowWSDL.cs

@imcarolwang
Copy link
Contributor

@schneoka thank you for the information! It's very helpful, and I'm able to reproduce both of the issues described.

I found out that it was "xsd:integer" that was causing the problem, if update the given WSDL file by replacing the two occurrences of "xsd:integer" with "xsd:int", dotnet-svcutil will be able to generate the code as expected.

I'm wondering how you defined your service that its WSDL would contain "xsd:integer". Can you share the corresponding service contract definition? Thanks!

@schneoka
Copy link
Author

@imcarolwang Isn't that the definition in https://www.w3.org/2001/XMLSchema?

<xs:simpleType name="integer" id="integer">
<xs:annotation>
<xs:documentation source="http://www.w3.org/TR/xmlschema-2/#integer"/>
</xs:annotation>
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="0" fixed="true" id="integer.fractionDigits"/>
<xs:pattern value="[\-+]?[0-9]+"/>
</xs:restriction>
</xs:simpleType>

@imcarolwang
Copy link
Contributor

Hi @schneoka, I have a proposed fix to address this issue and I tried to run the private "fixed" build against the WSDL.xml you provided, here is the cs file that was generated: BflowWSDL2.txt, would you mind try it out in your project and see if it works?

@schneoka
Copy link
Author

@imcarolwang The new cs file works in our project, thank you very much.

@schneoka
Copy link
Author

schneoka commented Jul 1, 2024

Hi @imcarolwang, we have a change in our WSDL. Do you know when a new release will be available that contains the fix.
Or is there a workaround for the problem.

@mconnew
Copy link
Member

mconnew commented Jul 29, 2024

@schneoka, you can build and pack the product locally. Clone the repo, then run:

build -restore
build -build
build -pack

On high core count machines the build step sometimes fails due to an issue with parallel builds, if that happens, run it again. This will get you a local build of the nuget package which should unblock you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants