I have a problem with code generation using xsd.exe (the one provided with the .NET SDK) and also with Xsd2Code (http://xsd2code.codeplex.com/).
I have the following setup of XSD files:
Common.xsd
Summary.xsd
Detail.xsd
Common defines some types that are used in both Summary and Detail and are therefore both Summary and Detail include the line <xs:include schemaLocation="Common.xsd" />.
Now the problem with all XSD code generation tools I tried is that they only take a XSD file with a top level type (so Summary/Detail) and create classes in ONE namespace.
The problem with this is that if I use these tools I get 2 exact copies of every type in Common.xsd (Namespace.Summary.CommonType and Namespace.Detail.CommonType). When I want to use them in code I always have to convert between them (basically just copy all the values) with is quite a nuisance and leads to quite a lot of overhead and confusion.
Is there any XSD code generation tool that handles includes better (ie. puts included types into an own namespace and only generates them once)?
You should try to list all the XSD files in the command line, it should fix your problem for all but some scenarios that hopefully don't apply to your case.
Please take a look at this post, also on SO, it shows exactly what you need to do.
Xsd2Code handles this scenario, you just need to run multiple passes of the command for each xsd file, specifying the namespace..
xsd2code Common.xsd MyNamespace MyNamespace\Common.cs
xsd2code Summary.xsd MyNamespace MyNamespace\Summary.cs /eit+
xsd2code Detail.xsd MyNamespace MyNamespace\Detail.cs /eit+
Each xsd file will be generated into its own source code file (optionally in different namespaces). The /eit+ switch indicates that xsd2code wont generate the included schema types into that file.
The following method in Xsd2Code always returns true:
Xsd2Code.Library.Extensions.CodeExtension.ContainsTypeName(XmlSchema schema, CodeTypeDeclaration type)
This prevents the exclusion of included xml schema items.
Related
I am using <PropertyGroup><XsdCodeGenEnabled>true</XsdCodeGenEnabled></PropertyGroup> in my .csproj project file to generate C# classes for the XML schema defined in an .xsd file in the project.
I can see that this generates classes in a namespace called ContractTypes by default, and this works because a .targets file in the XsdCodeGen target is setting the value of the XsdCodeGenNamespaceMappings property as <XsdCodeGenNamespaceMappings>*, ContractTypes</XsdCodeGenNamespaceMappings> and I can set the property the same way but substitute a namespace I want for 'ContractTypes'
The problem I have is that I want to generate C# types from multiple .xsd files in separate namespaces. I am guessing that XsdCodeGenNamespaceMappings is intended to solve this problem, I can see that it is used to build a Dictionary which somehow looks up what output namespace to use. And I don't understand what (in the .xsd file) the input namespace is coming from. ('*' is a magic value.)
How does the XsdTypeImporterTask which does the work actually process the 'NamespaceMappings' parameter?
I've done some diving in the assembly and it looks to me like for XmlSerializer mode the only 'input namespace' value supported by XsdBuildTask is *. And the only way a namespace mapping dictionary with other values is ever used by the build task is if you're in the DataContractSerializer mode. I would be happy to hear I'm wrong however...
I am working on a project that consumes (external) services.
The vendor has provided a whole heap of XSDs (89 of them) and I want the convert them all into .Net (C#) classes / class library.
I am using the XSD utility on these but as there is a lot of cross-referencing and importing, they are failing with error messages saying type 'xxxxx' not declared
Now, based my my googling, this is quite simply overcome by compiling the complete reference "tree" but ....
I have 89 files to convert
It concatenates all the schema names together for the output .cs file name (and breaks due to being too long (> 260char))
I thought about creating a class library assembly, starting with the base level schemas (ones without imports) and then telling XSD to convert a schema but use any referenced types from this assembly... but I am not sure how or even if it is possible.
So, how can I best do this please... any advice is welcome..
And yes, 89 schemas are a lot and unfortunately, I have no control on this, I just have to suck it up and deal with it.
You can use /P[arameters]:file.xml option in xsd.exe to specify many parameters in separate file instead of pass them in command line.
Sample of this xml:
<xsd xmlns='http://microsoft.com/dotnet/tools/xsd/'>
<generateClasses language='CS' namespace='MyNamespace'>
<schema>FirstSchema.xsd</schema>
<schema>SecondSchema.xsd</schema>
<schema>ThirdSchema.xsd</schema>
</generateClasses>
</xsd>
We have a xsd file in which the contracts are already defined. We use xsd.exe to generate classes for our WCF service, and use the XmlSerializerFormat for our webservice again.
It seems to me, that this is a weird thing to do, to have WCF generate a new XSD for the classes which the xsd.exe generated for us, while we have already have our XSD definition right there for the taking..
While xsd.exe does a nice job of generating classes for us, it also simplifies complextypes as you can see in my previous question; meaning, the xsd actually changes a bit when it generates classes and are used in the webservice again; the ArrayOfStringXXX problem..
Can we tell the WCF service to use our own xsd file for its contract, instead of generating a new contract based on what the xsd.exe delivers?
What I tried:
I already looked at this sample: IWsdlExportExtension interface sample which seems promosing, but I was not able to replace the xsd in the export method, because it was never
called.
TL;DR: Can we point our WCF service to our own xsd file, instead of letting it generate it's own?
Thanks
You can use tools like WSCF.blue to generate the data contract classes from your XSD file. I have experience from this and it works OK for most cases. See this blog for a good explanation.
There are also other tools that enable this, see this question for some suggestions.
There also seems to be a new option in Visual Studio 2012 for this, see the documentation. I haven't checked this out myself.
This development method is referred to as contract first, so you will find yet more info on Google :-)
We do have more than one xsd, currently two teams are working on two different xsd along with one common xsd. If we generate separate class file for each xsd then the common xsd object types are duplicated. If we use all xsd in one command line it generate into one class file. We want separate class file for each xsd so that each team can manage separately and the future changes also can be tracked which team made the change.
Is it possible to create each class file for each xsd passed in the xsd.exe command line when multiple xsd’s are passed?
Thanks,
Zahir
No, sorry, that's not possible.
Remember that the generated class file is an output . I don't know what sort of management that would require. It is the XSD files which are the input to the process, and which should be managed.
Building an app that is relying on a 3rd party provider who has a very verbose set of SOAP services (we're talking 50+ WSDL files). Each individual WSDL however has numerous shared type declarations. When generating client code with wsdl.exe, there used to be a /sharedtypes flag that would merge duplicate entries if a type was found several times.
When I attempt to generate my client code, I bomb on these overlapping types that the 3rd party includes in all their WSDL files.
svcutil /t:code /importxmltypes [mypath]/*.wsdl
Results in error messages alluding to the type collisions. For example, a couple samples of the error messages below:
Error: There was an error verifying some XML Schemas generated during export:
The simpleType 'http://common.soap.3rdparty.com:CurrencyNotation' has already been
declared.
Error: There was an error verifying some XML Schemas generated during export:
The complexType 'http://common.soap.3rdparty.com:NumberFormat' has already been
declared.
I do not have control over the output of the WSDLs. I do not want to have to edit the WSDLs by hand for fear of an error that breaks in a fashion at runtime that would be highly difficult to track back to our editing of the WSDL files. Not to mention that there are 50 some WSDL files that range from 200-1200 lines of XML. (Remind me again why we thought SOAP was the great salvation to us all back in the late 90s?)
Try specifying all the WSDLs in one command:
svcutil http://example.com/service1?wsdl http://example.com/service2?wsdl ...
This should automatically take care of duplicate types. Another option is to take a look at the /reference command switch:
/reference:<file path> - Add the specified assembly to the set of
assemblies used for resolving type
references. If you are exporting or
validating a service that uses 3rd-party
extensions (Behaviors, Bindings and
BindingElements) registered in config use
this option to locate extension assemblies
that are not in the GAC. (Short Form: /r)
This means that if you already have some types defined in some assembly you may include this assembly and svcutil will exclude types from it to avoid duplicates:
svcutil /reference:someassembly.dll http://example.com/service?wsdl
I was having similar problems. By defining different CLR namespaces for the different xml namespaces (using the /namespace argument of svcutil) i was able to get it working.
/namespace:http://www.opengis.net/gml,OpenGIS.GML
I have been using wsdl.exe to get round this because I work with some SOAP webservices which define the same data transfer objects at different endpoints. So I use wsdl.exe because it has the sharetypes switch. I'm not a WPF developer so I don't really care that the output does not implement IWhatever for WPF, but the classes generated are all partial so you can do some work to implement interfaces you care about in a separate file.