Using the jxAPI With C#.NET 3.x
This page is about the legacy SOAP-based jxAPI that is no longer updated or recommended for use in new projects. The documentation in this section may be outdated or inaccurate, and is provided for reference purposes only.
Journyx recommends using the REST-based API for new projects in most cases. However, at the current time, there are certain object types that are not available through the REST API.
Note: For .NET versions prior to 3.0, see Using the jxAPI With C#.NET 2.x for instructions.
Requirements
- A Journyx installation, version 8.8 or newer
- Visual Studio 2008
- Windows XP SP2
- .NET Framework 3.0-3.5
For versions of Journyx prior to 8.8, you must use the RPC/encoded SOAP endpoint, which uses the older .NET 2.x style of web reference. See Using the RPC/Encoded SOAP Endpoint With C#.NET 3.x for additional instructions.
Preparing Your C# Project
To use the jxAPI in a C# project, you must add a Service Reference, disable Expect-100-continue headers, and adjust the XML reader name table size in your application's configuration. These steps are described below.
To add a service reference to the jxAPI, select Project -> Add Service Reference from the menu. In the dialog box that appears, enter the URL of the jxAPI document/literal wrapped WSDL in the Address box, and click Go. The URL of the WSDL is of the form:
https://<hostname>:<port>/jtime/jxapi_wsi.wsdl
For example:
https://customer-name.apps.journyx.com/jtime/jxapi_wsi.wsdl
After Visual Studio loads the WSDL, the "Services" box of the dialog will show that it has found the "jxapi" service. Next, enter a name for the reference in the "Namespace" field, and click "OK". The reference will appear in the "Service References" subtree of the Solution Explorer.
To disable expect-100-continue headers, which are not supported by the Journyx server, include the following code near the beginning of your application:
System.Net.ServicePointManager.Expect100Continue = false;
Due to the complexity of the jxAPI, it will usually be necessary to adjust your
application's configuration to increase the XML reader name table size. Open
the app.config
file from the Solution Explorer, search for
maxNameTableCharCount
in the readerQuotas
element, and edit its value
to 256000.
Connecting
The first step in using the jxAPI is to obtain an object that represents a
connection to the server. This is an object of type jxapi
inside the service
reference namespace, and it is returned by calling the service reference's
jxapiClient
function. For example, if your service reference is named
timesheet
:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
timesheet.jxapi jxapi = new timesheet.jxapiClient();
// ...
}
}
}
The connection object is a proxy for the entire jxAPI; it has methods corresponding to the methods in the jxAPI, and calls to it will be translated automatically to server operations.
Error Handling
Attempts to call jxAPI methods with improper or incomplete arguments will be
caught on the client side, often during program compilation. Errors occurring on
the server, and certain client-side protocol errors, will be reported as SOAP
faults, causing a System.Web.Services.Protocols.SoapException
exception in
your application. This single exception type may correspond to many different
kinds of server-side error, from bad passwords to data validation errors and
more. If your code catches a SoapException
, you can use its methods and
properties (Detail
, for example) to examine the error report provided by the
server.
Data Types
In the jxAPI reference documentation, data types are referred to by generic names like "string" and "number". These correspond to specific C# types as follows:
- a jxAPI "integer" is an
int
- a jxAPI "float" is a
double
- a jxAPI "string" is a
string
- a jxAPI "boolean" is a
bool
- a jxAPI "list" is an array (for example, a "list of int" is an
int[]
) - a jxAPI "record" or "structure" is a C# object
Record types are defined in the service reference namespace. For example, if
your service reference is called timesheet
, the class of time records is
timesheet.TimeRecord
.
Authentication
Nearly all parts of the jxAPI require authentication, just as using Journyx from the web interface does. Authentication in the jxAPI is session-based; your application "logs in" with a user name and password, and receives a session key which must then be passed back to the server with every method call. For example:
timesheet.jxapi jxapi = new timesheet.jxapiClient();
String skey;
skey = jxapi.login("joe", "joespass", 1);
The third parameter to the login
method determines whether to keep any
existing sessions for this user. If it is 0, all other sessions for the user,
including web logins, will be automatically invalidated; if it is 1, they will
be ignored.
With only a few exceptions, every method in the jxAPI takes the session key as a parameter. The jxAPI cannot be used to bypass Journyx's normal security model — most users can access only their own data, and only administrators have free reign.
Your application should always log out each session that it creates, by calling
the logout
method when done:
jxapi.logout(skey);
Records
Almost everything in the Journyx database is stored as records. For example, a week of time entries which appear on a single page in the web user interface may actually correspond to several records, one for each filled grid square. Each entry in the pull-down fields (project, pay type, etc.) is a record, and so is each user.
Records, and other types of structured data used by Journyx, are represented by
C# objects. The web reference that you previously generated from the server's
WSDL includes a C# class for each record type used by the jxAPI. Each of these
classes has properties corresponding to the fields described by the jxAPI. For
example, if a record has an id
attribute (as most of them do), then its C#
object will have an id
property that can be read and assigned to. The jxAPI
Reference has a full list of the fields in each type of record, and their types.
More About Records: Time Entry
Time entries are represented by a single record per grid square. A full row on a user's time sheet corresponds to up to seven records, one per day, each with the project, pay type, bill type, and comment set for that row.
The first step in creating a time record is to create a TimeRecord
object.
Simply calling new timesheet.TimeRecord
isn't usually the best way to do this;
the C# constructor creates a completely empty record, and there are several
fields that can and should be filled in with default values by the server. The
getDefaultTimeRecord
method asks the server for a fresh time record with
default values already filled in. Finally, after the rest of the record is
filled in, the addFullTimeRecord
method inserts it into the Journyx database:
timesheet.TimeRecord trec;
String id;
trec = jxapi.getDefaultTimeRecord(skey);
trec.hours = 6.0;
trec.comment = "test record";
id = jxapi.addFullTimeRecord(skey, trec);
Notice that the session key is passed as the first parameter to both jxAPI
calls. The getDefaultTimeRecord
method implicitly creates a record referring
to the current user and today's date, and addFullTimeRecord
will throw an
exception if the current user doesn't have permission to add this record (if,
for example, the user
field of the record doesn't match).
Also note that addFullTimeRecord
returns an ID. The ID of a record is a unique
key generated when the record is first added to the Journyx database. It can be
used later to delete or modify a record:
trec = jxapi.getTimeRecord(skey, id);
trec.hours = 7.0;
jxapi.modifyTimeRecord(skey, id, trec);
jxapi.removeTimeRecord(skey, id);
Other Record Types: Common Methods
The methods described above in the discussion of time entries have counterparts
for other record types in the jxAPI. For example, there is a
getDefaultExpenseRecord
, addFullExpenseRecord
, getExpenseRecord
, and so
forth, with corresponding methods for each of the core record types, including
TimeRecord
, ExpenseRecord
, User
, Project
, Code
(Task), Subcode
(Pay
Type), Subsubcode
(Bill Type), and Group
.
Project and Code Lists
If you are creating time and expense records, you probably want to fill in the
Project, Task, Pay Type, and Bill Type fields with meaningful values. (The
latter are called code
, subcode
, and subsubcode
in the TimeRecord
and
ExpenseRecord
objects for historical reasons.) The jxAPI provides several
methods to retrieve all available values for those fields:
String[] x;
x = jxapi.getProjectList(skey);
x = jxapi.getCodeList(skey);
x = jxapi.getSubcodeList(skey);
x = jxapi.getSubsubcodeList(skey);
In each case, the return value is an array of strings in which each pair of elements is the ID (to put in the corresponding field of a time or expense record) and name of a project, code, subcode, or subsubcode. Since these methods are authenticated, the returned list only includes items available to the current user.
Sheets
A time sheet represents a batch of time entries in a date range. You do not need
to explicitly create time sheets (they exist automatically based on the
timekeeping periods defined by the Journyx administrator) but you should take
them into account when creating time records. To retrieve the current user's
time sheet for a specific date, use the getTimeSheetIDByDate
method; once you
have the ID, you can manipulate it:
String id;
Double hours;
String[] a;
id = jxapi.getTimeSheetIDByDate(skey, '20051001');
hours = jxapi.getTotalHoursInTimeSheet(skey, id);
a = jxapi.getDatesInTimeSheet(skey, id);
a = jxapi.getTimeRecordIDsInSheet(skey, id);
When you add a time record, you should add it to the proper sheet; likewise, when you remove a time record, you should remove it from the sheet:
String trecid, tsid;
timesheet.TimeRecord trec;
trec = jxapi.getDefaultTimeRecord(skey);
trec.hours = 6.0;
trecid = jxapi.addFullTimeRecord(skey, trec);
tsid = jxapi.getTimeSheetIDByDate(skey, trec.date);
jxapi.addTimeRecordToSheet(skey, tsid, trecid);
jxapi.removeTimeRecordFromSheet(skey, tsid, trecid);
jxapi.removeTimeRecord(skey, trecid);
Finally, you might want to submit a time sheet and, later, check its status:
jxapi.submitTimeSheet(skey, tsid);
System.Console.WriteLine(jxapi.getTimeSheetStatus(skey, tsid));
The jxAPI also contains methods for approving and rejecting sheets, Expense and Mileage sheets, and administering approval templates. For more information on these topics, see the jxAPI Reference.
Other Features
The samples in this document show only a small part of the jxAPI's complete functionality. Most features of Journyx are accessible through the jxAPI now, or will be soon. The jxAPI Reference will contain an up-to-date list of every method and data structure it supports.
Using the RPC/Encoded SOAP Endpoint With C#.NET 3.x
Journyx versions prior to 8.8 provided only a RPC/Encoded SOAP endpoint, instead of the Document/Literal Wrapped one described here. Although the .NET 3.x WCF does not support this encoding, you can use a .NET 2.x web service binding instead. Follow the instructions in Using the jxAPI With C#.NET 2.x, except for the following changes due to differences in Visual Studio 2008:
To add a web reference, select Project -> Add Service Reference from the menu, click the Advanced... button in the first dialog, then click the Add Web Reference... button in the second dialog.
You must add the following code near the beginning of your application, before making any SOAP requests:
System.Net.ServicePointManager.Expect100Continue = false;