Sunteți pe pagina 1din 11

Amadeus Web Services

Implementation Guide
.NET Framework
Implementation Guidelines and Known Issues

Index

Introduction ......................................................................................................................... 4
Code Generation ................................................................................................................. 5
System Configuration ................................................................................................... 5
Generation ................................................................................................................... 5
Generated Proxy Use (.NET 3.0).................................................................................. 6
Security Authenticate ............................................................................................... 6
Cryptic Command .................................................................................................... 7
Security Sign-Out..................................................................................................... 7
Generated Proxy Use (.NET 3.0 with message contracts)............................................ 7
Security Authenticate ............................................................................................... 7
Cryptic Command .................................................................................................... 8
Security Sign-Out..................................................................................................... 8
Generated Proxy Use (.NET 2.0).................................................................................. 8
Security Authenticate ............................................................................................... 8
Cryptic Command .................................................................................................... 9
Security Sign-Out..................................................................................................... 9
Known Issues...................................................................................................................... 9
.Net 2.0 Session Handling (Session ID)........................................................................ 9
Improving Performance ................................................................................................ 9
Wrong Name Table Buffer Size - No WSDL Impact...................................................... 9
Fields not being set in XML ........................................................................................ 10
Soap Fault 500........................................................................................................... 10
Manual SOAP/HTTP Handling............................................................................... 10
Proxy-generated Handling ..................................................................................... 10
Double Sequences ..................................................................................................... 11
© 2006 Amadeus IT Group SA

Sample Source Code ........................................................................................................ 11

API Consulting & Services


17 December 2009
Page Nº 2
Implementation Guidelines and Known Issues

Document control

Security level
Company Amadeus
Department API Consulting & Services
Author Cedric Counotte
Reviewed by Guillaume Cardon Date DD / MM / YYYY
Approved by Guillaume Cardon Date DD / MM / YYYY
Version Date Change Comment By
0.1 31 / 03 / 2009 Cedric Counotte
0.2 03 / 06 / 2009 Updated Known Issues Cedric Counotte
Soap Fault management
0.3 21 / 07 / 2009 Cedric Counotte
(Http Error 500)
0.4 17 / 12 / 2009 Updated known issues Cedric Counotte
© 2006 Amadeus IT Group SA

API Consulting & Services


17 December 2009
Page Nº 3
Implementation Guidelines and Known Issues

Introduction
This document describes implementation guidelines and known issues when using .NET
framework to access Amadeus Web Services.
© 2006 Amadeus IT Group SA

API Consulting & Services


17 December 2009
Page Nº 4
Implementation Guidelines and Known Issues

Code Generation
System Configuration
Minimum requirement is to have Microsoft Visual Studio 2005 or above installed on your
system. Express editions can also be used.
You have downloaded the WSDL package (.NET version, including all XSDs) for your
services and extracted its content on a local hard drive.
Express editions can be downloaded from here.

Generation
From within a Visual Studio project, you can generate a client proxy as follows:
1. Create a project based on either version of the .NET framework.
2. Right-click on the project name and select either ‘Add Web Reference’ (.NET 2.0)
or ‘Add Service Reference’ (.NET 3.0 or above).
3. In the ‘Address’ text box, enter the location of the WSDL file and press the ‘Go’
button. If everything goes well you should get a screen like this, in .NET 3.0:
© 2006 Amadeus IT Group SA

API Consulting & Services


17 December 2009
Page Nº 5
Implementation Guidelines and Known Issues

And a screen like this in .NET 2.0:

4. Enter the namespace of your choice to replace ‘ServiceReference1’ in the bottom of


the dialog box and press ‘OK’ or ‘Add Reference’.
Code is now generated, and you can start using it as shown in below sections.

Generated Proxy Use (.NET 3.0)


The following code was built on .NET 3.0 framework without the use of the ‘Always generate
message contracts’ option.

Security Authenticate
Security_Authenticate sec_auth = new Security_Authenticate();

sec_auth.dutyCode = new Security_AuthenticateDutyCode();


sec_auth.dutyCode.dutyCodeDetails = new Security_AuthenticateDutyCodeDutyCodeDetails();
sec_auth.dutyCode.dutyCodeDetails.referenceIdentifier = "SU";
sec_auth.dutyCode.dutyCodeDetails.referenceQualifier = "DUT";

