finpower connect 2 web services connectivity … connect web...services connectivity and programming...

72
N:\DATA\Development\finPOWER Connect\Version 2\Web Services\finPOWER Connect Web Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version 1.12 30 th March 2015

Upload: others

Post on 25-Jul-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

N:\DATA\Development\finPOWER Connect\Version 2\Web Services\finPOWER Connect Web Services Connectivity and Programming Guide.doc

finPOWER Connect 2 Web Services Connectivity and Programming

Guide

Version 1.12

30th March 2015

Page 2: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 2 of 72

Table of Contents

Disclaimer.................................................................................................................... 5

Version History ............................................................................................................. 7

Introduction ................................................................................................................. 8

Limitations ................................................................................................................ 8

System Requirements and Prerequisites .......................................................................... 9

Help Resources ........................................................................................................... 10

Web Services ............................................................................................................. 11

Connectivity and Security ............................................................................................ 12

Encryption .............................................................................................................. 12

Authentication ......................................................................................................... 12

Setting up a Test Environment ..................................................................................... 13

Setup and Connection .............................................................................................. 13

Web Administrator ................................................................................................ 15

User .................................................................................................................... 16

Client................................................................................................................... 17

Signing In ............................................................................................................ 18

Using the Web Services Test Form ............................................................................. 19

Programming Languages ............................................................................................. 21

Microsoft .NET ......................................................................................................... 21

Parsing using the XmlDocument .............................................................................. 21

Deserialisation into a .NET Object ............................................................................ 21

Authenticating (Signing In) .......................................................................................... 23

Web Roles ............................................................................................................... 23

Web Subscribers ...................................................................................................... 23

The Authentication Process ....................................................................................... 23

hashSalt .............................................................................................................. 23

hash .................................................................................................................... 24

Authentication Code Sample ................................................................................... 24

Authentication Response ........................................................................................ 27

Supplying the Session Token with a Request ............................................................ 28

When to Re-Authenticate ....................................................................................... 28

Dates ........................................................................................................................ 30

Custom Web Services .................................................................................................. 31

Overview ................................................................................................................ 31

Creating a Custom Web Service Script ........................................................................ 32

Calling the Custom Web Service ................................................................................ 33

Accepting Parameters ............................................................................................... 34

Controlling the Response .......................................................................................... 36

HTML Response..................................................................................................... 36

JSON Response ..................................................................................................... 36

Page 3: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 3 of 72

Text Response ...................................................................................................... 36

XML Response ...................................................................................................... 36

PDF Response ....................................................................................................... 36

Accepting Posted Data .............................................................................................. 38

Serialising the Response ........................................................................................... 40

Nullable Types ...................................................................................................... 41

Dates .................................................................................................................. 43

Enums ................................................................................................................. 45

Using Attributes to Tweak Serialisation .................................................................... 46

Preventing Properties From Being Serialised ............................................................. 47

Serialising Collections ............................................................................................ 49

Deserialising the Request .......................................................................................... 51

Testing Posted XML ............................................................................................... 53

Enums ................................................................................................................. 54

Using Attributes to Tweak Deserialisation ................................................................. 55

Deserialising Collections ......................................................................................... 56

Troubleshooting Deserialisation Issues ..................................................................... 58

Parsing Posted XML Request ...................................................................................... 59

Serialising and Deserialising XML .................................................................................. 61

Serialisation ............................................................................................................ 61

Visual Basic .......................................................................................................... 62

C# ...................................................................................................................... 63

Deserialisation ......................................................................................................... 64

Visual Basic .......................................................................................................... 65

C# ...................................................................................................................... 66

PDF Documents .......................................................................................................... 67

Returning a PDF Document from a Custom Web Service ............................................... 67

Returning a Response Containing a PDF Document Data from a Custom Web Service ....... 68

Formatting PDF Documents ....................................................................................... 69

Visual Basic Code Examples ......................................................................................... 70

Troubleshooting .......................................................................................................... 72

Timeout when Authenticating Client ........................................................................... 72

Misconfigured Address Database ............................................................................. 72

Page 4: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 4 of 72

Page 5: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 5 of 72

Disclaimer This document contains information that may be subject to change at any stage.

All code examples are provided "as is".

Copyright Intersoft Systems Ltd, 2014.

Page 6: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 6 of 72

Page 7: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 7 of 72

Version History Date Version Name Changes

07/03/2014 1.00 PH Created.

17/03/2014 1.01 PH Clarified that Web Services cannot currently be used for accessing external resources.

20/03/2014 1.02 PH Added serialisation/ deserialisation section and samples.

09/04/2014 1.03 PH Added dates section.

02/05/2014 1.04 PH Updated information regarding session tokens and when to re-authenticate.

06/05/2014 1.05 PH Clarified section detailing session token in Authorization header.

06/06/2014 1.06 PH Added troubleshooting guide for address database issues and PDF sections.

21/07/2014 1.07 PH Updated ExecuteRequest sample.

21/07/2014 1.08 PH Support for external Web Services detailed in Limitations section.

12/08/2014 1.09 PH Custom Web Services section enhanced.

13/08/2014 1.10 PH Custom Web Service Enum deserialisation.

01/10/2014 1.11 PH Custom Web Service section used to note new "Execute (Parameters)" option from Test Web Service form.

30/03/2015 1.12 PH Added link to Microsoft article in Introduction, Web Services section.

Page 8: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 8 of 72

Introduction This document is intended for software developers who would like to connect to the finPOWER Connect Web Services over HTTP.

This document provides all of the necessary information needed to connect to and perform requests against the Web Services.

For information on installing and configuring the finPOWER Connect Web Services on a Web

Server, see the finPOWER Connect 2 Web Services Installation and Configuration

document.

Limitations Where access to a resource external to the finPOWER Connect database is required and a built-

in Web Service does not exist to achieve this, it should be assumed that such access cannot

currently be achieved and therefore any Custom Web Services or Scripts that run within finPOWER Connect as part of a Web Service call cannot access these resources.

This includes the following:

Document Manager

o Accessing of the Document Manager folder structure is not possible in the usual manner from a Web Service.

Any form of document publishing, E.g., using a Word VBA template to create a document.

o Microsoft Office should never be run on a Web Server and therefore no form of document publishing is available from a Web Service.

Access to external Web Services, E.g.:

o PPSR G2B

o Credit Bureau (Centrix, Veda, DecisionLogic etc)

o MotorWeb

WARNING: Any Custom Web Services or Scripts that attempt to access external resources

cannot be supported and cannot be guaranteed to work in future releases of finPOWER Connect and the finPOWER Connect Web Services.

Unless listed in the table below, assume the external resource is not supported.

The following external Web Services are supported. The Web Services version at which support was added is detailed below:

Service Version Details

Credit Sense 2.01.01.00 Comprehensive Web Service support.

Veda (Australia) 2.01.01.00 Limited Web Services since it is anticipated most

functionality will be performed from Custom Web

Services.

Page 9: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 9 of 72

System Requirements and Prerequisites Since the finPOWER Connect Web Services use HTTP, the only programming requirement is

a development environment that allows HTTP and secure HTTP (HTTPS) requests to be made.

o The application being developed can use any programming language and exist on any platform providing the above is supported.

A connection to a Web Server running the finPOWER Connect Web Services is required.

o This Web Server might be:

Accessible over the Internet.

Accessible over a private LAN.

Running on the development PC (for testing purposes).

The finPOWER Connect 2 Web Services Installation and Configuration document details installation of the Web Services for testing purposes.

From a development point-of-view, a solid knowledge of the following is recommended:

o HTTP connectivity.

o XML and/ or JSON.

Most code samples are currently limited to Visual Basic (VB.NET).

Page 10: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 10 of 72

Help Resources The finPOWER Connect Web Services have online help detailing all Web Services. This help is available from:

The finPOWER Connect Web Services Web Server via the API reference link on the Sign In

page:

From within the finPOWER Connect Windows User Interface via the Test Web Services

form (Tools, Web, Test Web Services).

o The help is available by selecting a Web Service on the Web Services tab, providing a valid URL has been entered on the Connect page.

This help is constantly evolving and is updated for every new Web Service that is added.

Page 11: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 11 of 72

Web Services All Web Services are based on the Microsoft Web API framework meaning:

o They use HTTP/ HTTPS as a transport protocol.

o They do not use SOAP and therefore no WSDL is available.

XML (or JSON) can be parsed manually or, if using a language that supports it (e.g.,

VB.NET), deserialised into a simple object.

o They use a RESTful, RPC based approach meaning:

Most services are fully URL-based, E.g., to retrieve a list of Accounts for a finPOWER Connect Client, you would simply request a URL such as:

/Api/Client/GetAccounts?clientId=C10000&includeQuote=true

o Unless otherwise specified, both XML and JSON are supported.

Generally, only the HTTP response will contain XML/ JSON data but services that require more than just simple URL parameters can POST either XML or JSON.

The finPOWER Connect Web Services consist of many individual services.

o These services are organised into 'Controllers' which is simply a way of grouping related

services, e.g., the above URL example calls the GetAccounts service which is located in the Client controller.

NOTE: The Web Services help and the Test Web Services form within finPOWER

Connect organise their table of contents with a higher level of grouping for readability,

e.g., both Client and ClientWebMail controllers are grouped within a Client folder.

The following are useful articles for understanding Microsoft's Web API and REST services:

http://blogs.msdn.com/b/martinkearn/archive/2015/01/05/introduction-to-rest-and-net-web-

api.aspx

Page 12: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 12 of 72

Connectivity and Security Connectivity to the Web Services is via HTTP/ HTTPS.

o HTTP is fine for testing but secure HTTP (HTTPS) MUST be used in a production

environment.

o The HTTP link to Web Services may be over a private network or the Internet (public) or,

to an installation of the Web Services running on the same PC (usually for development purposes only, using localhost).

Encryption All communication (in a production environment) takes place over a secure, encrypted HTTP

channel using SSL/ TLS.

o This is enabled by a certificate installed on the Web Server hosting the Web Services and is outside of the scope of this document.

Authentication Most Web Services require authentication.

Any application wishing to access the Web Services must have a Web Subscriber record defined in the finPOWER Connect database.

o This record has an Id and a Secret key, both of which are required for authentication.

Authenticated services must be passed a special Session Token as an HTTP header. This is returned from the initial authentication request.

o The Session Token is valid for up to 24 hours.

Page 13: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 13 of 72

Setting up a Test Environment When programming against the finPOWER Connect Web Services, it is useful to be able to test the Web Services without having to write any code.

finPOWER Connect provides a Test Web Services form for this purpose.

The following steps are required to set up a test environment.

NOTE: This assumes you can connect to a Web Server running the finPOWER Connect Web

