Working with Dekho Java Web Service in .Net

farflungconvyancerSoftware and s/w Development

Dec 2, 2013 (3 years and 10 months ago)

116 views




Working with Dekho Java Web Service in .Net


ESRI Australia

Working with Dekho Java Web Services in .Net

Alexander Uloth

auloth@esriaustralia.com.au

Released
Version 1.0
July 2009

ESRI Australia Pty Ltd
Lvl 1 442 Murray Street
Perth WA 6000
Phone 94767500
Fax 94767555
Web www.esriaustralia.com.au

Putting knowledge into place







ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 2 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

Contents
1

Introduction 3

1.1 Background 3
1.2 Java Web Services and Visual Studio .Net 3
2

De-serialization Issues with .Net 4

2.1 Null Object Returned from Web Service 4
2.1.1 Symptom 4
2.1.2 Cause 4
2.1.3 Solution 6
2.1.4 References 6
2.2 Complex Objects Returned Contain Empty Arrays 7
2.2.1 Symptom 7
2.2.2 Cause 7
2.2.3 Solution 7
2.2.4 References 8
2.3 Jagged Arrays incorrectly Deserialized 9
2.3.1 Symptom 9
2.3.2 Cause 9
2.3.3 Solution 9
2.3.4 References 10




ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 3 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

1 Introduction
1.1 Background
Prior to Dekho 3.0 all calls to Dekho web services took a single input parameter of type string. This XML
formatted string would contain the function parameters. E.g.:

string
xml =
"<request><session-
id>AC10181E:0117A9E39C6E:7D27:017CF956</session-id></request>"
;

Likewise the response from every Dekho web service call was an XML formatted string. These methods
required XML manipulation to build the input string and process the results, but there were no problems
consuming these Java web services in .Net.
Dekho 3.0 has removed the single string input and response and now works with complex data types. This
means no more XML manipulation, however there are a couple potential problems to making this work with
.Net.

1.2 Java Web Services and Visual Studio .Net
Dekho uses Java web services, when you import the Java WSDL definitions into Visual Studio; Visual
Studio builds some reference classes, usually into a reference.cs. When a web service call is made that
returns a complex data type .Net attempts to de-serialize the SOAP message into these reference classes.
The problem is that the SOAP XML is not always correctly de-serialized into the reference.cs classes. This
appears to be a restriction of Visual Studio, but at time of writing I am unaware of any patches to Visual
Studio that correct these problems. Fortunately these errors can be corrected by manually modifying the
reference.cs classes. The following sections list symptoms, causes and solutions for several de-
serialization problems.


ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 4 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

2 De-serialization Issues with .Net
2.1 Null Object Returned from Web Service
2.1.1 Symptom
The object returned from the web service call is null, expected complex data type. The returned SOAP
message is correct and contains data, but no object is created, or the object created has null values.