sec_auth.passwordInfo = new Security_AuthenticatePasswordInfo[1];


sec_auth.passwordInfo[0] = new Security_AuthenticatePasswordInfo();
sec_auth.passwordInfo[0].dataLength = "12";
sec_auth.passwordInfo[0].dataType = "E";
sec_auth.passwordInfo[0].binaryData = "MnJPRWJyaSZXb1V0";

sec_auth.systemDetails = new Security_AuthenticateSystemDetails();


sec_auth.systemDetails.organizationDetails =
© 2006 Amadeus IT Group SA

new Security_AuthenticateSystemDetailsOrganizationDetails();
sec_auth.systemDetails.organizationDetails.organizationId = "1A";

sec_auth.userIdentifier = new Security_AuthenticateUserIdentifier[1];

API Consulting & Services


17 December 2009
Page Nº 6
Implementation Guidelines and Known Issues

sec_auth.userIdentifier[0] = new Security_AuthenticateUserIdentifier();


sec_auth.userIdentifier[0].originator = "WS1APOC";
sec_auth.userIdentifier[0].originatorTypeCode = "U";
sec_auth.userIdentifier[0].originIdentification =
new Security_AuthenticateUserIdentifierOriginIdentification();
sec_auth.userIdentifier[0].originIdentification.sourceOffice = "NCEP02001";

Security_AuthenticateReply sec_auth_reply;
String sessionid = pt_client.Security_Authenticate(sec_auth, out sec_auth_reply);

return sessionid;

Cryptic Command
Command_Cryptic cryptic_cmd = new Command_Cryptic();
cryptic_cmd.longTextString = new Command_CrypticLongTextString();
cryptic_cmd.longTextString.textStringDetails = cmd;

cryptic_cmd.messageAction = new Command_CrypticMessageAction();


cryptic_cmd.messageAction.messageFunctionDetails = new
Command_CrypticMessageActionMessageFunctionDetails();
cryptic_cmd.messageAction.messageFunctionDetails.messageFunction = "M";

Command_CrypticReply ccr = pt_client.Command_Cryptic(ref sessionid, cryptic_cmd);

return ccr.longTextString.textStringDetails;

Security Sign-Out
Security_SignOut sec_signout = new Security_SignOut();

pt_client.Security_SignOut(ref sessionid, sec_signout);

Generated Proxy Use (.NET 3.0 with message contracts)


The following code was built on .NET 3.0 framework using the ‘Always generate message
contracts’ option.

Security Authenticate
Security_Authenticate sec_auth = new Security_Authenticate();

sec_auth.dutyCode = new Security_AuthenticateDutyCode();


sec_auth.dutyCode.dutyCodeDetails = new Security_AuthenticateDutyCodeDutyCodeDetails();
sec_auth.dutyCode.dutyCodeDetails.referenceIdentifier = "SU";
sec_auth.dutyCode.dutyCodeDetails.referenceQualifier = "DUT";

sec_auth.passwordInfo = new Security_AuthenticatePasswordInfo[1];


sec_auth.passwordInfo[0] = new Security_AuthenticatePasswordInfo();
sec_auth.passwordInfo[0].dataLength = "12";
sec_auth.passwordInfo[0].dataType = "E";
sec_auth.passwordInfo[0].binaryData = "MnJPRWJyaSZXb1V0";

sec_auth.systemDetails = new Security_AuthenticateSystemDetails();


sec_auth.systemDetails.organizationDetails =
new Security_AuthenticateSystemDetailsOrganizationDetails();
sec_auth.systemDetails.organizationDetails.organizationId = "1A";

sec_auth.userIdentifier = new Security_AuthenticateUserIdentifier[1];


sec_auth.userIdentifier[0] = new Security_AuthenticateUserIdentifier();
sec_auth.userIdentifier[0].originator = "WS1APOC";
sec_auth.userIdentifier[0].originatorTypeCode = "U";
sec_auth.userIdentifier[0].originIdentification =
new Security_AuthenticateUserIdentifierOriginIdentification();
sec_auth.userIdentifier[0].originIdentification.sourceOffice = "NCEP02001";
© 2006 Amadeus IT Group SA

Security_AuthenticateRequest sar = new Security_AuthenticateRequest();


sar.Security_Authenticate = sec_auth;

