locked
XSD generated class problem RRS feed

  • 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,
    Enda


    Wednesday, 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.

    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 PM
    Moderator
  • 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.xml

    xsd 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.
    Enda

    Wednesday, 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
    Wednesday, June 17, 2009 3:42 PM
    Moderator
  • 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.


    Enda


    Wednesday, 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 PM
    Moderator
  • 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,
    Enda
    Wednesday, 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 AM
    Moderator

  • 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?..

    Enda

    Thursday, 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 PM
    Moderator
  • 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.

    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