By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,688 Members | 1,229 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,688 IT Pros & Developers. It's quick & easy.

Web Service returning xs:choice as return type in C++ .NET

P: n/a
Hi,

I want to consume a Web Service that returns a choice, but my C++ client
always receives the same returned type. On the other hand, when I am using a
Java client, it is working fine (of course, the generated proxy is not the
same).

When I am looking at the C++ generated code, it seems fine, but when I am
executing the code, I always get the first choice type.

Do someone already used a returned choice in C++ ?

(I am using Visual Studio 2003).
Here is the execute code:

// -------------------------
// My test code
// -------------------------
Object *queryResult = webService->queryMatchingPersonsByTraits(
fillRequestType(condition), szProductID, Convert::ToString(iMaxReturnRow),
totalNumberOfMatches, timestamp );

Query::PersonQueryResponseTypeMatchingProfiles *profiles =
dynamic_cast<Query:: PersonQueryResponseTypeMatchingProfiles *>(queryResult);
if ( profiles == NULL )
{
Query::PersonQueryResponseTypeError* error =
dynamic_cast<Query::PersonQueryResponseTypeError*> (queryResult);
String *value = error->Value;
}

//I never receive a PersonQueryResponseTypeMatchingProfiles in my C++ code,
but I am receiving some in the Java code.
//---------------------------
// Generated Proxy method declaration
//---------------------------
public:
[System::Web::Services::Protocols::SoapDocumentMeth odAttribute(S"http://www.openuri.org/queryMatchingPersonsByTraits",
RequestElementName=S"PersonQueryRequest",
RequestNamespace=S"http://.../personqueryrequest",
ResponseElementName=S"PersonQueryResponse",
ResponseNamespace=S"http://.../personquery",
Use=System::Web::Services::Description::SoapBindin gUse::Literal,
ParameterStyle=System::Web::Services::Protocols::S oapParameterStyle::Wrapped)]
[returnvalue: System::Xml::Serialization::XmlElementAttribute(S" Error",
__typeof(Query::PersonQueryResponseTypeError))]
[returnvalue:
System::Xml::Serialization::XmlElementAttribute(S" MatchingProfiles",
__typeof(Query::PersonQueryResponseTypeMatchingPro files))]
System::Object *
queryMatchingPersonsByTraits(Query::PersonQueryReq uestTypeProfileData *
ProfileData, [System::Xml::Serialization::XmlAttributeAttribute]
System::String * SystemID,
[System::Xml::Serialization::XmlAttributeAttribute( DataType=S"integer")]
System::String * MaxNumMatches,
[System::Xml::Serialization::XmlAttributeAttribute( DataType=S"integer")]
System::String * & TotalNumberOfMatches,
[System::Xml::Serialization::XmlAttributeAttribute] System::DateTime&
Timestamp);

//---------------------------
// Generated Proxy method definition
//---------------------------
inline System::Object *
Person::queryMatchingPersonsByTraits(Query::Person QueryRequestTypeProfileData
* ProfileData, [System::Xml::Serialization::XmlAttributeAttribute]
System::String * SystemID,
[System::Xml::Serialization::XmlAttributeAttribute( DataType=S"integer")]
System::String * MaxNumMatches,
[System::Xml::Serialization::XmlAttributeAttribute( DataType=S"integer")]
System::String * & TotalNumberOfMatches,
[System::Xml::Serialization::XmlAttributeAttribute] System::DateTime&
Timestamp) {
System::Object* __mcTemp__1[] = new System::Object*[3];
__mcTemp__1[0] = ProfileData;
__mcTemp__1[1] = SystemID;
__mcTemp__1[2] = MaxNumMatches;
System::Object * results[] =
this->Invoke(S"queryMatchingPersonsByTraits", __mcTemp__1);
TotalNumberOfMatches = (__try_cast<System::String * >(results[1]));
Timestamp = (*__try_cast<__box System::DateTime * >(results[2]));
return (__try_cast<System::Object * >(results[0]));
};
// -------------------------------
// XML part
// -------------------------------

<xs:element name="QueryResponse" type="pq:QueryResponseType">
</xs:element>
<xs:complexType name="QueryResponseType">
<xs:choice>
<xs:element name="Error">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="pq:ErrorType" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Profiles">
<xs:complexType>

</xs:complexType>
</xs:element>
</xs:choice>

</xs:complexType>
<xs:simpleType name="ErrorType">
<xs:restriction base="xs:string">
<xs:enumeration value="client"/>
<xs:enumeration value="server"/>
</xs:restriction>
</xs:simpleType>


Nov 22 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Hi dgaucher,
I want to consume a Web Service that returns a choice, but my C++ client
always receives the same returned type.


What's the return "xs:choice" here, a custom type you defined in your
webservice application, something like a enum type?