Services. Installation and configuration of the Web Services is detailed in the finPOWER Connect 2 Web Services Installation and Configuration document.

Setup and Connection Install the latest version of finPOWER Connect.

Open finPOWER Connect.

o If available, open the finPOWER Connect database to which the Web Services connect.

This is not necessary but does make the connection and testing process easier, E.g., if

you call a Web Service to add an Account, you can then view the Account directly from within finPOWER Connect.

o If unavailable, open any finPOWER Connect database, E.g., the demonstration database.

Ensure you are logged in as an administrator User.

From the Tools menu, select Web, Test Web Services.

On the Connect page, enter the URL of the Web Services to access, E.g.

NOTE: The Web Services URL will always end with /Api/.

Click the Ping button to test that the Web Services are available.

All going well, you should see a message like this:

Page 14: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 14 of 72

o NOTE: Ping is one of the few Web Services that do not require authentication.

Now you can connect to the Web Services by specifying details of the user to connect as. The User Type determines how you connect.

o Note that connecting as a finPOWER Connect User or a Client requires the Id and Secret Key of a Web Subscriber to connect as.

o If you have the finPOWER Connect Web Services database loaded, you can add a new

Web Subscriber record (if required) as follows:

From the Tools menu, select Web, Web Subscribers.

Click the Add button and enter the following:

Code: TEST

Name: Test Web Services

Click the Save button.

Close the Web Subscribers form.

o If you do not have the finPOWER Connect Web Services database, you will need to

contact the database administrator and ask them to set up a Web Subscriber record for you to use and to supply you with the Web Subscriber Id and Secret Key.

Page 15: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 15 of 72

Web Administrator

Connecting as a Web Administrator requires only the Web Administration User Id and Password. By default these are:

o User Id: webadmin

o Password: password

NOTE: The Web Administrator role is for use in the Web Services Administration facility and would not generally be used by external applications.

Page 16: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 16 of 72

User

Connecting as a finPOWER Connect User requires both the User Id and Password and also

the Id and Secret Key of a Web Subscriber to connect as.

If you have the Web Services database open, you can select the Subscriber from the

dropdown. If not, you will need to be enter the details manually in the Subscriber dropdown and Secret Key fields.

Enter the credentials of a finPOWER Connect User, E.g.

o User Id: admin

o Password: admin

NOTE: The User must have been granted Web Access. This is configured via the Web

Access page on the Users form (Tools, User Security, Users).

Page 17: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 17 of 72

Client

Connecting as a finPOWER Connect Client requires both the Client Id and Password and also

the Id and Secret Key of a Web Subscriber to connect as.

If you have the Web Services database open, you can select the Subscriber from the

dropdown. If not, you will need to be enter the details manually in the Subscriber dropdown and Secret Key fields.

Enter the credentials of a finPOWER Connect Client, E.g.

o Client Id: C10000

o Password: Password1

NOTE: The Client must have been granted Web Access. This is configured via the Web

Access page on the Clients form (Client, Clients).

Page 18: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 18 of 72

Signing In

After entering the Web Administrator/ User/ Client details, click the Connect button to sign in.

You should see a message similar to this:

And a green box will appear in the top-right corner of the form to show that you have

connected successfully:

o If signing in was unsuccessful, you will see a message such as:

Click OK and switch to the Web Services tab.

Click the Response tab.

The response should contain an XML error message which should help you determine

why signing in failed. The following example has removed attributes on the Error tag

for clarity):

Page 19: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 19 of 72

Using the Web Services Test Form Now that you have successfully connected to the Web Services, you can test any Web Service or view online help as follows.

Switch to the Web Services tab.

Locate and select the Web Service to test in the explorer.

o You can use the Quick Search box above the explorer to filter Web Services.

The Help tab allows you to view the selected Web Service's help.

The Request and Response pages allows you to view the information sent to and received from the Web Services.

For example:

o Type Client Accounts into the Quick Search box.

o Select the Client, GetAccounts Web Service.

o A list of parameters that this Web Service accepts is displayed along with help for the

Web Service, E.g.

o Enter any parameters, E.g.

Client Id: C10000

Include Quote: checked

o Click the Test button.

o The Response tab will automatically be selected and the results of the test will be

displayed, E.g.

Page 20: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 20 of 72

By default, the response will be retrieved as XML. This can be changed from the Connect

page by changing the Format to JSON.

Page 21: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 21 of 72

Programming Languages You may develop your application in the programming language of your choice, on the

platform of your choice. The majority of the code samples throughout this document however use Visual Basic (VB.NET).

Most finPOWER Connect Web Services allow you to use either XML or JSON for transferring data.

NOTE: No formal XML or JSON schemas are defined and the XML/ JSON responses may be

extended over time hence any parsing code should assume that the response may contain

additional nodes/ properties in the future.

