I ran into a strange problem using a C# webservice client to call a ASP.NET 2.0 webservice.
The service is a simple product search and returns an array of products matching a search term - see the relevant part of the WSDL file below.
My C# client is simply generated by adding a web reference in VS2010 (non-WCF) and for comparison I'm using an Axis 1.4 Java client.
Using the same search paramaters in both the C# and the Java client the call returns 50 products but in the C# client the result array has length 1 while the Java client shows up the correct 50 elements.
I am looking for suggestions how to locate the problem - I've tried the following:
Compare the XML returned by the webservice using a TCP/IP monitor: The XML looks identical C# vs. Java and contains the 50 products
Compare HTTP parameters using netcat: C# defaults to HTTP 1.1 while Axis 1.4 uses HTTP 1.0, but changing the C# client to use HTTP 1.0 as well does no change anything
Try SOAP 1.2 instead of SOAP 1.1: No effect
Try HttpGetProtocol, HttpPostProtocol instead of Soap
Any suggestions are highly appreciated.
EDIT: Full WSDL and generated code (Reference.cs) can be found here:
http://timmay.dk/Reference.txt
http://timmay.dk/Wsdl.txt
Simplified WSDL part:
<s:element name="Search">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="SearchTerm" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="StartFrom" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="NumberToBeReturned" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="SearchResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="SearchResult" type="tns:SearchResult" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="SearchResult">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Products" type="tns:ArrayOfResponseProduct" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfResponseProduct">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="ResponseProduct" nillable="true" type="tns:ResponseProduct" />
</s:sequence>
</s:complexType>
<s:complexType name="ResponseProduct">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Fields" type="tns:ArrayOfResponseField" />
</s:sequence>
<s:attribute name="id" type="s:string" />
</s:complexType>
From the WSDL I gather that the maxOccurs is 1. So it seems that you should receive indeed only one SearchResult. However, that result itself should contain an object of type ArrayOfReponseProduct, which contains an unbounded amount of `ResponseProduct items. Maybe you are not looking deep enough?
Have you tried to check inside the debugger with the variable inspectors (Local, Auto, Immediate etc)? Is the object typed, or untyped, in which case you may need to cast it first to see the contents?
It turned out that the culprit was the type of the return values - Response field
< s:complexType name="ResponseField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Value">
<s:complexType>
<s:sequence>
<s:element ref="s:schema" />
<s:any />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
This was pr default converted to a System.Data.DataSet - changing this to a simple string solved the problem. It seems that the unmarshalling failed in this case.
Related
If in the WSDL definition of one of my web methods, I have something like this:
<s:complexType name="ExampleType">
<s:sequence>
<s:element name="Element1" type="s:string" maxOccurs="1" minOccurs="0"/>
<s:element name="Element2" type="s:string" maxOccurs="1" minOccurs="0"/>
<s:element name="Element3" type="s:string" maxOccurs="1" minOccurs="0"/>
</s:sequence>
</s:complexType>
Is it possible to change the order that these elements are returned to the client?
Method being called is something like this:
public static IList<ExampleType> WebMethod(string number)
{
IList<ExampleType> listOfExampleType = GetExampleType();
return listOfExampleType;
}
As I am new to WSDL, WCF and SOAP, I have no real clue how I should structure the WSDL.
My problem right now is that when a user logs in using their username//password, the server should respond with data owned by the user. Lets say the data that wants to be sent back are:
MatterID
MatterTitle
MatterText
MatterDate
The problem is that each user can own more than 1 matter and my problem is that I have no idea how to parse more than the first Matter that the server send as response. My WSDL is structured something like this:
IN:
username
password
OUT:
int MatterID
str MatterTitle
str MatterText
int MatterDate
Am I doing it wrong? Should I respond with a list instead containing all the data? Or is there a way to loop through a response?
If you have an array of data to return, you better define a list in the WSDL (the types section) like so:
<wsdl:types>
<s:schema xmlns:s="http://www.w3.org/2001/XMLSchema" targetNamespace="http://localhost/SampleService" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<s:complexType name="MatterItemType"> <!-- List Item -->
<s:sequence>
<s:element name="MatterID" type="s:integer" minOccurs="1" maxOccurs="1"/>
<s:element name="MatterTitle" type="s:string" minOccurs="1" maxOccurs="1"/>
<s:element name="MatterText" type="s:string" minOccurs="1" maxOccurs="1"/>
<s:element name="MatterDate" type="s:integer" minOccurs="1" maxOccurs="1"/>
</s:sequence>
</s:complexType>
<s:complexType name="MatterListType"> <!-- List -->
<s:sequence>
<s:element name="MatterItem" type="tns:MatterItemType" minOccurs="0" maxOccurs="unbounded"/>
</s:sequence>
</s:complexType>
<!-- Request and Response -->
<s:element name="SampleRequest">
<s:complexType>
<s:sequence>
<s:element name="username" type="s:string" minOccurs="1" maxOccurs="1"/>
<s:element name="password" type="s:string" minOccurs="1" maxOccurs="1"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="SampleResponse">
<s:complexType>
<s:sequence>
<s:element name="MatterList" type="tns:MatterListType" minOccurs="1" maxOccurs="1"/>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
The Response always contains a MatterList element which is of MatterListType. The MatterListType contains from 0 to N MatterItem items defined in the MatterItemType.
The response will be structured something like this (not including SOAP envelope, namespaces, etc, just for illustration of the structure):
<SampleResponse>
<MatterList>
<MatterItem>
<MatterID>1</MatterID>
<MatterTitle>Title1</MatterTitle>
<MatterText>Text1</MatterText>
<MatterDate>1</MatterDate>
</MatterItem>
<MatterItem>
<MatterID>2</MatterID>
<MatterTitle>Title2</MatterTitle>
<MatterText>Text2</MatterText>
<MatterDate>2</MatterDate>
</MatterItem>
</MatterList>
</SampleResponse>
Let me know if you need more help in the comments.
I have a basic web service that parses XML sent from a client. The web service works fine but I was asked to remove elements from the WSDL file generated by the web service. Is it even possible to do this?
Here are the first lines from the WSDL file:
<wsdl:definitions targetNamespace="localhost">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="localhost">
<s:element name="HTTPWebService">
<s:complexType/>
</s:element>
<s:element name="HTTPWebServiceResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="HTTPWebServiceResult">
<s:complexType mixed="true">
<s:sequence>
<s:any/>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="HTTPWebServiceSoapIn">
<wsdl:part name="parameters" element="tns:HTTPWebService"/>
</wsdl:message>
Is it possible to remove the lines <s:element name="HTTPWebServiceResponse"> and it's contents, and <s:element name="HTTPWebServiceResponse">?
WSDL is a system generated xml file and editing its content may cause unexpected behavior and may not be load during introspecting. You cannot edit those lines without understanding what functionality these elements do.
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.
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