Security_AuthenticateResponse sec_response = pt_client.Security_Authenticate(sar);

API Consulting & Services


17 December 2009
Page Nº 7
Implementation Guidelines and Known Issues

return sec_response.SessionId;

Cryptic Command
Command_Cryptic cryptic_cmd = new Command_Cryptic();
cryptic_cmd.longTextString = new Command_CrypticLongTextString();
cryptic_cmd.longTextString.textStringDetails = cmd;

cryptic_cmd.messageAction = new Command_CrypticMessageAction();


cryptic_cmd.messageAction.messageFunctionDetails = new
Command_CrypticMessageActionMessageFunctionDetails();
cryptic_cmd.messageAction.messageFunctionDetails.messageFunction = "M";

Command_CrypticRequest ccr = new Command_CrypticRequest();


ccr.Command_Cryptic = cryptic_cmd;
ccr.SessionId = sessionid;

Command_CrypticResponse ccresp = pt_client.Command_Cryptic(ccr);

return ccresp.Command_CrypticReply.longTextString.textStringDetails;

Security Sign-Out
Security_SignOut sec_signout = new Security_SignOut();
Security_SignOutRequest sec_req = new Security_SignOutRequest();
sec_req.Security_SignOut = sec_signout;
sec_req.SessionId = sessionid;

Security_SignOutResponse sor = pt_client.Security_SignOut(sec_req);

Generated Proxy Use (.NET 2.0)


The following code was built on .NET 2.0 framework with default parameters.

Security Authenticate
Security_Authenticate sec_auth = new Security_Authenticate();

sec_auth.dutyCode = new Security_AuthenticateDutyCode();


sec_auth.dutyCode.dutyCodeDetails = new Security_AuthenticateDutyCodeDutyCodeDetails();
sec_auth.dutyCode.dutyCodeDetails.referenceIdentifier = "SU";
sec_auth.dutyCode.dutyCodeDetails.referenceQualifier = "DUT";

sec_auth.passwordInfo = new Security_AuthenticatePasswordInfo[1];


sec_auth.passwordInfo[0] = new Security_AuthenticatePasswordInfo();
sec_auth.passwordInfo[0].dataLength = "12";
sec_auth.passwordInfo[0].dataType = "E";
sec_auth.passwordInfo[0].binaryData = "MnJPRWJyaSZXb1V0";

sec_auth.systemDetails = new Security_AuthenticateSystemDetails();


sec_auth.systemDetails.organizationDetails =
new Security_AuthenticateSystemDetailsOrganizationDetails();
sec_auth.systemDetails.organizationDetails.organizationId = "1A";

sec_auth.userIdentifier = new Security_AuthenticateUserIdentifier[1];


sec_auth.userIdentifier[0] = new Security_AuthenticateUserIdentifier();
sec_auth.userIdentifier[0].originator = "WS1APOC";
sec_auth.userIdentifier[0].originatorTypeCode = "U";
sec_auth.userIdentifier[0].originIdentification =
new Security_AuthenticateUserIdentifierOriginIdentification();
sec_auth.userIdentifier[0].originIdentification.sourceOffice = "NCEP02001";

Security_AuthenticateReply sec_auth_reply = pt_client.Security_Authenticate(sec_auth);


© 2006 Amadeus IT Group SA

// WARNING: Not thread-safe if using pt_client from multiple threads!


//
return pt_client.SessionId.Text[0];

API Consulting & Services


17 December 2009
Page Nº 8
Implementation Guidelines and Known Issues

Cryptic Command
Command_Cryptic cryptic_cmd = new Command_Cryptic();
cryptic_cmd.longTextString = new Command_CrypticLongTextString();
cryptic_cmd.longTextString.textStringDetails = cmd;

cryptic_cmd.messageAction = new Command_CrypticMessageAction();


cryptic_cmd.messageAction.messageFunctionDetails = new
Command_CrypticMessageActionMessageFunctionDetails();
cryptic_cmd.messageAction.messageFunctionDetails.messageFunction = "M";

// WARNING: Not thread-safe if using pt_client from multiple threads!


//
pt_client.SessionId.Text[0] = sessionid;

Command_CrypticReply ccr = pt_client.Command_Cryptic(cryptic_cmd);

return ccr.longTextString.textStringDetails;

Security Sign-Out
Security_SignOut sec_signout = new Security_SignOut();

