I hoping you guys can help me.
I am a .Net developer using C# code. I have been given the task to call a web service written in Java by my colleague. The first problem we have is he doesn’t speak .Net and I don’t speak Java.
The first question is whether to using a web reference or a service reference. Both seem to work in the sense that my program can find the service and add the reference. But the Service Reference is not exposed in my project. For this reason I went with the Web reference at least for now.
I can set any of the properties and recall them and it works fine. The question I have is how to invoke the method. When I ask my colleague he does not seem to get what I am talking about.
I need the answer if it’s something simply or if I need to ask a question my colleague in a way that a Java person will understand what I’m talking about.
Here is the code I have written:
WebReference.getContactUs myContactUs = new WebReference.getContactUs();
myContactUs.ContactUsReceived = DateTime.Now;
myContactUs.FirstName = "Bob";
myContactUs.LastName = "Avallone";
DateTime _ThisDateTime = myContactUs.ContactUsReceived;
Here is the code from the wsdl
<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://contactus.nrcme.fmcsa.dot.gov/" xmlns:ns1="http://nrcme.fmcsa.dot.gov/ContactUs/" name="ContactUs" targetNamespace="http://nrcme.fmcsa.dot.gov/ContactUs/" xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xs:schema targetNamespace="http://nrcme.fmcsa.dot.gov/ContactUs/" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="getContactUs">
<xs:complexType>
<xs:sequence>
<xs:element name="ContactUsReceived" type="xs:dateTime" />
<xs:element name="FirstName" type="xs:string" />
<xs:element name="LastName" type="xs:string" />
<xs:element name="Title" type="xs:string" />
<xs:element name="Organization" type="xs:string" />
<xs:element name="Address1" type="xs:string" />
<xs:element name="Address2" type="xs:string" />
<xs:element name="City" type="xs:string" />
<xs:element name="State" type="xs:string" />
<xs:element name="ZipCode" type="xs:string" />
<xs:element name="Telephone" type="xs:string" />
<xs:element minOccurs="0" name="Fax" type="xs:string" />
<xs:element name="Email" type="xs:string" />
<xs:element name="EmailConfirm" type="xs:string" />
<xs:element minOccurs="0" name="Comment" type="xs:string" />
<xs:element minOccurs="0" name="Question1" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getContactUsResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="ContactUsReceived" type="xs:dateTime" />
<xs:element minOccurs="0" name="status" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</types>
<message name="ContactUs_getContactUsResponse">
<part name="getContactUsResponse" element="ns1:getContactUsResponse" />
</message>
<message name="ContactUs_getContactUs">
<part name="getContactUs" element="ns1:getContactUs" />
</message>
<portType name="ContactUs">
<operation name="getContactUs" parameterOrder="getContactUs">
<input message="ns1:ContactUs_getContactUs" />
<output message="ns1:ContactUs_getContactUsResponse" />
</operation>
</portType>
<binding name="ContactUsBinding" type="ns1:ContactUs">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="getContactUs">
<soap:operation soapAction="http://nrcme.fmcsa.dot.gov/ContactUs/getContactUs" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
</definitions>
Thanks in advance, this forum has been great.
One of the problems that I see is that the WSDL is making things a little confusing. It defines both the XML data object element name and Web Service operation as 'getContactUs'. I would discuss changing the XML data element from 'getContactUs' to something similar to 'ContactInfo'. If this element changes, you will most likely see that your confusion was with this naming.
Typically you would have a few operations that you would need to perform to execute the web service. The first is to retrieve the WebReference proxy instance for the service. The second is to initialize any input parameters as needed. Finally you would use the proxy class to invoke the service method. I believe you have performed the second step, but you are missing the first step which would give you access to the web service invocation. The service invocation may look something similar to the following depending on you code:
WebReference.ContactUs myService = new WebReference.ContactUs();
...
<result data type> _Response = myService.getContactUs(myContactUs);
...
It seems that you are calling the service method when you call new WebReference.getContactUs();. If you check the web server logs of the machine running the java service you can verify this, However soap "functions" are defined by the element in that wsdl.
The most important point is to have the correct WSDL for the code you need to call. THis appears to be in order.
I would suggest you start with Storm (http://storm.codeplex.com/) to ensure that the WSDL is correct and do initial testing of the web service. Then I have been told that Visual Studio can import a WSDL and generate client code you can then just invoke, which I would do next.
I've had this problem too. It's caused by .NET's DateTime type being different than the Java-defined web service. Just use string to replace the DateTime with a confirmed datetime format.
Related
I am using NDbunit to unit test the functionality of my methods and database. For NDbunit to work, it firsts loads an xml schema file (.xsd) and then reads in the xml file with all the data that will be populated into the database. Here is my xml schema file MessageDS.xsd:
<xs:schema id="MessageDS"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:msprop="urn:schemas-microsoft-com:xml-msprop"
targetNamespace="http://tempuri.org/MessageDS.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/MessageDS.xsd"
xmlns:mstns="http://tempuri.org/MessageDS.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="MessageDS" msdata:IsDataSet="true" msdata:UseCurrentLocalexmlns="true" msprop:Generator_MessageDSName="MessageDS" msprop:Generator_DataSetName="MessageDS">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="MESSAGE">
<xs:complexType>
<xs:sequence>
<xs:element name="CREATED_AT" type="xs:dateTime" />
<xs:element name="SUBJECT" type="xs:string" />
<xs:element name="MESSAGE" type="xs:string" />
<xs:element name="FROM" type="xs:string" />
<xs:element name="TO" type="xs:string" />
<xs:element name="TO_EMAIL" type="xs:string" />
<xs:element name="EMAIL_SENT_AT" type="xs:dateTime" />
</xs:sequence>
<xs:attribute name="ID" type="xs:int" use="required" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Here is my xml data file Message.xml:
<MessageDS xlmns="http://tempuri.org/MessageDS.xsd">
<MESSAGE ID="1">
<FROM>Test User 2</FROM>
<TO>Test User 1</TO>
<MESSAGE>
</MessageDS>
Initially I was just using the dll references for NDbunit but eventually I downloaded the source code and started debugging through the problems. I noticed that after the xml schema file is read in the xml file is not being properly loaded into the dataset (System.Data.DataSet). The only xml that is written in is:
<MessageDS xmlns="http://tempuri.org/MessageDS.xsd" />
For some reason my MESSAGE objects are not being read into the xml file. I'm not sure if this is because my xml file is not properly created according to the xml schema file or something else is the cause. I tried to follow the examples on the https://code.google.com/p/ndbunit/wiki/QuickStartGuide for NDbunit and I also looked at the xml files in the testing files for NDbunit.
To start with, "xlmns" is misspelled:
<MessageDS xlmns="http://tempuri.org/MessageDS.xsd">
I'm trying to validate XSD aginst XML but getting an error
The element 'Table' has incomplete content. List of possible elements expected: 'IP21TAG'.
XML:
<NewDataSet>
<Table>
<SITE>VMD</SITE>
<TANK>65-12-392</TANK>
<SERVICE>HZLPG</SERVICE>
</Table>
<Table>
<SITE>VMD</SITE>
<TANK>65-12-392</TANK>
<SERVICE>HZLPG</SERVICE>
<IP21TAG>BC-BBH-OS-4LI21392</IP21TAG>
</Table>
</NewDataSet>
XSD:
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="NewDataSet">
<xs:complexType>
<xs:sequence>
<xs:element name="Table">
<xs:complexType>
<xs:sequence>
<xs:element name="SITE" type="xs:string" />
<xs:element name="PLANT" type="xs:string" />
<xs:element name="TANK" type="xs:string" />
<xs:element name="SERVICE" type="xs:string" />
<xs:element name="IP21TAG" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Can anyone help me how to solve this?
Thanks in advance.
Obviously, solution is to set minOccurs="0" on elements that are optional.
However, error message in Visual Studio displayes even optional elements in the "possible element name" list, so it is not obvious if you miss minOccurs on an element.
My problem was that ONE element missed the minOccurs="0", and error message listed ALL, approximately 100, elements...
You omit minOccurs in <xs:element> node of your schema, its default is one (see specifications) then if you don't specify that node your XML won't be validated against that schema.
If that node is optional simply change your XSD to reflect that. Here I changed just IP21TAG and PLANT (because they're both not present in your example XML but if others are optional too you should change them accordingly):
<xs:element name="IP21TAG" type="xs:string" minOccurs="0"/>
<xs:element name="PLANT" type="xs:string" minOccurs="0" />
If that element is not optional then to be wrong is your XML, you may - for example - provide an empty string instead of a missing node:
<NewDataSet>
<Table>
<SITE>VMD</SITE>
<TANK>65-12-392</TANK>
<SERVICE>HZLPG</SERVICE>
<IP21TAG></IP21TAG>
<PLANT></PLANT>
</Table>
</NewDataSet>
I am trying to create a web service consumer, given a WSDL of a service that is already up and running. The challenge is, doing the whole thing dynamically, in runtime. I am working with C#. To sum up, I have to do the following:
I have an application that will be given as input the WSDL file (url). done
The application will drill down the WSDL file, recognizing the operations, messages and the types used. (point that I'm having trouble with)
It will create the code needed to invoke the Web Service, compile it and load it through reflection. done
Have everything ready for invocation, including creating and sending the necessary parameters to the remote method. Then it'll handle the response properly. done
I am having some issues with #2, which is parsing and drilling down in the WSDL file. In specific: extracting complex types that appear to be "nested".
I've read some very useful resources about extracting complex types:
Parse Complex WSDL Parameter Information
Detailed ServiceDescription / Proxy from WSDL
http://mikehadlow.blogspot.com/2006/06/simple-wsdl-object.html
However, I am a bit puzzled with an example WSDL that I have received for testing:
<definitions name='MyWSService' targetNamespace='http://some.url.com/' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://some.url.com/' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<types>
<xs:schema attributeFormDefault='qualified' elementFormDefault='qualified' targetNamespace='http://some.url.com/' version='1.0' xmlns:tns='http://some.url.com/' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:element name='dsSendOperationName' type='tns:systemSendOperationName'/>
<xs:element name='dsSendOperationNameResponse' type='tns:systemSendOperationNameResponse'/>
<xs:complexType name='systemSendOperationName'>
<xs:sequence>
<xs:element minOccurs='0' name='systemOperationName' type='tns:systemOperationName'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='systemOperationName'>
<xs:sequence>
<xs:element minOccurs='0' name='param1' type='xs:string'/>
<xs:element minOccurs='0' name='param2' type='xs:string'/>
<xs:element minOccurs='0' name='param3' type='xs:string'/>
<xs:element minOccurs='0' name='param4' type='xs:string'/>
<xs:element minOccurs='0' name='param5' type='xs:string'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='systemSendOperationNameResponse'>
<xs:sequence>
<xs:element minOccurs='0' name='return' type='xs:string'/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</types>
<message name='SystemOperationNameWS_dsSendOperationName'>
<part element='tns:dsSendOperationName' name='dsSendOperationName'></part>
</message>
<message name='SystemOperationNameWS_dsSendOperationNameResponse'>
<part element='tns:dsSendOperationNameResponse' name='dsSendOperationNameResponse'></part>
</message>
<portType name='SystemOperationNameWS'>
<operation name='dsSendOperationName' parameterOrder='dsSendOperationName'>
<input message='tns:SystemOperationNameWS_dsSendOperationName'></input>
<output message='tns:SystemOperationNameWS_dsSendOperationNameResponse'></output>
</operation>
</portType>
<binding name='SystemOperationNameWSBinding' type='tns:SystemOperationNameWS'>
<soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='dsSendOperationName'>
<soap:operation soapAction=''/>
<input>
<soap:body use='literal'/>
</input>
<output>
<soap:body use='literal'/>
</output>
</operation>
</binding>
<service name='SystemOperationNameWSService'>
<port binding='tns:SystemOperationNameWSBinding' name='SystemOperationNameWSPort'>
<soap:address location='http://a.url.here.com'/>
</port>
</service>
</definitions>
Look how the root elements (as defined in the messages' section) are referring to a complex type, which has an element that is later on declared as a complex type, that finally has a sequence of elements with standard XSD types.
Programatically, I am able to drill down to the very last element of that "chain". However, I am confused about the type of the actual message being sent to the web service. Is it:
A systemSendOperationName that wraps a systemOperationName, that contains 5 strings?
or
A systemOperationName object that contains 5 strings?
And overall, is that sort of nested types normal? I haven't found a similar example so far.
EDIT:
Made some points of my initial post more clear to avoid any confusions.
I have created a simple Northwind's Product REST Web Service in WCF at /Northwind/Product. I have also enabled WCF Web HTTP Service Help Page on my service, which is at /Northwind/Product/help. I have a "GET" operation and its help page is located at: /Northwind/Product/help/operations/Get, which is your standard WCF help page that displays the Xml body, Json body, Xml Schema and Additional Xml Schemas. Pretty straight forward, right? Okay now, on to the fun stuff...
I am interested in the Xml Schema section, which is:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Product">
<xs:sequence>
<xs:element minOccurs="0" name="CategoryID" nillable="true" type="xs:int" />
<xs:element minOccurs="0" name="Discontinued" type="xs:boolean" />
<xs:element minOccurs="0" name="ProductID" type="xs:int" />
<xs:element minOccurs="0" name="ProductName" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="QuantityPerUnit" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="ReorderLevel" nillable="true" type="xs:short" />
<xs:element minOccurs="0" name="SupplierID" nillable="true" type="xs:int" />
<xs:element minOccurs="0" name="UnitPrice" nillable="true" type="xs:decimal" />
<xs:element minOccurs="0" name="UnitsInStock" nillable="true" type="xs:short" />
<xs:element minOccurs="0" name="UnitsOnOrder" nillable="true" type="xs:short" />
</xs:sequence>
</xs:complexType>
<xs:element name="Product" nillable="true" type="Product" />
</xs:schema>
I am interested in it because of the datatypes. I want to know the datatypes of the elements. Now, I understand that's not the fundamentals of REST. However, I don't want SOAP objects here. I want to keep my services simple and loosely typed and yet still be aware of their datatypes when needed.
My question is, how can I expose just this particular section of the help file? If I cannot do that, what are my other options for achieving what I am trying to do here?
Maybe you could try with OData, as I see it it is in between of REST and SOAP.
http://msdn.microsoft.com/es-es/library/cc668794.aspx
I do not think that it is possible to be both loosly typed and a the same time know the types behind the fields.
You could send everything as a string, and then throw an exception if conversion is not possible.
There does not appear to be a tag in the xs:element tag that could be used for help infomation, http://www.w3schools.com/schema/el_element.asp
I want to add an XML schema(Main.xsd) to a dataset which includes another schema(base.xsd) defining the complex types used in the former one.
The Main.xsd has a block defining xs:unique with selector and field to uniquely define a particular element as the primary key.
Here is the Main.xsd:
<xs:schema id="NewDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/Main.xsd" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" targetNamespace="http://tempuri.org/Main.xsd" attributeFormDefault="unqualified" elementFormDefault="qualified" version="3.0.4 01-07-2011">
<xs:include schemaLocation="base.xsd"/>
<xs:complexType name="Employees">
<xs:sequence>
<xs:element name="EmployeeID" type="UE_SignedInt"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Report" type=" Employees" />
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref=" Report " />
</xs:choice>
</xs:complexType>
<xs:unique name="ReportConst" msdata:PrimaryKey="true">
<xs:selector xpath=".//Report" />
<xs:field xpath="EmployeeID" />
</xs:unique>
</xs:element>
</xs:schema>
The type “UE_SignedInt” is defind in the base.xsd which is included in Main.xsd.
Now , when I try to include Main.xsd into a dataset, it throws an error: “Invalid XPath selection inside field node. Cannot find EmployeeID” as EmployeeID uses the type which is defined in the base.xsd.
If I use some basic type like “xs:int” to this element , the loading into the dataset works fine. Could anyone please help me to resolve this issue??
The issue was solved when I modifed the unique block as:
<xs:unique name="ReportConst" msdata:PrimaryKey="true">
<xs:selector xpath="." />
<xs:field xpath="EmployeeID" />
</xs:unique>
You need to specify the namespace of the UE_SignedInt element.
<xs:element name="EmployeeID" type="xxx:UE_SignedInt"/>