2.1.2 Cause
This is the most common problem and is usually caused by incorrect namespace definitions in the
reference.cs classes. Below is a sample return SOAP XML message, of a “getSessionInfoSoap” call to the
Dekho Session Service. Note the namespace defined in the message:
“http://session.dekho.esriau.com.au”.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"><soapenv:Body><getSessionInfoSoapResponse
xmlns="http://session.dekho.esriau.com.au"><getSessionInfoSoapReturn><displayWkid>28350</displayWkid><exte
nt><maxX>147.46876126658478</maxX><maxY>-
26.313546999999993</maxY><minX>146.88867773341522</minX><minY>-
26.653351855036863</minY></extent><height>816</height><identifiedFeatures/><mapId>1</mapId><measurementFea
tures/><measurementUnits>esriMeters</measurementUnits><redlineFeatures/><selectableLayers><selectableLayers>0
</selectableLayers><selectableLayers>1</selectableLayers><selectableLayers>2</selectableLayers><selectableLayers
>3</selectableLayers><selectableLayers>4</selectableLayers><selectableLayers>5</selectableLayers></selectableLay
ers><selectedFeatures><selectedFeatures><layerId>1</layerId><layerName>VIN.DCDB_clpd</layerName><selectedFe
aturesIds><selectedFeaturesIds>594</selectedFeaturesIds></selectedFeaturesIds></selectedFeatures><selectedFeatur
es><layerId>2</layerId><layerName>VIN.PMAV</layerName><selectedFeaturesIds><selectedFeaturesIds>1543</select
edFeaturesIds></selectedFeaturesIds></selectedFeatures><selectedFeatures><layerId>3</layerId><layerName>VIN.RE
SEQ</layerName><selectedFeaturesIds><selectedFeaturesIds>1828</selectedFeaturesIds></selectedFeaturesIds></se
lectedFeatures><selectedFeatures><layerId>4</layerId><layerName>VIN.Regional Ecosystem -
Status</layerName><selectedFeaturesIds><selectedFeaturesIds>1828</selectedFeaturesIds></selectedFeaturesIds></
selectedFeatures></selectedFeatures><selectionMode>0</selectionMode><userName>anonymous</userName><visible
Layers><visibleLayers>0</visibleLayers><visibleLayers>1</visibleLayers><visibleLayers>2</visibleLayers><visibleLayer
s>3</visibleLayers><visibleLayers>4</visibleLayers><visibleLayers>5</visibleLayers></visibleLayers><width>1393</widt
h></getSessionInfoSoapReturn></getSessionInfoSoapResponse></soapenv:Body></soapenv:Envelope>

If we inspect the start of the corresponding WSDL we see:


   

-



 
 ! 
" 


   



 " #
 "

  



"


   



 


   








   




$

 
   




%


 
   




&

  
   




'

   
   




(


   






  





 "

   






  !"#


-

)


WSDL created by Apache Axis version: 1.3
Built on Oct 05, 2005 (05:23:37 EDT)







ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 5 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

-



*"



-



#   + ,

$


 ! 
" 


   





  !"#





" 


" 

 
   
-




" 


" 

   
   

-




" 


" 



   
-




" 


" 


 
   
-




" 


" 

  
   
-




" 


" 


   
-




Note that the WSDL imports multiple namespaces, but the target namespace is the one used in the SOAP
message above: “http://session.dekho.esriau.com.au”. This all looks ok so far, now let’s check the
automatically generated reference.cs definition for the “getSessionInfoSoap” method:



///

<remarks/>
[System.Web.Services.Protocols.
SoapDocumentMethodAttribute
(
""
,
RequestNamespace=
"http://session.dekho.esriau.com.au"
,
ResponseNamespace=
"http://session.dekho.esriau.com.au"
,
Use=System.Web.Services.Description.
SoapBindingUse
.Literal,
ParameterStyle=System.Web.Services.Protocols.
SoapParameterStyle
.Wrapped
)]
[
return
:
System.Xml.Serialization.
XmlElementAttribute
(
"getSessionInfoSoapReturn"
)]

public