// WARNING: Not thread-safe if using pt_client from multiple threads!


//
pt_client.SessionId.Text[0] = sessionid;

pt_client.Security_SignOut(sec_signout);

Known Issues
.Net 2.0 Session Handling (Session ID)
In .NET 2.0, the session id is handled using a single common object. Thus in a multi-
threaded environment, developers must synchronize service calls, so that only one thread
makes service calls at a time.

Improving Performance
It has been noted that on .NET 2.0 / 3.0 framework, the first web service call is very slow.
This is mainly due to the framework attempting to configure the proxy automatically!
To improve performance, add the following line to your code:
System.Net.WebRequest.DefaultWebProxy = null;

or
MyRequest.Proxy = null;

To improve HTTPS performance, add the following line to your code:


System.Net.ServicePointManager.UseNagleAlgorithm = false;

Wrong Name Table Buffer Size - No WSDL Impact


By default .NET allocated 16384 bytes to store name tables. On initial connections, the
framework will check all verbs and messages to index them for performance reasons.
Unfortunately, this 16384 bytes buffer is not enough and needs to be adjusted in the
app.config auto-generated file, by editing the maxNameTableCharCount attribute of the
readerQuotas element as follows:
© 2006 Amadeus IT Group SA

<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"


maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />

API Consulting & Services


17 December 2009
Page Nº 9
Implementation Guidelines and Known Issues

Fields not being set in XML


You may notice that some fields even you set them to a specific value do not appear in the
XML generated code.
This is true only for base data types, such as integer, decimal, because there is no way for
.NET to know if the value is present or not, to the opposite of String, which can be set to null,
informing the .NET framework that the field is not setup, thus not to be used.
In this case, .NET adds a field named ‘<field_name>Specified’, which can be set to true or
false (false being the default).
For example in the PaxReference of some web services, there is a traveler node containing
a ‘ref’ element, which is an integer, and .NET adds a refSpecified Boolean which must be set
to true to ensure the ‘ref’ element is added to the XML-generated code.
This issue is only relevant for optional elements (minOccurs=0 in XSDs definition).

Soap Fault 500


When a SOAP FAULT is received it is encapsulated within a HTTP Error Code 500,
which generates an exception. But the response is not provided in the exception, instead only
the soap fault string is returned. One might need the full response.

Manual SOAP/HTTP Handling


To handle such error code, one must encapsulate the GetResponse() method in a try-catch
block with a code similar to this:
// Get response
//
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception e)
{
// Manage HTTP ERROR 500...
//
FieldInfo fi = request.GetType().GetField("_HttpResponse", BindingFlags.NonPublic |
BindingFlags.Instance);
if (fi != null)
{
// Get soap fault response
//
response = (HttpWebResponse)fi.GetValue(request);
}
if (response == null)
{
// Other error
//
}
}

Proxy-generated Handling
In .NET 3.0, the detail of the exception will be contained in an object of type
© 2006 Amadeus IT Group SA

System.ServiceModel.FaultException. In .NET 2.0, it is contained in an object of type


System.Web.Services.Protocoals.SoapHeaderException.

API Consulting & Services


17 December 2009
Page Nº 10
Implementation Guidelines and Known Issues

Double Sequences
You may get this error message at run-time:
error CS0029: Cannot implicitly convert type…

It appears that the code generator for .NET performs auto-optimization on code generation
for the following types of WSDL fragment (a sequence containing a single sequence):
<xs:element name="name1" …>
<xs:complexType>
<xs:sequence>

<xs:element name="name2" …>


<xs:sequence>

</xs:sequence>
</xs:element>

</xs:sequence>
</xs:complexType>
</xs:element>

It results in a two dimensional table (definition [] []) instead of a one dimensional table
containing one single element. To solve this issue, an optional dummy element should be
added to the top sequence:
<xs:element name="name2" …/>
<xs:element name="Dummy.NET" minOccurs="0" maxOccurs="0"/>

To ensure you have generated the code properly, make sure you can’t find any “[][]” inside
your solution directory (usually in a reference.* file).

Sample Source Code


Here is the full source code of the above 3 projects.

AmadeusWebServiceTest.zip
© 2006 Amadeus IT Group SA

API Consulting & Services


17 December 2009
Page Nº 11

S-ar putea să vă placă și