Answered by:
XSD generated class problem

Question
-
Hi, I have 10 xml files I use to request and respond from my web service. I use the xsd.exe tool to generate the xsd files and then c# classes. Each class when generated contails the following class NewDataSet and when I build the project I get errors, becaues there are multiply defined items.
public partial class NewDataSet {
private server_amount_data[] itemsField;
/// <remarks/>
[System.Xml.Serialization.
XmlElementAttribute("server_amount_data")]
public server_amount_data[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
This class is included in each of my 10 c# classes and there are multiply defined symbols, itemsField and Items.
Is there a way around this, and if possible can you tell me wha t NewDataSet class is used for.
Thanks,
EndaWednesday, June 17, 2009 12:17 PM
Answers
-
I just came across this thread when I ran into a similar problem.
The simple answer is that xsd.exe looks for an 'id' attribute in the <xs:schema> node of the xsd and names the class accordingly. If that attribute isn't present then it will default to 'NewDataSet' for the Class name.
- Proposed as answer by TheAgus Monday, March 19, 2012 11:10 AM
- Marked as answer by John SaundersModerator Monday, March 19, 2012 7:15 PM
Wednesday, February 16, 2011 1:56 PM
All replies
-
Where are the schemas coming from? Did you mean that you have 10 XSD files, and not 10 XML files?
Please post the command line you use in calling XSD.EXE.
Is this your own web servic that you're calling?
Why do you not simply use "Add Service Reference" to communicate with the service? See How to Consume a Web Service for some ideas around that.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of old ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
Wednesday, June 17, 2009 12:59 PMModerator -
I have 10 hand crafted xml files which are the parameters to my web methods. here are 5 of them, forst I create the xsd files then I generate the c# code.
xsd RetrieveAccomodationList.xml
xsd RetrieveCountries.xml
xsd RetrieveNationalities.xml
xsd RetrieveAmount.xml
xsd RetrieveMethods.xmlxsd RetrieveAccomodationList.xsd /c /l:CS /n:PI.Configuration.XSD /nologo
xsd RetrieveCountries.xsd /c /l:CS /n:PI.Configuration.XSD /nologo
xsd RetrieveNationalities.xsd /c /l:CS /n:PI.Configuration.XSD /nologo
xsd RetrieveAmount.xsd /c /l:CS /n:PI.Configuration.XSD /nologo
xsd RetrieveMethods.xsd /c /l:CS /n:PI.Configuration.XSD /nologo
problem occurs when I include the c# code in my web service solution, I get the build error I described above. multiply defined symbols, itemsField and Items.
What do you think.
EndaWednesday, June 17, 2009 3:22 PM -
I think I would have created the schemas first, then created the XML files so that they validate against the schemas, then created the classes.
Have you looked at the .XML files? I bet they are all DataSets, and that they all have the name "NewDataSet". Naturally, XSD will create a separate, and different, NewDataSet class for each schema.
I recommend you revisit this entire strategy. For instance, why can't you use "Add Web Reference" or "Add Service Reference" to communicate with the service, instead of prepackaged XML files? Why communicate DataSets? That's an anti-pattern - a "worst practice" instead of a best practice. If DataSets must be used, then they should have different names when they have different contents.
Finally, you should try running XSD.EXE with all the .XSD files on the command line at once. That's the only way that XSD can do anything intelligent that would require knowledge of all of your schemas. That may not be enough to solve your problem (a better design may be the only solution), but it may help.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of old ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
- Marked as answer by Youssef Moussaoui - MSFTModerator Wednesday, June 17, 2009 7:04 PM
- Unmarked as answer by Youssef Moussaoui - MSFTModerator Wednesday, June 17, 2009 7:04 PM
- Proposed as answer by Youssef Moussaoui - MSFTModerator Wednesday, June 17, 2009 7:05 PM
Wednesday, June 17, 2009 3:42 PMModerator -
Thanks again, just to show you, here is my hand crafted XML file, there is no mention of NewDataSet.
<?xml version="1.0" encoding="utf-8"?>
<!--- Server file containing accommodation data, Version 1.0 -->
<!-- EM 09/06/2009 -->
<server_accommodation_list>
<xml_message_type>SC accommodation list</xml_message_type>
<version>
<xml_version>1.4</xml_version>
</version>
<merchant_data>
<merchant_country_code>826</merchant_country_code>
</merchant_data>
<accommodation_list>
<accommodation_item>
<ID>894</ID>
<name>ZAMBIA Hotel</name>
<AddressOne>address w323</AddressOne>
<AddressTwo>address w323</AddressTwo>
<AddressThree>address w323</AddressThree>
<PostalCode>75014</PostalCode>
<City>Paris</City>
<Country>250</Country>
</accommodation_item>
</accommodation_list>
</server_accommodation_list>
Here is the XSD that is generated by using XSD.exe. NewDataSet is an element near the end.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="server_accommodation_list">
<xs:complexType>
<xs:sequence>
<xs:element name="xml_message_type" type="xs:string" minOccurs="0" />
<xs:element name="version" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="xml_version" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="merchant_data" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="merchant_country_code" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="accommodation_list" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="accommodation_item" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string" minOccurs="0" />
<xs:element name="name" type="xs:string" minOccurs="0" />
<xs:element name="AddressOne" type="xs:string" minOccurs="0" />
<xs:element name="AddressTwo" type="xs:string" minOccurs="0" />
<xs:element name="AddressThree" type="xs:string" minOccurs="0" />
<xs:element name="PostalCode" type="xs:string" minOccurs="0" />
<xs:element name="City" type="xs:string" minOccurs="0" />
<xs:element name="Country" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="server_accommodation_list" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
But if you think my strategy is wrong I wil give creating the XSD firat a go.
EndaWednesday, June 17, 2009 4:16 PM -
As I said, I would never depend on XSD to infer a schema for me. That's probably why I never saw this bug before.
XSD is inferring that you want a DataSet. When you take the schema it generated from your .XML files and use it to create classes, XSD assumes that the schema was deliberately meant to represent a DataSet named NewDataSet.
There are some questions you have not answered. Is there some reason you can't just use "Add Web Reference" and point either to the service or to the WSDL file in order to access this service?
If you must do it this way, then edit the XSD files and get rid of the NewDataSet element from them all. Also remove any attributes or elements with msdata: in them. Once you've got those schemas, lock them down. Never infer schemas from .XML files again. Instead, if the schema changes, change the schema, then change the XML files (and confirm that they validate).
If you then run all the XSD files through XSD to produce classes (remember: all on the same command line), then I don't think you'll have any more duplicate NewDataSet classes.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of old ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
Wednesday, June 17, 2009 8:35 PMModerator -
For this I am not creating a client to consume the service right now. I am generating the c# classes from the xsd files so I can searialize the xml parameter to the webmethods. My webmethods take xml files as parameters and that is why I want to create the c# classes, so I can work with objects. I reckon I will take your advise though and create the xsd files myself without using xsd.exe.
Thanks,
EndaWednesday, June 17, 2009 11:24 PM -
I'm still very confused. How are you calling these web methods? Could you show us the signature of one of these web methods? That is, show the method name, the [WebMethod] or other attributes, and what parameters it takes?
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of old ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
Thursday, June 18, 2009 12:04 AMModerator -
Currently passing strings, these strings are XML files that are based on our xsd files. The client is given the c# object generated from the xsd file as well as the wsdl.
[
WebMethod]
public string GetEligibleCountries(string strCountriesRequestXML)
{
XmlSerializer _serializer = new XmlSerializer(typeof(XSD.retrieve_countries));XSD.
retrieve_countries _xml = (XSD.retrieve_countries)_serializer.Deserialize(new StringReader(strCountriesRequestXML));
////
////
////
...
}
I'm afraid I am after inheriting this project and trying to make sence out of it. So far been worked on by a few different people. My job is to extend it and to try and do things correctly.
To do things correctly, this is what I have learned...
1. Create my XML files and XSD files myself by hand. XSD files will be used with XSD.exe to generate the c# code to represent xml parameters as objects.
2. Or instead of using a string parameter to the webmethod use the XmlElement type.
3. A web reference will be used by the clients to call the service functions.
Is this a load of blarney?..
EndaThursday, June 18, 2009 8:39 AM -
No, you're much closer to correct. Whoever created this project really didn't know what they're doing.
As Youssef from Microsoft said in another post, you would be better off creating an XSD, then creating classes from the XSD. Then, instead of XmlElement (or the wrapper solution, also from Youssef), you should have the web method accept or return the class created from XSD.
Because the class that XSD.EXE creates from the schema will have appropriate [XmlElement] attributes and such, the web service will be able to serialize and deserialize this class so that it will match the XML that validates against the schema you create. The service will then be able to use properties of an object, instead of having to process XML.
Similarly, when you create a .NET client by using "Add Web Reference", or "Add Service Reference", the client will be able to work with properties of an object. The same will likely happen with clients written in other languages.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of old ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
Thursday, June 18, 2009 2:19 PMModerator -
Of course the simplest solution is to put them each in there own namespace. Though I know this is very ugly. Also I didn't know about the solution mensioned below of just putting tham all on the XSD.exe command together that way it seems all the classes would be generated in one file.
Saturday, July 10, 2010 7:24 PM -
I just came across this thread when I ran into a similar problem.
The simple answer is that xsd.exe looks for an 'id' attribute in the <xs:schema> node of the xsd and names the class accordingly. If that attribute isn't present then it will default to 'NewDataSet' for the Class name.
- Proposed as answer by TheAgus Monday, March 19, 2012 11:10 AM
- Marked as answer by John SaundersModerator Monday, March 19, 2012 7:15 PM
Wednesday, February 16, 2011 1:56 PM -
Phil's reply is the answer, adding the ID attribute to the Schema node helps setting the name of the DataSet class, which would help preventing the errors due to having several classes with the same name.Monday, March 19, 2012 11:12 AM