SessionInfoSoap
getSessionInfoSoap(
string
sessionId) {



The Request and Response namespaces match the namespace defined in the returned soap message, this
is correct, everything still looks ok. Note that the method returns an object of type
SessionInfoSoap
;
inspecting this object definition:


///

<remarks/>
[System.CodeDom.Compiler.
GeneratedCodeAttribute
(
"System.Xml"
,
"2.0.50727.3053"
)]
[System.
SerializableAttribute
()]
[System.Diagnostics.
DebuggerStepThroughAttribute
()]
[System.ComponentModel.
DesignerCategoryAttribute
(
"code"
)]

[System.Xml.Serialization.
XmlTypeAttribute
(Namespace=
"http://response.s
ession.dekho.esriau.com.au"
)]

public

partial

class

SessionInfoSoap
{


Here we see a problem, the namespace defined here, although it is a namespace that is defined in the
WSDL, is not the namespace used in the SOAP message, the result is that the SessionInfoSoap object will
not be created correctly and the returned SessionInfoSoap object will have all its properties set to their
default values (usually null). Note; this will not result in any exception being returned, only that the object is
not correctly populated.


ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 6 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0


http://response.session.dekho.esriau.com.au != http://session.dekho.esriau.com.au

2.1.3 Solution
The solution to this problem is to manually modify the namespace definition in the reference.cs class and
change it to the namespace specified in the returned SOAP XML.

Old, incorrect definition from reference.cs:

///

<remarks/>
[System.CodeDom.Compiler.
GeneratedCodeAttribute
(
"System.Xml"
,
"2.0.50727.3053"
)]
[System.
SerializableAttribute
()]
[System.Diagnostics.
DebuggerStepThroughAttribute
()]
[System.ComponentModel.
DesignerCategoryAttribute
(
"code"
)]

[System.Xml.Serialization.
XmlTypeAttribute
(Namespace=
"http://response.s
ession.dekho.esriau.com.au"
)]

public

partial

class

SessionInfoSoap
{

Corrected definition from reference.cs:

///

<remarks/>
[System.CodeDom.Compiler.
GeneratedCodeAttribute
(
"System.Xml"
,
"2.0.50727.3053"
)]
[System.
SerializableAttribute
()]
[System.Diagnostics.
DebuggerStepThroughAttribute
()]
[System.ComponentModel.
DesignerCategoryAttribute
(
"code"
)]

[System.Xml.Serialization.
XmlTypeAttribute
(Namespace=
"http://session.de
kho.esriau.com.au"
)]

public

partial

class

SessionInfoSoap
{


2.1.4 References
The following URLs reference this problem:


http://stackoverflow.com/questions/64833/writing-c-client-to-consume-a-java-web-service-that-returns-
array-of-objects



ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 7 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

2.2 Complex Objects Returned Contain Empty Arrays
2.2.1 Symptom
Even after fixing the namespace errors in section 2 the complex objects that contain arrays always return
empty arrays. The returned SOAP message is correct and contains data that should populate the array, but
the array has 0 elements.

Amendment: (11/03/2010) In Dekho 3.0.4 the SOAP message returned references array items as “item” so
it is not necessary to make the below changes.

2.2.2 Cause
This is caused by incorrectly identifying the name of the array field from the SOAP XML in the reference.cs
definition of the array.
If we continue the example from section 2 we may observe that the
SessionInfoSoap
object returned
should have an array of selectable layer ids corresponding to the following XML structure, but the array is
empty.

<selectableLayers><selectableLayers>0</selectableLayers><selectableLayers>1</selectableLayers><selectableLayers>
2</selectableLayers><selectableLayers>3</selectableLayers><selectableLayers>4</selectableLayers><selectableLayer
s>5</selectableLayers></selectableLayers>

Clearly the array should have values, so inspecting the reference.cs definition for this property:

private

int
[] selectableLayersField;

///

<remarks/>
[System.Xml.Serialization.
XmlArrayAttribute
(IsNullable=
true
)]
[System.Xml.Serialization.
XmlArrayItemAttribute
(
"item"
,
Namespace=
"http://session.dekho.esriau.com.au"
, IsNullable=
false
)]

public

int
[] selectableLayers {

get
{

return

this
.selectableLayersField;
}

set
{

this
.selectableLayersField =
value
;
}
}

Notice that the definition of the XmlArrayItemAttribute specified the element to be of type “item”, but in the
XML the element is named “selectableLayers”. This means that when the SOAP XML is de-serialized it
attempts to find an element of name “item” and disregards all the elements of name “selectableLayers”,
resulting in an empty array being returned.
2.2.3 Solution
The solution is to ensure that the name of the element defined in the
XmlArrayItemAttribute

metadata for the array matches the element name in the returned SOAP XML message.

Old, incorrect definition from reference.cs:

private

int
[] selectableLayersField;

///

<remarks/>
[System.Xml.Serialization.
XmlArrayAttribute
(IsNullable=
true
)]


ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 8 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

[System.Xml.Serialization.
XmlArrayItemAttribute
(
"item"
,
Namespace=
"http://session.dekho.esriau.com.au"
, IsNullable=
false
)]

public

int
[] selectableLayers {

get
{

return

this
.selectableLayersField;
}

set
{

this
.selectableLayersField =
value
;
}
}


Corrected definition from reference.cs:


private

int
[] selectableLayersField;

///

<remarks/>
[System.Xml.Serialization.
XmlArrayAttribute
(IsNullable=
true
)]

[System.Xml.Serialization.
XmlArrayItemAttribute
(
"selectableLayers"
,
Namespace=
"http://session.dekho.esriau.com.au"
, IsNullable=
false
)]

public

int
[] selectableLayers {

get
{

return

this
.selectableLayersField;
}

set
{

this
.selectableLayersField =
value
;
}
}


2.2.4 References
The following URL does not directly reference this problem, but deals with a similar issue which lead me to
discover the above fix:


http://groups.google.com/group/microsoft.public.dotnet.xml/browse_frm/thread/383d0253b40c0da8?hl=e
n&lr=&ie=UTF-
8&rnum=8&prev=/groups%3Fq%3Ddotnet%2520XmlSerializer%2520cannot%2520convert%2520type%
26hl%3Den%26lr%3D%26ie%3DUTF-8%26sa%3DN%26tab%3Dwg





ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 9 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

2.3 Jagged Arrays incorrectly De-serialized
2.3.1 Symptom
Note: I have not encountered this problem with any of the Dekho web services at time of writing; however it
is possible it may exist. I came across this potential problem while researching the previous fixes and
thought it best to include here just in case. I believe the symptom is an exception thrown when attempting to
de-serialize jagged arrays or jagged arrays incorrectly de-serialized.
2.3.2 Cause
Taken directly from reference URL:
What you have run into is a known problem with the XmlSerializer when
generating classes from XML schemas whose members need to be represented as
jagged arrays. On running XSD against your schema, the following is the
class generated for the Infomation type:
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public class Information {
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("CoID",
typeof(CoIDType), IsNullable=false)]
public CoIDType[][] CoIDs;
}
If you notice carefully, you will see that the public CoIDs field is a
jagged array. In a jagged array, each element of the array is an array by
itself. This needs to be reflected in the type specified in the
XmlArrayItemAttribute that describes how the field should be serialized.

2.3.3 Solution
The solution involves modifying the reference.cs class definitions; taken directly from reference URL:

You will need to manually change the above definition to the following to
reflect the array type of each element of the jagged array and to get your
code to run (Notice the change in the type specified in the
XmlArrayItemAttribute):
System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public class Information {
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("CoID",
typeof(CoIDType[]), IsNullable=false)]
public CoIDType[][] CoIDs;
}


ESRI Australia
Working with Dekho Java Web Services in .Net

Working with Dekho Java Web Service in .Net
July 2009


Page 10 www.esriaustralia.com.au
© ESRI Australia
Released
Version 1.0

While your code will now execute and you will be able to serialize your
object instances to XML, you may have some problems when attempting to
de-serialize the data. This can happen in a few cases and is again a known
behavior. Implement this change and test the serialization/de-serialization
to see how it works in your case.
2.3.4 References
The following URLs reference this problem:


http://groups.google.com/group/microsoft.public.dotnet.xml/browse_frm/thread/383d0253b40c0da8?hl=e
n&lr=&ie=UTF-
8&rnum=8&prev=/groups%3Fq%3Ddotnet%2520XmlSerializer%2520cannot%2520convert%2520type%
26hl%3Den%26lr%3D%26ie%3DUTF-8%26sa%3DN%26tab%3Dwg


http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/edf02da2-fbf0-441b-88ed-
aa3b6c3ec61c