By the way, do you have tried to use other .NET language code(e.g. C#) to
consume the Web Service, is it OK?
Thanks for your understanding!

Best regards,

Gary Chang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------

Nov 22 '05 #2

P: n/a
Hy Gary
By the way, do you have tried to use other .NET language code(e.g. C#) to
consume the Web Service, is it OK?
I have just tried with C# and I am having the same result as in C++. If you
look at the schema, you will find that I should receive an “Error” or a
“MatchingProfiles”. What I am getting from either C# or C++ is always the
“Error”. When the Web Service effectlively returned an “Error”, it is filled
properly, but when it returns a “MatchingProfiles”, I am getting an “Error”
with the default data in.
What's the return "xs:choice" here, a custom type you defined in your
webservice application, something like a enum type?


Effectively, the return is a complex type.
//--------------------------------------------------------------------------
<xs:complexType name="PersonQueryResponseType">
<xs:choice>
<xs:sequence>
<xs:element name="Error">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="pq:ErrorType" use="required"/>

</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="MatchingProfiles">
<xs:complexType>
<xs:sequence>
<xs:element name="UnknownMatchingPerson" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Alias" minOccurs="0" maxOccurs="10">

<xs:complexType>
<xs:attribute name="FirstName" type="xs:string"
use="optional"/>
<xs:attribute name="LastName" type="xs:string"
use="optional"/>
<xs:attribute name="MiddleName" type="xs:string"
use="optional"/>
<xs:attribute name="NameSuffix" type="xs:string"
use="optional"/>
<xs:attribute name="AliasDOB" type="xs:date"
use="optional"/>
<xs:attribute name="AliasSSN" type="xs:string"
use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="ScarsMarksTattoos" minOccurs="0"
maxOccurs="10">
<xs:complexType>
<xs:attribute name="SMTNCICCode" type="xs:string"
use="optional"/>
<xs:attribute name="SMTDescription" type="xs:string"
use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="ConfidenceLevel" type="xs:double"
use="required"/>
<xs:attribute name="MPI" type="xs:string" use="required"/>

<xs:attribute name="MNI" type="xs:string" use="required"/>

<xs:attribute name="FirstName" type="xs:string"
use="optional"/>
<xs:attribute name="LastName" type="xs:string"
use="optional"/>
<xs:attribute name="MiddleName" type="xs:string"
use="optional"/>
<xs:attribute name="NameSuffix" type="xs:string"
use="optional"/>
<xs:attribute name="SSN" type="xs:string" use="optional"/>

<xs:attribute name="StateID" type="xs:string" use="optional"/>

<xs:attribute name="DateOfBirth" type="xs:date"
use="optional"/>
<xs:attribute name="CityOfBirth" type="xs:string"
use="optional"/>
<xs:attribute name="CountyOfBirth" type="xs:string"
use="optional"/>
<xs:attribute name="StateOfBirth" type="xs:string"
use="optional"/>
<xs:attribute name="CountryOfBirth" type="xs:string"
use="optional"/>
<xs:attribute name="Gender" type="xs:string" use="optional"/>

<xs:attribute name="Race" type="xs:string" use="optional"/>

<xs:attribute name="RightEyeColor" type="xs:string"
use="optional"/>
<xs:attribute name="LeftEyeColor" type="xs:string"
use="optional"/>
<xs:attribute name="OperatorLicenseNumber" type="xs:string"
use="optional"/>
<xs:attribute name="OperatorLicenseState" type="xs:string"
use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="KnownMatchingPerson" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="ConfidenceLevel" type="xs:double"
use="required"/>
<xs:attribute name="MPI" type="xs:string" use="required"/>

</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
<xs:attribute name="TotalNumberOfMatches" type="xs:integer"
use="required"/>
<xs:attribute name="Timestamp" type="xs:dateTime" use="required"/>

</xs:complexType>

//--------------------------------------------------------------------------
// where ErrorType is
<xs:simpleType name="ErrorType">
<xs:restriction base="xs:string">
<xs:enumeration value="client"/>
<xs:enumeration value="server"/>
</xs:restriction>
</xs:simpleType>

Thanks for your help
Dominique Gaucher
Nov 22 '05 #3

P: n/a
Hi Dominique,

Thanks for your response, as for the .NET wsdl generated proxy class's
return type problem you mentioned, I've done some research on the .NET's
WSDL parser (wsdl.exe) and found that the problem on parsing the
xsd:choice element does be an existing limitation of the .net 's wsdl.exe
tool.

In fact, the xsd:choice type should be mapped to a variant type which can
reference a certain type among a given type groups. However, currently the
..net's wsdl.exe tool dosn't support the correct mapping on such element(
Variant Type). That's why we'll always get the fixed Type object when
consuming a webservivce with a custom WSDL which contains xsd:choice
element as return type.

Currently, the available workaround is to consuming the xmlwebservice
direct via the HttpWebRequest class in the System.Net namespace. The
wsdl.exe generated proxy class is also using the HttpWebRequest to send the
underlying SOAP message internally. So we can create our own custom proxy
class which directly use the HttpWebRequest to send the SOAP xml message
and get the returned XML SOAP message and then parsing the certain object
instance to the correct type (manually use the xmlSerialier).

If there is any further questions, please feel free to post here.
Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Nov 22 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.