Microsoft .NET Microsoft .NET programming languages (Visual Basic and C#) allow the response returned

from a Web Service to be parsed in different ways, E.g., you may wish to parse an XML

response using an XmlDocument object or you could use .NET's built-in deserialisation to automatically convert the XML (or JSON) into a simple .NET object.

The following are Visual Basic code examples of parsing an XML error response of:

Parsing using the XmlDocument

Private Sub ParseXml(xml As String)

Dim Document As System.Xml.XmlDocument

Dim Node1 As System.Xml.XmlNode

Dim Node2 As System.Xml.XmlNode

Dim Message As String

Dim Code As String

Dim InternalMessage As String

' Load XML Document

Document = New System.Xml.XmlDocument()

Document.LoadXml(xml)

' Get Root <Error> node

Node1 = Document.SelectSingleNode("//Error")

' Get properties

Node2 = Node1.SelectSingleNode("Message")

If Node2 IsNot Nothing Then Message = Node2.InnerText

Node2 = Node1.SelectSingleNode("Code")

If Node2 IsNot Nothing Then Code = Node2.InnerText

Node2 = Node1.SelectSingleNode("InternalMessage")

If Node2 IsNot Nothing Then InternalMessage = Node2.InnerText

End Sub

Deserialisation into a .NET Object

Private Sub ParseXml(xml As String)

Dim ErrorDetails As WSErrorDetails

Dim ms As System.IO.MemoryStream

Dim Obj As Object

Dim XmlSerializer As Serialization.XmlSerializer

Page 22: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 22 of 72

' Deserialise

Try

' Create Serialiser

XmlSerializer = New Serialization.XmlSerializer(GetType(WSErrorDetails))

' Deserialise

ms = New System.IO.MemoryStream(Encoding.UTF8.GetBytes(xml))

ErrorDetails = DirectCast(XmlSerializer.Deserialize(ms), WSErrorDetails)

Catch ex As Exception

' Failed

Finally

If ms IsNot Nothing Then ms.Close(): ms.Dispose()

End Try

End Sub

<Xml.Serialization.XmlType("Error")>

Public Class WSErrorDetails

Public Message As String

Public Code As String

Public InternalMessage As String

End Class

A more comprehensive example of deserialisation is given in the Deserialisation section.

Page 23: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 23 of 72

Authenticating (Signing In) This section details the authentication process.

Most Web Service require that a special 'Session Token' is included in an HTTP header. This

Session Token is generated during the authentication process, itself a Web Service, and is valid for 24 hours.

Web Roles A different authentication service is used depending on the type of user that you are signing in

as. The type of user defines a 'Web Role' which determines which services can be used.

The Web Roles are:

User (a finPOWER Connect User)

Client (a finPOWER Connect Client)

WebAdmin (the Web Services Administrator)

You will only ever use User or Client since WebAdmin is used internally for administering Web

Services.

Web Subscribers For an application to use Web Services, that application must first have a Web Subscriber record defined in finPOWER Connect.

Web Subscribers are maintained in finPOWER Connect from the Tools menu, Web, Web

Subscribers.

Each Subscriber is given a unique Subscriber Id and also a Secret Key which are used during the authentication process.

If successful, the authentication service returns a Session Token. This is tied to the Web

Subscriber's Secret Key therefore, if the Web Subscriber's Secret Key is changed (via the Web Subscribers form), the Session Token will immediately become invalid.

The Authentication Process When authenticating, the Subscriber's Secret Key is never sent across the network. It is used to produce a Hash which is sent with the authentication request.

An example URL to authenticate a finPOWER Connect User is shown below:

/Api/Authentication/AuthenticateUser?subscriberId=CC&userId=Admin&password=admin&hash=Faawwodidux5zIuG

%2Fe1vR8wpCVxV0aoKijjyucKbo14%3D&hashSalt=YXBIGIMHKJ

The subscriberId, userId and password parameters are self-explanatory. The hash and hashSalt are explained in the next section.

hashSalt

The hashSalt parameter is simply a string of 10 random letters. The following Visual Basic code

sample forms a random string.

Rnd = New Random(CInt(Now.Ticks Mod Int32.MaxValue))

hashSalt = ""

For i = 1 To 10

hashSalt &= Chr(65 + Rnd.Next(0, 25))

Next

Page 24: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 24 of 72

hash

The hash parameter is an SHA256 hash produced by concatenating the Hash Salt, User Id,

Password and the Web Subscriber's Secret Key. The following pseudo code shows the process

of creating the hash:

s = hashSalt & userId & password & secretKey

hash = Sha256(s)

hash = Base64Encode(hash)

Authentication Code Sample

The following is a Visual Basic code example of signing in as a finPOWER Connect User. It

demonstrates how to create the Hash required by the authentication service and how to send a request to the Web Services.

The resultant Session Token can then be used for performing authenticated requests.

The ExecuteRequest and CreateHash functions are taken directly from the Web Forms examples in the /Samples folder of the Web Services application.

' Connection Constants

Const WEB_SERVICES_URL As String = "http://localhost/finPOWERConnectWS2/Api/"

Const WEB_SUBSCRIBER_ID As String = "CC"

Const WEB_SUBSCRIBER_SECRET_KEY As String = "1F673CE613414"

Const USER_ID As String = "admin"

Const USER_PASSWORD As String = "admin"

Public Sub Test()

Dim Document As System.Xml.XmlDocument

Dim ErrorMessage As String

Dim Hash As String

Dim HashSalt As String

Dim Node1 As System.Xml.XmlNode

Dim Nodes As System.Xml.XmlNodeList

Dim Ok As Boolean

Dim RequestUrl As String

Dim ResponseText As String

Dim SessionToken As String

Dim StatusCode As Integer

' Assume Success

Ok = True

' Initialise

Document = New System.Xml.XmlDocument()

' --------------------------------------------------

' Connect to Web Services as a finPOWER Connect User

' --------------------------------------------------

If Ok Then

' Produce a hash (and a random hash salt) of the User Id and Password

Hash = HashSha256(USER_ID & USER_PASSWORD, WEB_SUBSCRIBER_SECRET_KEY, HashSalt)

' Build Request URL

RequestUrl = WEB_SERVICES_URL

RequestUrl &= String.Format("Authentication/AuthenticateUser?subscriberId={0}&userId={1}&passwor

d={2}&hash={3}&hashSalt={4}", Server.UrlEncode(WEB_SUBSCRIBER_ID), Server.UrlEncode(USER_ID), Server

.UrlEncode(USER_PASSWORD), Server.UrlEncode(Hash), Server.UrlEncode(HashSalt))

' Execute Request

Ok = ExecuteRequest(RequestUrl, "GET", "XML", "",

Nothing, "", ResponseText, StatusCode, ErrorMessage, Nothing) AndAlso StatusCode = HttpStatusCode.OK

' Parse Response

If Ok Then

' Parse Response to retrieve Session Token

Document.LoadXml(ResponseText)

SessionToken = Document.SelectSingleNode("//SessionDetails/SessionToken").InnerText

End If

End If

' Error

If Not Ok Then

Page 25: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 25 of 72

' If ResponseText contains <Error>, this can be parsed as an XML document

End If

End Sub

''' <summary>

''' Execute a Request (sending either nothing, text or binary data in the form of a Byte array) to

retrieve either a text or binary (Byte array) Response.

''' </summary>

''' <param name="requestUrl">

''' The Request URL.

''' </param>

''' <param name="httpMethod">

''' The HTTP Method, E.g., GET or POST.

''' </param>

''' <param name="contentType">

''' The Content Type for the HTTP Content-Type header or just 'XML' or 'JSON'.

''' </param>

''' <param name="requestText">

''' The Request Text or a blank String if not sending any text in the body of the request or if

sending binary data using the requestBytes parameter.

''' </param>

''' <param name="requestBytes">

''' The Request Bytes or Nothing if not sending binary data to the request.

''' </param>

''' <param name="sessionToken">

''' The Session Token or a blank String is using a unauthenticated Web Service.

''' </param>

''' <param name="responseText">

''' The Response Text. This will be Nothing if the content type of the Response did not indicate

that this was a text response, i.e., it did not begin 'text'.

''' </param>

''' <param name="responseBytes">

''' The binary Response. This will be Nothing if the content type of the Response indicates a text

response.

''' </param>

''' <param name="statusCode">

''' The HTTP Status Code received.

''' </param>

''' <param name="errorMessage">

''' An Error Message. This will only by populated if this function returns False.

''' </param>

''' <param name="response">

''' The Response object. May be useful for debugging purposes.

''' </param>

''' <returns>

''' A Boolean value indicating success.

''' </returns>

''' <remarks>

''' NOTE: This is a sample only and matches the function used in the Web Services Test form within

finPOWER Connect. This sample may be subject to updating at any time.

''' </remarks>

Private Function ExecuteRequest(requestUrl As String,

httpMethod As String,

contentType As String,

requestText As String,

requestBytes() As Byte,

sessionToken As String,

ByRef responseText As String,

ByRef responseBytes() As Byte,

ByRef statusCode As Integer,

ByRef errorMessage As String,

ByRef response As System.Net.HttpWebResponse) As Boolean

Dim Buffer(1023) As Byte

Dim Bytes As Integer

Dim Encoding As System.Text.UTF8Encoding

Dim Ok As Boolean

Dim MemoryStream As System.IO.MemoryStream

Dim Request As System.Net.HttpWebRequest

Dim Stream As System.IO.Stream

Dim srText As System.IO.StreamReader

' Assume Success

Ok = True

' Initialise ByRef Parameters

responseText = ""

responseBytes = Nothing

statusCode = 0

errorMessage = ""

Page 26: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 26 of 72

response = Nothing

' Initialise

Select Case UCase(contentType)

Case "JSON" : contentType = "application/json"

Case "XML" : contentType = "text/xml"

End Select

' Create Web Request

Try

Request = DirectCast(System.Net.WebRequest.Create(requestUrl), System.Net.HttpWebRequest)

With Request

' General

.Method = httpMethod

.ContentType = contentType

.Timeout = 20000 ' 20 Seconds

' Add authorisation header

If Len(sessionToken) <> 0 Then

.Headers.Add("Authorization", String.Format("AuthFinWs token=""{0}""", sessionToken))

End If

' Write Request Body

If Len(requestText) = 0 AndAlso requestBytes Is Nothing Then

' None

.ContentLength = 0

Else

' Text/ Binary

Try

' Encode Text as UTF8

If Len(requestText) <> 0 Then

.ContentType &= "; charset=UTF-8"

Encoding = New System.Text.UTF8Encoding()

requestBytes = Encoding.GetBytes(requestText)

End If

' Content Length

.ContentLength = requestBytes.Length

' Content

Stream = .GetRequestStream()

Stream.Write(requestBytes, 0, requestBytes.Length)

Catch ex As Exception

Ok = False

errorMessage = ex.Message

Finally

If Stream IsNot Nothing Then

Stream.Close()

Stream.Dispose()

End If

End Try

End If

End With

Catch ex As Exception

Ok = False

errorMessage = ex.Message

End Try

' Send Request and get Response

Try

Response = DirectCast(Request.GetResponse(), System.Net.HttpWebResponse)

Catch ex As System.Net.WebException

' Not all exceptions should be treated as errors

If ex.Response Is Nothing OrElse Not (TypeOf ex.Response Is System.Net.HttpWebResponse) Then

Ok = False

errorMessage = ex.Message

Else

' Valid Response received

response = DirectCast(ex.Response, System.Net.HttpWebResponse)

End If

Catch ex As Exception

Ok = False

errorMessage = ex.Message

End Try

' Get Response details

If Ok AndAlso response IsNot Nothing Then

' Response (as both a Byte array and Text to cater for both situations)

If response.ContentLength = 0 Then

' No Response Content

responseText = ""

Page 27: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 27 of 72

ReDim responseBytes(0)

Else

' Get either Text or Binary Response

If response.ContentType.StartsWith("text", StringComparison.OrdinalIgnoreCase) OrElse

InStr(response.ContentType, "/json", CompareMethod.Text) <> 0 Then

' Text

srText = New System.IO.StreamReader(response.GetResponseStream())

responseText = srText.ReadToEnd()

srText.Close()

Else

' Binary

MemoryStream = New System.IO.MemoryStream()

Stream = response.GetResponseStream()

Do

Bytes = Stream.Read(Buffer, 0, 1023)

If Bytes > 0 Then MemoryStream.Write(Buffer, 0, Bytes)

Loop While Bytes > 0

responseBytes = MemoryStream.ToArray()

End If

End If

' Status Code

statusCode = CInt(response.StatusCode)

End If

Return Ok

End Function

Public Function HashSha256(value As String,

key As String,

ByRef salt As String) As String

Dim HashBytes As Byte()

Dim i As Integer

Dim rnd As Random

Dim SaltValueKeyBytes As Byte()

Dim Sha256 As System.Security.Cryptography.SHA256

' Generate Salt (could just as easily be passed in but this will generate a random one regardless)

rnd = New Random(CInt(Now.Ticks Mod Int32.MaxValue))

salt = ""

For i = 1 To 10

salt &= Chr(65 + rnd.Next(0, 25))

Next

' Convert Salt+Value+Key into a byte array

SaltValueKeyBytes = System.Text.Encoding.UTF8.GetBytes(salt & value & key)

' Hash

Sha256 = New System.Security.Cryptography.SHA256Managed()

HashBytes = Sha256.ComputeHash(SaltValueKeyBytes)

' Base-64 encode

Return System.Convert.ToBase64String(HashBytes)

End Function

Authentication Response

Both the Authentication/AuthenticateClient and Authentication/AuthenticateUser services return a Session Details response, both of which include a Session Token, E.g.

Page 28: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 28 of 72

Supplying the Session Token with a Request

The Session Token returned when authenticating (signing in) must be supplied with all authenticated requests (i.e., just about anything other than Ping).

In a typical Web application, the Session Token might be stored in Session state.

The Authentication Code Sample above demonstrated issuing an authenticated request to

retrieve a list of a Client's Accounts. The authenticated request included a special HTTP

Authorization header, E.g.:

GET http://localhost/finPOWERConnectWS2/Api/Client/GetAccounts?clientId=C10000

Content-Type: text/xml

Authorization: AuthFinWs token="0fb1121adfPi6BcHo48oIgTWMo9+ZA==:rW5lqC5"

The token= portion of the header specifies the Session Token (this has been truncated for clarity).

When to Re-Authenticate

As mentioned above, authenticating (signing in), returns a Session Token that must be sent

with any request that requires authentication.

The Session Token is valid for 24 hours, after which, supplying it with a request will fail.

Therefore, you may wish to consider the following scenarios and solutions:

Never re-authenticate

o When the User (or Client) first signs in, store the Session Token in Session State.

Typically, for financial applications, Session State on a Web Server is set to a short period, E.g., 20 minutes of inactivity.

o Therefore, if you are sure that a User is never going to be continuously connected to your Web application for more than 24 hours, this approach is suitable.

o This is the method the Client Connect sample uses.

Re-authenticate a User/ Client after a set period

o If a User (or Client) is likely to remain signed in to your Web application for more than 24 hours, you may wish to re-authenticate after a set period, E.g., every 12 hours.

o When the User (or Client) first signs in, store the Session Token together with the

authentication time and the User (or Client's) Id and Password in Session State.

NOTE: If using out-of-process Session State, you may wish to encrypt this information

as a precaution.

o Prior to performing a Web Service request, check if the Session Token is more than 12

hours old and, if so, re-authenticate using the Id and Password stored in Session State. Update the Session Token and authentication time held in Session State.

Ad-hoc access, i.e., no User or Client is signed in

o If your Web application has no concept of a User (or Client) signing in, E.g., an

application that provides a loan application form on a public Website, you will need to

store the credentials of a finPOWER Connect User somewhere in your application. You will then need to do one of the following:

Page 29: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 29 of 72

Re-authenticate prior to performing a Web Service request. This provides a new Session Token that you never need to store.

NOTE: This approach may bloat the finPOWER Connect audit log.

When first performing a Web Service request, authenticate and store the Session Token together with the authentication time in Application State.

Prior to performing a Web Service request, check if the Session Token is more than

12 hours old and, if so, re-authenticate and update the Session Token and

authentication time held in Application State.

Page 30: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 30 of 72

Dates Web Service dates use the ISO 8601 standard regardless of whether the date is passed as part of a request URL or is included in an XML or JSON response.

Web Services return dates in UTC (Coordinated Universal Time) regardless of how they are

stored within the finPOWER Connect database or displayed in the finPOWER Connect Windows interface.

WARNING: Any dates provided as parameters to Web Services will be parsed according to the

time zone on the Web Server. Therefore, it is advisable to always provide dates in UTC format.

Dates are covered in detail in the Dates topic of the Web Services API reference.

Page 31: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 31 of 72

Custom Web Services Custom Web Services are implemented via finPOWER Connect Scripts.

Although General, Summary Page (version 2) and Web Summary Page type Scripts can all be

used as custom Web Services, this section will concentrate on Web Service (Web API) type Scripts.

This section is a basic tutorial on how to create and use a custom Web Service.

Overview Custom Web Services can be written where either there is no Web Service currently available

to perform a specific task or, a totally custom task is required, E.g., creating a Quote Account

using custom information entered on a Web page (as per the CustomLoanQuote1VB.aspx sample detailed in the Visual Basic Code Examples section).

NOTE: Always check with Intersoft Systems before choosing to write a custom Web Service if

the task you want to perform could be considered standard finPOWER Connect functionality.

Page 32: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 32 of 72

Creating a Custom Web Service Script This section outlines the steps required to create a simple custom Web Service Script.

Open finPOWER Connect.

Open the database being used by the Web Services.

From the Admin menu, select Scripts.

Click the Add button.

Give the Script an Code and Description, E.g.:

o Code: TESTWS

NOTE: By default, the Script's code is the name of the custom Web Service and

should therefore contain only alphanumeric characters (this can be overridden on the Web page of the Scripts form).

o Description: Custom Web Service Test

Specify a Script Type of Web Service (Web API).

On the Script Code page, click the Paste template Script code button.

Click the Save button to save the Script.

Page 33: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 33 of 72

Calling the Custom Web Service The custom Web Service created above can now be called just like any other Web Service using the special Custom controller, E.g.:

http://localhost/finPOWERConnectWS2/Api/Custom/TESTWS

In this case, a Script named TESTWS will be called or, if a Script has a Web Service Name of

'TESTWS' defined on the Web page of the Scripts form in finPOWER Connect, this Script will be

called (i.e., the Script's code is used by default but can be overridden by specifying a Web Service Name).

By default, you must have already authenticated and therefore include the Authorization HTTP header as detailed in The Authentication Process section.

WARNING: The Web page of the Scripts form has a checkbox to 'Allow Anonymous access'.

Use this option with extreme caution since it allows your custom Web Service to be called

without having first authenticated.

You can test your custom Web Service from the Test Web Services form in finPOWER Connect as follows:

Connect to the Web Services from the Connect page as detailed in the Setting up a Test Environment section.

Switch to the Web Services page.

Select the Custom, ExecuteGet node in the Web Services explorer.

Enter the Id of your Script, E.g., TESTWS

Click the Test button.

o You should see a Response of:

Switch to the Connect page and change the Format to JSON.

Switch to the Web Services page and click the Test button again.

o You should now see a Response of:

NOTE: Custom Web Services can be called using either the 'GET' or 'POST' HTTP methods via

the ExecuteGet and ExecutePost nodes in the Web Services explorer.

GET-based Web Services receive all of their parameters from the URL; POST-based services

can receive parameters from the URL and also from the 'Posted' RequestText, E.g., the

RequestText might be XML formatted Client information.

Page 34: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 34 of 72

Accepting Parameters We will now update the custom Web Service to accept parameters.

The Script will be updated to accept a ClientId parameter and will return the Client's name together with a list of all their aliases (Akas).

Update your custom Web Service Script code to the following:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim ErrorCode As String

Dim ErrorStatusCode As HttpStatusCode

Dim Ok As Boolean

Dim Client As finClient

Dim ClientAka As finClientAka

Dim ClientDetails As clsClientDetails

Dim ClientId As String

' Assume Success

Ok = True

' Initialise

ErrorStatusCode = HttpStatusCode.BadRequest

' Get Parameters

ClientId = request.Parameters.GetString("ClientId")

' Load Client

Client = finBL.CreateClient()

If Client.Load(ClientId) Then

' Create and update Client Details

ClientDetails = New clsClientDetails()

ClientDetails.Name = Client.Name

' List AKAs

For Each ClientAka In Client.Akas

ClientDetails.Akas.Add(ClientAka.NameFull)

Next

Else

Ok = False

End If

' Response

If Ok Then

Return request.CreateResponse(HttpStatusCode.OK, ClientDetails)

End If

' Error

If Not Ok Then

Return request.CreateErrorResponse(ErrorStatusCode, "Failed to get Client name details.",

ErrorCode, finBL.Error.Message(True, True))

End If

End Function

<System.Xml.Serialization.XmlType("ClientDetails")>

Public Class clsClientDetails

Public Name As String

Public Akas As New List(Of String)

End Class

We will now test the updated service using the Test Web Service form.

Select the Custom, Execute (GET) node in the Web Services explorer.

Enter the Id of your Script, E.g., TESTWS

In the Parameters field, enter clientId=C10000.

o Parameters must be URL encoded and separated by a '&', E.g., if you had two parameters, you would specify them as param1=value1&param2=value2

Click the Test button.

Page 35: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 35 of 72

o You should see a Response similar to:

Switch to the Connect page and change the Format to JSON.

Switch to the Web Services page and click the Test button again.

o You should now see a Response similar to:

NOTE: As of version 2.02.01 of finPOWER Connect, Custom Web Service Scripts can define

Parameters which are then used by the Test Web Service form when selecting the Custom, Execute (Parameters) node in the Web Services explorer.

This provides a more user-friendly way of testing Custom Web Services that use Parameters.

In the above example, adding a Text or Range parameter named 'ClientId' to the Script would

allow the Custom Web Service to be tested in this way.

Page 36: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 36 of 72

Controlling the Response Note that in the above example, the XML response has a root node of <ClientDetails>. This

is because we applied an XmlType attribute to the clsClientDetails class. Without this, the

root node will have been named <clsClientDetails>.

Also, because we have declared the Akas property as a List(Of String), we do not have any

control over how this is serialised. Using a custom collection would allow more control.

Our custom Web Service switches automatically between XML and JSON serialisation due to the way we are returning the response as an object, i.e.:

Return request.CreateResponse(HttpStatusCode.OK, ClientDetails)

Alternatively, to return an error response:

Return request.CreateErrorResponse(ErrorStatusCode, "Failed to add Client.", ErrorCode,

finBL.Error.Message(True, True))

For most services, this is probably desirable but, using the various 'Create' methods of the

request object we can force the response to be a particular format as follows:

HTML Response

CreateHtmlResponse allows us to force the response to be HTML, E.g.

Return request.CreateHtmlResponse(HttpStatusCode.OK, "<h1>This is HTML</h1>")

This simply sets the HTTP Content-Type header to text/html.

JSON Response

CreateJsonResponse allows us to force the response to be JSON, E.g.

Return request.CreateJsonResponse(HttpStatusCode.OK, "{FirstName: "John", LastName: "Smith"}")

This simply sets the HTTP Content-Type header to application/json.

Text Response

CreateTextResponse allows us to force the response to be plain text, E.g.

Return request.CreateTextResponse(HttpStatusCode.OK, Account.AccountId)

This simply sets the HTTP Content-Type header to text/plain.

NOTE: If a Web Service is designed to return only a very simple value, E.g., the Id of an

Account, returning it as plain text means that any calling applications do not need to parse

XML or JSON and therefore simplifies the code.

XML Response

CreateXmlResponse allows us to force the response to be XML, E.g.

Return request.CreateXmlResponse(HttpStatusCode.OK, Branch.ToXmlString())

This simply sets the HTTP Content-Type header to text/xml.

PDF Response

CreatePdfResponse and CreatePdfResponseFromHtml allows us to force the response to be PDF document, E.g.

Page 37: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 37 of 72

Return request.CreatePdfResponseFromHtml(HttpStatusCode.OK, "<h1>My PDF document</h1>")

Or:

Dim PdfData() As Byte

If finBL.PdfUtilities.CreatePdfByteArrayFromHtml("<h1>My PDF document</h1>", PdfData) Then

Return request.CreatePdfResponse(HttpStatusCode.Ok, PdfData)

Else

' Error

End If

This sets the HTTP content to the binary PDF data and sets the Content-Type header to

application/pdf.

See the PDF Documents section for more information.

Page 38: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 38 of 72

Accepting Posted Data Sometimes, you may wish to simply POST data directly to a custom Web Service, E.g., an XML document created from an external application.

The following Script will accept a POSTed piece of XML in the following format and create a

Transaction for an Account. It will not return anything, just an HTTP Status code of 200 if successful:

<AccountPayment>

<AccountId>L10035</AccountId>

<Amount>35.00</Amount>

<Reference>REF</Reference>

</AccountPayment>

Update your custom Web Service's Script code to the following:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim ErrorCode As String

Dim ErrorStatusCode As HttpStatusCode

Dim Ok As Boolean

Dim AccountPayment As finAccountPayment

Dim AccountPaymentDetails As clsAccountPaymentDetails

Dim Obj As Object

' Assume Success

Ok = True

' Initialise

ErrorStatusCode = HttpStatusCode.BadRequest

' Parse XML (use business layer helper Function)

If finBL.Runtime.WebUtilities.DeserialiseXmlStringToObject(request.RequestText,

GetType(clsAccountPaymentDetails), Obj) Then

AccountPaymentDetails = DirectCast(Obj, clsAccountPaymentDetails)

Else

Ok = False

End If

' Add Account Payment

If Ok Then

AccountPayment = finBL.CreateAccountPayment()

With AccountPayment

' Load Account

Ok = .AccountLoad(AccountPaymentDetails.AccountId)

' Update

If Ok Then

.TransactionTypeId = "PAY"

.PaymentMethodId = "CASHR"

.PaymentValue = AccountPaymentDetails.Amount

.TransactionReference = AccountPaymentDetails.Reference

End If

' Commit

If Ok Then

Ok = .ExecuteCommit()

End If

End With

End If

' Response

If Ok Then

Return request.CreateResponse(HttpStatusCode.OK)

End If

' Error

If Not Ok Then

Return request.CreateErrorResponse(ErrorStatusCode, "Failed to make Account payment.",

ErrorCode, finBL.Error.Message(True, True))

End If

End Function

<System.Xml.Serialization.XmlType("AccountPayment")>

Page 39: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 39 of 72

Public Class clsAccountPaymentDetails

Public AccountId As String

Public Amount As Decimal

Public Reference As String

End Class

We will now test the updated service using the Test Web Service form.

Select the Custom, Execute (POST) node in the Web Services explorer.

Enter the Id of your Script, E.g., TESTWS

In the Request Text field, past the XML shown at the start of this section.

Click the Test button.

o You should receive a Response that contains nothing, just an HTTP Status code of 200.

The Deserialising the Request and Parsing Posted XML Request sections cover handling Posted

data in more detail.

Page 40: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 40 of 72

Serialising the Response As shown in some of the previous samples in this section, serialisation to either XML or JSON is handled automatically by the Web API and the .NET framework.

This section has examples of automatic serialisation of the Response from Script objects.

WARNING: Never attempt to return built-in finPOWER Connect business layer objects from a

Custom Web Service. These objects are not designed for serialisation.

NOTE: Many of the examples in this section remove the following attributes from the response's root XML node for clarity:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"

Page 41: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 41 of 72

Nullable Types

.NET nullable types are not used within the finPOWER Connect business layer however, they can, and often should, be used when returning the results of a Web Service.

For instance if you attempt to return an object that has a Date property, E.g., DateOfBirth,

and this does not have a value, it will be returned as 0001-01-01T00:00:00 since the .NET

Date type cannot have no value (within .NET, the Date = Nothing assignment and comparison

is actually assigning and comparing the date with 0001-01-01T00:00:00).

For example, the following Script:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim ClientDetails As ClientDetails

' Create Object

ClientDetails = New ClientDetails()

With ClientDetails

.Name = "Paul"

End With

' Return

Return request.CreateResponse(HttpStatusCode.OK, ClientDetails)

End Function

Public Class ClientDetails

Public Name As String

Public DateOfBirth As Date

End Class

Returns:

<ClientDetails>

<Name>Paul</Name>

<DateOfBirth>0001-01-01T00:00:00</DateOfBirth>

</ClientDetails>

If this is modified to use a nullable data type, E.g.:

Public Class ClientDetails

Public Name As String

Public DateOfBirth As Date?

End Class

The response is much more intuitive:

<ClientDetails>

<Name>Paul</Name>

<DateOfBirth xsi:nil="true" />

</ClientDetails>

Nullable types would typically be used for the following:

Dates

o Only where the date is optional, E.g., a Date of Birth.

Numeric types, E.g., Decimal, Double and Integer

o Only where returning zero does not make sense.

Boolean values

o Only where returning True or False does not make sense.

Page 42: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 42 of 72

NOTE: Strings cannot be nullable since the String data type in the .NET framework is an object

and only value types can be nullable.

WARNING: Returning nullable types does add an extra level of complexity to the application

having to parse the XML and you should consider not including the elements in the response at

all as described in the Preventing Properties From Being Serialised section.

Page 43: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 43 of 72

Dates

Dates are serialised using the ISO 8601 standard as detailed in the Dates section.

All built-in Web Services return dates containing a time portion in UTC format, regardless of how they are stored within finPOWER Connect.

Unless you have a requirement to explicitly ignore this rule, all dates containing a time portion

that are returned from a Custom Web Service, E.g., Log dates, should be returned as UTC dates.

WARNING: .NET Dates have a Kind property which may affect how the date is serialised.

Therefore, when setting dates on objects that are to be serialised, it is important to bear this in

mind, E.g., if Kind is DateTimeKind.Local, serialising a date containing a time portion may

not produce the result you expect, E.g., the date may be converted to a UTC date when this is not expected.

When testing a Custom Web Service, if dates and times are involved, ensure that you test the

service on a Web Server running in the time zone that the production server will be using to

ensure there are no unforeseen issues.

finPOWER Connect contains business layer functionality to convert a dates to nullable, UTC format dates, E.g.:

' Create Object

ClientDetails = New ClientDetails()

With ClientDetails

.Name = Client.Name

.DateOfBirth = finBL.Runtime.DateUtilities.CastToNullableUtcDate(Client.DateOfBirth)

If LastLog IsNot Nothing Then

.LastLogDate = finBL.ToUniversalTime(LastLog.Date)

End If

End With

Produces the following response:

<ClientDetails>

<Name>Smith, John</Name>

<DateOfBirth>1978-02-04T00:00:00Z</DateOfBirth>

<LastLogDate>2014-08-07T03:26:11Z</LastLogDate>

</ClientDetails>

Note that both dates are returned as UTC dates even though the Date of Birth does not contain

a time portion.

The following helper functions are available in finPOWER Connect business layer:

finBL.ToUniversalTime(value)

o Converts a date recorded in local time (as Log dates are in finPOWER Connect 2) to UTC time.

o The time will be adjusted from local time to UTC time.

finBL.Runtime.DateUtilities

o CastToNullableUtcDate(value)

Casts a date containing no time portion (E.g., a Date of Birth) to a nullable UTC date.

If the Date = Nothing then this will be handled correctly.

Any time portion is removed.

o CastToNullableUtcDateTime(value)

Casts a date, optionally containing a time portion to a nullable UTC date.

If the Date = Nothing then this will be handled correctly.

Page 44: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 44 of 72

Does not 'convert' the date to UTC, i.e., no time adjustment is made so this is not suitable for converting local dates to UTC dates.

Page 45: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 45 of 72

Enums

Enums are serialised as String values, E.g., isefinAccountStatus.ClosedPending is

serialised to 'ClosedPending' using a method such as finAccount.Status.ToString().

finPOWER Connect generally has an Enum value, E.g., isefinAccountStatus.ClosedPending

and also a display value, E.g., 'Closed (Pending)'. This is not the same as the serialised

version of the Enum ('ClosedPending') although often the two are the same.

WARNING: Do not confuse the finPOWER Connect display value for the Enum which is

achieved via methods such as finBL.Enums.isefinAccountStatus_ToString() methods.

These methods are used for displaying Enum values in a user-readable form, E.g., including

spaces or varying the display value based upon the database country.

When returning an object that contains an Enum value, it may be desirable to return both the

Enum and the display value. Typically, the property holding the display value is named the same as the Enum value property but with a 'Text' suffix, E.g.:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim Account As finAccount

Dim AccountDetails As AccountDetails

' Load (ignore errors for simplicity)

Account = finBL.CreateAccount()

Account.Load("L10000")

' Create Object

AccountDetails = New AccountDetails()

With AccountDetails

.Name = Account.Name

.Status = Account.Status

.StatusText = Account.StatusText

End With

' Return

Return request.CreateResponse(HttpStatusCode.OK, AccountDetails)

End Function

Public Class AccountDetails

Public Name As String

Public Status As isefinAccountStatus

Public StatusText As String

End Class

Produces the following response:

<AccountDetails>

<Name>Smith, John</Name>

<Status>ClosedPending</Status>

<StatusText>Closed (Pending)</StatusText>

</AccountDetails>

Page 46: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 46 of 72

Using Attributes to Tweak Serialisation

You may wish to serialise classes using an XML element named differently from the class name.

This is achieved by applying the XmlType or XmlRoot attributes to the class, E.g.:

<System.Xml.Serialization.XmlType("Transaction")>

Public Class finwsAccountTransaction

' Properties

Public [Date] As Date

Public ElementId As String

Public Reference As String

Public Value As Decimal

End Class

< System.Xml.Serialization.XmlRoot("Transactions")>

Public Class finwsAccountTransactions : Inherits List(Of finwsAccountTransaction)

End Class

< System.Xml.Serialization.XmlType("AvailableCredit")>

Public Class finwsAccountAvailableCreditDetails

Public AvailableCredit1 As Decimal

Public AvailableCredit2 As Decimal

Public AvailableCredit3 As Decimal

Public CreditLimit1 As Decimal

Public CreditLimit2 As Decimal

Public CreditLimit3 As Decimal

End Class

NOTE: Both of these attributes work in a similar way in that they determine the name of the

XML element containing their properties.

Page 47: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 47 of 72

Preventing Properties From Being Serialised

Sometimes, you may wish to define properties on your object but not have them serialised under certain circumstances.

For example, you may have a ClientDetails class that contains properties that should only

be serialised for 'Individual' type Clients, E.g., DateOfBirth.

NOTE: These ShouldSerialize methods are applied when serialising as XML or JSON and are

built-in to the .NET framework.

The method MUST be named after the property name, E.g., to control whether a DateOfBirth

property is serialised, you must have a method named ShouldSerializeDateOfBirth() that

returns a Boolean value.

Also note the U.S. spelling of the word 'serialize'.

The following example shows how to achieve this using special ShouldSerialize methods

which are used by the .NET serialisation process to decide whether or not to serialise a property:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim Client As finClient

Dim ClientDetails As ClientDetails

' Load (ignore errors for simplicity)

Client = finBL.CreateClient()

Client.Load("C10000")

' Create Object

ClientDetails = New ClientDetails(Client)

With ClientDetails

.Name = Client.Name

.DateOfBirth = finBL.Runtime.DateUtilities.CastToNullableUtcDate(Client.DateOfBirth)

.OrganisationNumber = Client.OrganisationNumber

End With

' Return

Return request.CreateResponse(HttpStatusCode.OK, ClientDetails)

End Function

Public Class ClientDetails

' Properties

Public Name As String

Public DateOfBirth As Date?

Public OrganisationNumber As String

' Other

Private mClient As finClient

Public Sub New(client As finClient)

mClient = client

End Sub

Public Sub New()

End Sub

' Prevent Serialisation for Not Applicable Properties

Public Function ShouldSerializeDateOfBirth() As Boolean

Return mClient Is Nothing OrElse mClient.IsIndividual OrElse mClient.IsSoleTrader

End Function

Public Function ShouldSerializeOrganisationNumber() As Boolean

Return mClient Is Nothing OrElse mClient.IsOrganisation

End Function

End Class

Page 48: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 48 of 72

Produces the following response for an 'Individual' Client:

<ClientDetails>

<Name>Smith, John</Name>

<DateOfBirth>1978-02-04T00:00:00Z</DateOfBirth>

</ClientDetails>

And the following response for an 'Organisation' Client:

<ClientDetails>

<Name>Company Limited</Name>

<OrganisationNumber>1234567890</OrganisationNumber>

</ClientDetails>

WARNING: Serialisable classes must always have an empty, public constructor which is why the above example has two constructors.

This is also why the test mClient Is Nothing is performed since theoretically, a

ClientDetails object could be created without passing in a finClient object.

Page 49: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 49 of 72

Serialising Collections

All of the above examples have dealt with serialising a single-level object.

The following example shows how to return a collection object:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim Account As finAccount

Dim AccountTransaction As finAccountTransaction

Dim AccountDetails As AccountDetails

Dim Transaction As Transaction

' Load (ignore errors for simplicity)

Account = finBL.CreateAccount()

Account.Load("L10000")

' Create Object

AccountDetails = New AccountDetails()

With AccountDetails

.AccountId = Account.AccountId

.Name = Account.Name

.Transactions = New List(Of Transaction)

End With

' Add Transactions

For Each AccountTransaction In Account.Transactions

' Create

Transaction = New Transaction()

' Update

With AccountTransaction

Transaction.Date = finBL.Runtime.DateUtilities.CastToUtcDate(.Date)

Transaction.ElementId = .ElementId

Transaction.Value = .Value

End With

' Add to Collection

AccountDetails.Transactions.Add(Transaction)

Next

' Return

Return request.CreateResponse(HttpStatusCode.OK, AccountDetails)

End Function

Public Class AccountDetails

Public AccountId As String

Public Name As String

Public Transactions As List(Of Transaction)

End Class

Public Class Transaction

Public [Date] As Date

Public ElementId As String

Public Value As Decimal

End Class

Produces the following response:

<AccountDetails>

<AccountId>L10000</AccountId>

<Name>Smith, John</Name>

<Transactions>

<Transaction>

<Date>2014-06-08T00:00:00Z</Date>

<ElementId>ADV</ElementId>

<Value>10000</Value>

</Transaction>

<Transaction>

<Date>2014-06-09T00:00:00Z</Date>

<ElementId>ACCF</ElementId>

<Value>123</Value>

</Transaction>

Page 50: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 50 of 72

<Transaction>

<Date>2014-07-09T00:00:00Z</Date>

<ElementId>ACCF</ElementId>

<Value>2.22</Value>

</Transaction>

<Transaction>

<Date>2014-07-09T00:00:00Z</Date>

<ElementId>PAY</ElementId>

<Value>-4.22</Value>

</Transaction>

</Transactions>

</AccountDetails>

Page 51: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 51 of 72

Deserialising the Request As shown in the Accepting Posted Data section, it is often desirable to deserialise XML posted to the Custom Web Service into an object that the Script can use.

WARNING: Deserialisation is useful for small, flat objects or simple collections. For complex

XML it may be more suitable to parse the posted XML directly.

The finPOWER Connect business layer provides functionality to deserialise XML into an object as shown in the following example:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim ErrorCode As String

Dim ErrorStatusCode As HttpStatusCode

Dim Ok As Boolean

Dim Client As finClient

Dim ClientDetails As ClientDetails

Dim Obj As Object

' Assume Success

Ok = True

' Initialise

ErrorStatusCode = HttpStatusCode.BadRequest

' Parse XML (use business layer helper Function)

If finBL.Runtime.WebUtilities.DeserialiseXmlStringToObject(request.RequestText,

GetType(ClientDetails), Obj) Then

ClientDetails = DirectCast(Obj, ClientDetails)

Else

Ok = False

End If

' Add Client

If Ok Then

Client = finBL.CreateClient()

With Client

' Update

.FirstName = ClientDetails.FirstName

.LastName = ClientDetails.LastName

.DateOfBirth = ClientDetails.DateOfBirth

' Save

Ok = .Save()

End With

End If

' Return Response

If Ok Then

Return request.CreateResponse(HttpStatusCode.OK, Client.ClientId)

Else

Return request.CreateErrorResponse(ErrorStatusCode, "Failed to add Client.", ErrorCode,

finBL.Error.Message(True, True))

End If

End Function

Public Class ClientDetails

Public FirstName As String

Public LastName As String

Public DateOfBirth As Date

End Class

The following XML can be posted to the above Script:

<ClientDetails>

<FirstName>Paul</FirstName>

<LastName>Jones</LastName>

<DateOfBirth>1986-03-17</DateOfBirth>

</ClientDetails>

Page 52: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 52 of 72

Points of note in the above example are:

Use of the DeserialiseXmlStringToObject() helper method.

o Internally, this uses the .NET framework's deserialisation functionality.

ClientDetails.DateOfBirth is defined as a date.

o This means that if the XML omits this tag, the property will remain as the default value

for a Date which equals Nothing, therefore there is no special handling required.

o This is a Date with no time portion hence there is no need to convert from a UTC date.

o Supplying an empty DateOfBirth element in the XML, E.g.:

<DateOfBirth/>

Will cause a deserialisation error. Either omit the element completely or use the following

format:

<ClientDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<FirstName>Paul</FirstName>

<LastName>Jones</LastName>

<DateOfBirth xsi:nil="true" />

</ClientDetails>

And change the DateOfBirth property to a nullable type:

Public Class ClientDetails

Public FirstName As String

Public LastName As String

Public DateOfBirth As Date?

End Class

And handle accordingly when updating the finClient object, E.g.:

If ClientDetails.DateOfBirth IsNot Nothing Then

.DateOfBirth = CDate(ClientDetails.DateOfBirth)

End If

Page 53: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 53 of 72

Testing Posted XML

Testing a Custom Web Service that accepts posted XML can be achieved from the Test Web Services form.

Simply paste a sample of the XML into the 'Request Text' field, E.g.:

Page 54: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 54 of 72

Enums

Enums are included in XML using their String representation, E.g.,

isefinAccountStatus.ClosedPending would be serialised using a method such as

finAccount.Status.ToString(). This would produce a value of 'ClosedPending'.

WARNING: Do not confuse this with the finPOWER Connect display value for the Enum which

is achieved via methods such as finBL.Enums.isefinAccountStatus_ToString() methods.

These methods are used for displaying Enum values in a user-readable form, E.g., including

spaces or varying the display value based upon the database country.

Deserialisation of Enums is handed internally by the .NET framework however, it is not

recommended that you use nullable types for Enums since this complicates the deserialisation

process. Therefore, do not include an Enum tag in the XML if it is not required.

Page 55: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 55 of 72

Using Attributes to Tweak Deserialisation

By default, XML will be deserialised into properties that match the XML element names.

This can be tweaked using attributes, E.g.:

<System.Xml.Serialization.XmlType("TransactionBatch")>

Public Class clsTransactionBatch

Public BatchId As String

Public TransactionType As String

Public Transactions As List(Of clsTransaction)

End Class

<System.Xml.Serialization.XmlType("Transaction")>

Public Class clsTransaction

Public AccountId As String

Public [Date] As Date

Public Reference As String

Public ElementId As String

Public Value As Decimal

End Class

Page 56: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 56 of 72

Deserialising Collections

Collections can also be deserialied as shown in the following example which creates a Batch of Transactions and saves and then commits the Batch:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim Batch As finBatch

Dim BatchTransaction As finBatchTransaction

Dim ErrorCode As String

Dim ErrorStatusCode As HttpStatusCode

Dim Obj As Object

Dim Ok As Boolean

Dim Transaction As clsTransaction

Dim TransactionBatch As clsTransactionBatch

' Assume Success

Ok = True

' Initialise

ErrorStatusCode = HttpStatusCode.BadRequest

' Deserialise the XML to an Object

If finBL.Runtime.WebUtilities.DeserialiseXmlStringToObject(request.RequestText,

GetType(clsTransactionBatch), Obj) Then

TransactionBatch = DirectCast(Obj, clsTransactionBatch)

Else

Ok = False

End If

If Ok Then

' Initialise

Batch = finBL.CreateBatch()

' Setup Batch

With Batch

.BatchId = TransactionBatch.BatchId

.TransactionTypeId = TransactionBatch.TransactionType

.SourceSet(isefinTransactionSource.ExternalA)

End With

' Add Transactions

For Each Transaction In TransactionBatch.Transactions

' Create

BatchTransaction = Batch.Transactions.CreateBatchTransaction()

' Update (ignore errors for simplicity of sample)

With BatchTransaction

.AccountIdSet(Transaction.AccountId)

.ElementIdSet(Transaction.ElementId)

.Date = Transaction.Date

.Value = Transaction.Value

.Reference = Transaction.Reference

End With

' Add

Batch.Transactions.Add(BatchTransaction)

Next

' Save Batch

Ok = Batch.Save()

' Commit Batch

If Ok Then

Ok = Batch.ExecuteCommit(False)

End If

End If

' Return Response

If Ok Then

Return request.CreateResponse(HttpStatusCode.OK)

Else

Return request.CreateErrorResponse(ErrorStatusCode, String.Format("Failed to execute custom Web

Service Script '{0}'.", ScriptInfo.ScriptId), ErrorCode, finBL.Error.Message(True, True))

End If

End Function

<System.Xml.Serialization.XmlType("TransactionBatch")>

Page 57: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 57 of 72

Public Class clsTransactionBatch

Public BatchId As String

Public TransactionType As String

Public Transactions As List(Of clsTransaction)

End Class

<System.Xml.Serialization.XmlType("Transaction")>

Public Class clsTransaction

Public AccountId As String

Public [Date] As Date

Public Reference As String

Public ElementId As String

Public Value As Decimal

End Class

The following XML can be posted to the above Script:

<TransactionBatch>

<BatchId>WSBatch001</BatchId>

<TransactionType>PAY</TransactionType>

<Transactions>

<Transaction>

<AccountId>L10000</AccountId>

<Date>2014-08-07</Date>

<Reference>Reference 1</Reference>

<ElementId>PAY</ElementId>

<Value>100.00</Value>

</Transaction>

<Transaction>

<AccountId>L10035</AccountId>

<Date>2014-08-08</Date>

<Reference>Reference 2</Reference>

<ElementId>PAY</ElementId>

<Value>42.50</Value>

</Transaction>

</Transactions>

</TransactionBatch>

Points of note in the above example are:

Use of the DeserialiseXmlStringToObject() helper method.

o Internally, this uses the .NET framework's deserialisation functionality.

o This deserialises the <Transactions> block in to the Transactions property which is

defined as a List(Of clsTransaction).

Attributes (E.g., <System.Xml.Serialization.XmlType("Transaction")>) are used to

map the class names, E.g., clsTrasaction to an XML element name, E.g., Transaction.

Page 58: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 58 of 72

Troubleshooting Deserialisation Issues

Problems can arise when attempting to deserialise XML into an object and these are often hard to track.

The DeserialiseXmlStringToObject() method will return False if deserialisation failed. This

may be due to the following:

The XML being deserialised was invalid.

Dates or numbers within the XML are invalid.

o E.g., Date values are not in the ISO 8601 format.

ISO 8601: 2014-08-16

Non-standard format: 8/16/2014

Dates or numbers elements in the XML are empty.

o Even if the property on the object that the element is being serialised into is a nullable type, including an empty element will still produce an error unless the xsi:nil="true"

attribute is applied as described in the 'Date of Birth' example at the end of the Deserialising the Request section.

Additionally, if the property name in the object does not exactly match the XML element name (this is case-sensitive), the property will not be populated during the deserialisation process.

Page 59: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 59 of 72

Parsing Posted XML Request Parsing the posted XML request manually may be a better option than deserialising it if:

The XML is complex, E.g., many levels of nesting.

You want more control than the deserialisation process can provide, E.g.:

o The XML has different versions, E.g., a 'version' attribute on the root node affects how the XML should be parsed.

o The XML contains dates not formatted according to the ISO 8601 standard.

This may be the case if the supplied XML is in a legacy format of comes from a source that you do not have control over.

The finPOWER Connect business layer has helper methods to assist in the parsing of XML.

The following example shows how to manually parse the XML used in Deserialising Collections sample:

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim Batch As finBatch

Dim BatchTransaction As finBatchTransaction

Dim ErrorCode As String

Dim ErrorStatusCode As HttpStatusCode

Dim Ok As Boolean

Dim XmlDocument As XmlDocument

Dim Node As XmlNode

Dim Nodes As XmlNodeList

' Assume Success

Ok = True

' Initialise

ErrorStatusCode = HttpStatusCode.BadRequest

' Parse XML

With finBL.Runtime.XmlUtilities

' Load XML Document

If .LoadXmlDocumentFromString(request.RequestText, XmlDocument) Then

' Initialise

Batch = finBL.CreateBatch()

' Get Root Node

Node = XmlDocument.SelectSingleNode("TransactionBatch")

If Node Is Nothing Then

Ok = False

finBL.Error.ErrorBegin("TransactionBatch node not found.")

End If

' Setup Batch

If Ok Then

Batch.BatchId = .GetSubNodeString(Node, "BatchId")

Batch.TransactionTypeId = .GetSubNodeString(Node, "TransactionType")

Batch.SourceSet(isefinTransactionSource.ExternalA)

End If

' Transactions

If Ok Then

Nodes = Node.SelectNodes("Transactions/Transaction")

For Each Node In Nodes

' Create

BatchTransaction = Batch.Transactions.CreateBatchTransaction()

' Update (ignore errors for simplicity of sample)

BatchTransaction.AccountIdSet(.GetSubNodeString(Node, "AccountId"))

BatchTransaction.ElementIdSet(.GetSubNodeString(Node, "ElementId"))

BatchTransaction.Date = .GetSubNodeDate(Node, "Date")

BatchTransaction.Value = .GetSubNodeDecimal(Node, "Value")

BatchTransaction.Reference = .GetSubNodeString(Node, "Reference")

' Add

Batch.Transactions.Add(BatchTransaction)

Next

Page 60: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 60 of 72

End If

' Save Batch

If Ok Then

Ok = Batch.Save()

End If

' Commit Batch

If Ok Then

Ok = Batch.ExecuteCommit(False)

End If

Else

Ok = False

End If

End With

' Return Response

If Ok Then

Return request.CreateResponse(HttpStatusCode.OK)

Else

Return request.CreateErrorResponse(ErrorStatusCode, String.Format("Failed to execute custom Web

Service Script '{0}'.", ScriptInfo.ScriptId), ErrorCode, finBL.Error.Message(True, True))

End If

End Function

Points of note in the above example are:

Use of the finBL.Runtime.XmlUtilities helper methods to load and parse XML.

Page 61: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 61 of 72

Serialising and Deserialising XML Some programming languages support serialisation and deserialisation of XML from and to an object.

In many cases, this can make parsing a response (or forming a request) easier than dealing directly with XML.

NOTE: This section is intended for external applications consuming the Web Services. For

Custom Web Service Scripts, see the Serialising the Response and Deserialising the Request

sections.

In the Custom Web Services section, the finPOWER Connect business layer was used to

serialise a response to XML (or JSON). This section gives code samples of both serialisation and deserialisation.

Serialisation/ Deserialisation can be used with complex objects and collections (E.g., objects

that contain other objects). A Google search will provide many examples of how to achieve this.

Serialisation Serialisation is the process of taking an object and automatically creating an XML String that

represents that object.

The following examples will all serialise the simple ClientDetails object detailed below into XML:

ClientDetails

ClientId (String)

FirstName (String)

LastName (String)

DateOfBirth (Date)

Each of the code samples contains a SerialiseObjectToXmlString function which returns a

Boolean value based upon whether it was successful or not. If unsuccessful, an error message

is returned instead of the XML.

Page 62: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 62 of 72

Visual Basic

Public Sub Main()

Dim ClientDetails As clsClientDetails

Dim Xml As String

' Create Object

ClientDetails = New clsClientDetails()

With ClientDetails

.ClientId = "C10000"

.FirstName = "John"

.LastName = "Smith"

.DateOfBirth = New Date(1970, 9, 5)

End With

' Serialise

If SerialiseObjectToXmlString(ClientDetails, Xml) Then

MsgBox(Xml)

Else

MsgBox(Xml, MsgBoxStyle.Exclamation)

End If

End Sub

Public Function SerialiseObjectToXmlString(obj As Object, ByRef xml As String) As Boolean

Dim ms As System.IO.MemoryStream

Dim Ok As Boolean

Dim XmlSerializer As System.Xml.Serialization.XmlSerializer

' Assume Success

Ok = True

' Initialise ByRef Parameters

xml = ""

' Serialise

Try

XmlSerializer = New System.Xml.Serialization.XmlSerializer(obj.GetType())

ms = New System.IO.MemoryStream()

XmlSerializer.Serialize(ms, obj)

xml = System.Text.Encoding.UTF8.GetString(ms.GetBuffer(), 0, CInt(ms.Length))

ms.Close()

Catch ex As Exception

' Failed (return error message instead of XML)

Ok = False

xml = ex.Message

Finally

If ms IsNot Nothing Then ms.Dispose()

End Try

Return Ok

End Function

<System.Xml.Serialization.XmlType("ClientDetails")>

Public Class clsClientDetails

Public ClientId As String

Public FirstName As String

Public LastName As String

Public DateOfBirth As Date

End Class

Page 63: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 63 of 72

C#

public void Main()

{

clsClientDetails ClientDetails;

string Xml = "";

// Create Object

ClientDetails = new clsClientDetails {

ClientId = "C10000",

FirstName = "John",

LastName = "Smith",

DateOfBirth = new DateTime(1970, 9, 5)

};

// Serialise

if(SerialiseObjectToXmlString(ClientDetails, ref Xml)) {

System.Windows.Forms.MessageBox.Show(Xml);

}

else {

System.Windows.Forms.MessageBox.Show(Xml, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);

}

}

public bool SerialiseObjectToXmlString(Object obj, ref string xml)

{

System.IO.MemoryStream ms = null;

bool Ok;

System.Xml.Serialization.XmlSerializer XmlSerializer;

// Assume Success

Ok = true;

// Initialise ByRef Parameters

xml = "";

// Serialise

try {

XmlSerializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());

ms = new System.IO.MemoryStream();

XmlSerializer.Serialize(ms, obj);

xml = System.Text.Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length);

ms.Close();

}

catch(Exception ex) {

// Failed (return error message instead of XML)

Ok = false;

xml = ex.Message;

}

finally {

if(ms != null) ms.Dispose();

}

return Ok;

}

[System.Xml.Serialization.XmlType("ClientDetails")]

public class clsClientDetails {

public string ClientId;

public string FirstName;

public string LastName;

public DateTime DateOfBirth;

}

Page 64: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 64 of 72

Deserialisation Deserialisation is the process of taking an XML String and automatically creating and populating an object from the content of the XML.

The following examples will deserialise the following XML into the simple ClientDetails object

used in the previous section.

<ClientDetails>

<ClientId>C10000</ClientId>

<FirstName>John</FirstName>

<LastName>Smith</LastName>

<DateOfBirth>1970-09-05T00:00:00</DateOfBirth>

</ClientDetails>

Each of the code samples contains a DeserialiseObjectFromXmlString function which

returns a Boolean value based upon whether it was successful or not. If unsuccessful, an error message is returned instead of the deserialised object.

Page 65: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 65 of 72

Visual Basic

Public Sub Main()

Dim ClientDetails As clsClientDetails

Dim tempObject As Object

Dim Xml As String

' Define XML

Xml &= "<ClientDetails>"

Xml &= "<ClientId>C10000</ClientId>"

Xml &= "<FirstName>John</FirstName>"

Xml &= "<LastName>Smith</LastName>"

Xml &= "<DateOfBirth>1970-09-05T00:00:00</DateOfBirth>"

Xml &= "</ClientDetails>"

' Deserialise into Object

If DeserialiseXmlStringToObject(Xml, GetType(clsClientDetails), tempObject) Then

ClientDetails = DirectCast(tempObject, clsClientDetails)

MsgBox("Deserialised ClientId=" & ClientDetails.ClientId)

Else

MsgBox(CStr(tempObject), MsgBoxStyle.Exclamation)

End If

End Sub

Public Function DeserialiseXmlStringToObject(xml As String, objType As Type, ByRef obj As Object) As

Boolean

Dim ms As System.IO.MemoryStream

Dim Ok As Boolean

Dim XmlSerializer As System.Xml.Serialization.XmlSerializer

' Assume Success

Ok = True

' Initialise ByRef Parameters

obj = Nothing

' Deserialise

Try

' Create Serialiser

XmlSerializer = New System.Xml.Serialization.XmlSerializer(objType)

' Deserialise

ms = New System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml))

obj = XmlSerializer.Deserialize(ms)

ms.Close()

Catch ex As Exception

Ok = False

obj = ex.Message

Finally

If ms IsNot Nothing Then ms.Dispose()

End Try

Return Ok

End Function

<System.Xml.Serialization.XmlType("ClientDetails")>

Public Class clsClientDetails

Public ClientId As String

Public FirstName As String

Public LastName As String

Public DateOfBirth As Date

End Class

Page 66: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 66 of 72

C#

public void Main(object sender, EventArgs e)

{

clsClientDetails ClientDetails;

Object tempObject = null;

string Xml;

// Define XML

Xml = "";

Xml += "<ClientDetails>";

Xml += "<ClientId>C10000</ClientId>";

Xml += "<FirstName>John</FirstName>";

Xml += "<LastName>Smith</LastName>";

Xml += "<DateOfBirth>1970-09-05T00:00:00</DateOfBirth>";

Xml += "</ClientDetails>";

// Deserialise into Object

if(DeserialiseXmlStringToObject(Xml, typeof(clsClientDetails), ref tempObject))

{

ClientDetails = (clsClientDetails)tempObject;

System.Windows.Forms.MessageBox.Show("Deserialised ClientId=" + ClientDetails.ClientId);

}

else

{

System.Windows.Forms.MessageBox.Show((string)tempObject, "Error", MessageBoxButtons.OK,

MessageBoxIcon.Warning);

}

}

bool DeserialiseXmlStringToObject(string xml, Type objType, ref Object obj)

{

System.IO.MemoryStream ms = null;

bool Ok;

System.Xml.Serialization.XmlSerializer XmlSerializer;

// Assume Success

Ok = true;

// Initialise ByRef Parameters

obj = null;

// Deserialise

try

{

// Create Serialiser

XmlSerializer = new System.Xml.Serialization.XmlSerializer(objType);

// Deserialise

ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml));

obj = XmlSerializer.Deserialize(ms);

ms.Close();

}

catch (Exception ex)

{

Ok = false;

obj = ex.Message;

}

finally

{

if (ms != null) ms.Dispose();

}

return Ok;

}

[System.Xml.Serialization.XmlType("ClientDetails")]

public class clsClientDetails {

public string ClientId;

public string FirstName;

public string LastName;

public DateTime DateOfBirth;

}

Page 67: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 67 of 72

PDF Documents Web Service functionality exists to convert HTML to a PDF document.

NOTE: finPOWER Connect uses an external component to convert HTML to a PDF document

therefore the formatting is outside of the control of Intersoft Systems.

Returning a PDF Document from a Custom Web Service Custom Web Services can return a Response representing a PDF document using either the request.CreatePdfResponseFromHtml or request.CreatePdfResponse methods.

The following example returns a simple PDF document:

Option Explicit On

Option Strict On

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim ErrorCode As String

Dim ErrorStatusCode As HttpStatusCode

Dim Ok As Boolean

' Assume Success

Ok = True

' Initialise

ErrorStatusCode = HttpStatusCode.BadRequest

' Return Response

If Ok Then

Return request.CreatePdfResponseFromHtml(HttpStatusCode.OK, "<h1>My PDF document</h1>.")

Else

Return request.CreateErrorResponse(ErrorStatusCode, String.Format("Failed to execute custom Web

Service Script '{0}'.", ScriptInfo.ScriptId), ErrorCode, finBL.Error.Message())

End If

End Function

This returns the PDF file content as binary data. The following is a sample response with the

majority of the HTTP body stripped out since it is meaningless:

HTTP/1.1 200 OK

Content-Length: 2401

Content-Type: application/pdf

Date: Wed, 04 Jun 2014 00:29:48 GMT

Expires: -1

Server: Microsoft-IIS/8.0

X-AspNet-Version: 4.0.30319

X-Powered-By: ASP.NET

%PDF-1.5

%���� %Created by EVO PDF Tools v3.5

Note that the Content Type header specifies application/pdf.

A consumer of this Web Service could then retrieve the response data as am array of bytes and either write it to a file or stream it to the user's Web browser.

Page 68: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 68 of 72

Returning a Response Containing a PDF Document Data from a Custom Web Service In the previous section, a custom Web Service was used to return a PDF document. The

response from the custom Web Service was a complete PDF document and contained no other information.

In certain situations, it may be desirable to return the PDF document as part of a more

complex response, E.g., an XML response containing a <PdfDocument> node.

The following example returns a resonse containing Base 64 encoded PDF data. This can then be decoded by the Web Service consumer and written to a PDF file:

Option Explicit On

Option Strict On

Public Function Main(request As finwsHttpRequest) As finwsHttpResponse

Dim ErrorCode As String

Dim ErrorStatusCode As HttpStatusCode

Dim Ok As Boolean

Dim PdfDetails As PdfDetails

Dim PdfDocumentBase64 As String

' Assume Success

Ok = True

' Initialise

ErrorStatusCode = HttpStatusCode.BadRequest

' Create PDF Document from HTML

Ok = finBL.PdfUtilities.CreatePdfBase64StringFromHtml("<h1>My PDF Document</h1>",

PdfDocumentBase64)

' Create PDF Details

If Ok Then

PdfDetails = New PdfDetails()

With PdfDetails

.Title = "PDF Title"

.PdfDocument = PdfDocumentBase64

End With

End If

' Return Response

If Ok Then

' Return PDF Details

Return request.CreateResponse(HttpStatusCode.OK, PdfDetails)

Else

' Error

Return request.CreateErrorResponse(ErrorStatusCode, String.Format("Failed to execute custom Web

Service Script '{0}'.", ScriptInfo.ScriptId), ErrorCode, finBL.Error.Message())

End If

End Function

Public Class PdfDetails

Public Title As String

Public PdfDocument As String

End Class

Since this Script returns an object (PdfDetails), it will automatically be serialised as either XML or JSON as per the following (stripped down) responses:

<PdfDetails>

<Title>PDF Title</Title>

<PdfDocument>JVBERi0xLjUNCiWxsrO0DQolQ3JlYXRlZCBieSBFVk8gUERGIFRvb2xzIHYzLjUNCjEgMCBvYmoNCjw8DQovUGF

nZXMgMiAwIFINCi9QYWdlTGF5b3V0IC9PbmVDb2x1bW4NCi9QYWdlTW9kZSAvVXNlTm9uZQ0KL1ZpZXdlclByZWZlcmVuY2VzIDM

gMCBSDQovVHlwZSAvQ2F0YWxvZw0KPj4NCg0KZW5kb2JqDQo2IDAgb2JqDQo8PA0KL0ZpbHRlciAvRmxhdGVEZWNvZGUNCi9MZW5

ndGggMTMzDQo+Pg0Kc3RyZWFt</PdfDocument>

</PdfDetails>

Page 69: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 69 of 72

{"Title":"PDF Title",

"PdfDocument":"JVBERi0xLjUNCiWxsrO0DQolQ3JlYXRlZCBieSBFVk8gUERGIFRvb2xzIHYzLjUNCjEgMCBvYmoNCjw8DQovU

GFnZXMgMiAwIFINCi9QYWdlTGF5b3V0IC9PbmVDb2x1bW4NCi9QYWdlTW9kZSAvVXNlTm9uZQ0KL1ZpZXdlclByZWZlcmVuY2VzI

DMgMCBSDQovVHlwZSAvQ2F0YWxvZw0KPj4NCg0KZW5kb2JqDQo2IDAgb2JqDQo8PA0KL0ZpbHRlciAvRmxhdGVEZWNvZGUNCi9MZ

W5ndGggMTMyDQo+Pg0Kc3RyZWFt"}

Formatting PDF Documents finPOWER Connect contains functionality to convert HTML into a PDF via the finBL.PdfUtilities class.

When creating PDF documents from HTML, note the following:

The PDF file is generated on the Web Server on which the Web Services are running and can therefore only access any fonts available on this Server.

o You may wish to use safe fonts such as:

Arial

Times New Roman

Verdana

Any images you wish to include in the PDF, E.g., company logos should be referenced via a URL that can be resolved by the Web Server.

You do not have the same amount of control over the document that is produced as you would using a Word processing package such as Microsoft Word.

By default, the HTML is formatted as if displayed in a browser window that is 1024 pixels

wide.

o This can be changed via the ViewportWidth meta tag detailed below.

The following meta tags can be included at the top of the HTML to tweak that PDF file that is produced:

<meta name='pdf-PageSize' content='A4'/>

<meta name='pdf-PageOrientation' content='Portrait'/>

<meta name='pdf-LeftMargin' content='1.5cm'/>

<meta name='pdf-RightMargin' content='1cm'/>

<meta name='pdf-TopMargin' content='1.5cm'/>

<meta name='pdf-BottomMargin' content='2.54cm'/>

<meta name='pdf-ViewportWidth' content='1200'/>

PageSize

o One of the following: A4, A5, Legal, Letter

PageOrientation

o Either Portrait or Landscape

LeftMargin, RightMargin, TopMargin, BottomMargin

o Can be specified in the following units: cm, inches (if omitted, points are assumed)

ViewportWidth

o This defaults to 1024 but specifying a different value will vary how the PDF is generated, E.g., how much information fits on a line.

By changing this value, the HTML text may scale to a different size so for consistency,

it may be best to not set the ViewportWidth but to change the font size in the HTML using CSS.

Page 70: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 70 of 72

Visual Basic Code Examples Visual Basic code examples are included in the /Samples folder of the Web Services. All of these samples are ASP.NET Web Forms and therefore contain a .aspx and a .aspx.vb file.

The following table lists these samples:

Sample Description Other Details

ConnectUser1VB.aspx Connect as a finPOWER Connect User and retrieve a list of Client Accounts.

CustomLoanQuote1VB.aspx

Enter simple Loan and Client details and use a custom Web Service to create a Quote Account and a Client.

Script CustomLoanQuote1VB.xml must be imported into finPOWER Connect.

To use get these samples up and running:

Create a new empty Web Application in Visual Studio 2012 (or Visual Studio Express 2012 for Web).

o Keep the default project name of WebApplication1.

The sample .aspx files reference a namespace of WebApplication1 so doing this saves having to modify the samples' .aspx portion.

Copy the entire contents of the Web Services /Samples folder into the new Web Application.

o Include all files (except for any .xml files) in the Web Application project.

Ensure you have a Web Subscriber record set up in finPOWER Connect.

o In finPOWER Connect, open the database that the Web Services are connected to.

o From the Tools menu, select Web and then Web Subscribers.

o Add a new Web Subscriber record with the following details:

Code: TEST

Description: Test Web Subscriber

View the .vb portion of all sample pages and update the following constants to allow connection to the Web Services:

o WEB_SERVICES_URL

o WEB_SUBSCRIBER_ID

o WEB_SUBSCRIBER_SECRET_KEY

Run the Web Application and ensure that the ConnectUser1VB.aspx page runs correctly.

o This is the simplest example, therefore ensure this runs correctly before attempting to run any other examples.

Some samples may require a custom Web Service Script.

Page 71: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 71 of 72

o The following samples require that their corresponding .xml file is imported into the finPOWER Connect Scripts library:

CustomLoanQuote1VB.aspx

o To import the Script, do the following:

In finPOWER Connect, open the database that the Web Services are connected to.

From the Admin menu, select Scripts.

Use the Import action to import the .xml file.

Save the Script.

Page 72: finPOWER Connect 2 Web Services Connectivity … Connect Web...Services Connectivity and Programming Guide.doc finPOWER Connect 2 Web Services Connectivity and Programming Guide Version

Page 72 of 72

Troubleshooting

Timeout when Authenticating Client A timeout error when attempting to authenticate a Client via the

Authentication/AuthenticateClient service may be due to the following:

Misconfigured Address Database

If the Address database being used by the finPOWER Connect business layer is not available, attempting to connect to it may cause a time out.

This may be an issue when attempting to authenticate as a Client since the response from this

service includes formatted Branch address details which involves accessing the Addressing

interface which will always attempt to initialise a connection to the Address database when first accessed.