.Net wrapper for Clarizen API v2.0

Shortcuts:

Clarizen API: https://api.clarizen.com/V2.0/services/
Clarizen's API documentation: http://usermanual.clarizen.com/rest-api-guide
Nuget package: https://www.nuget.org/packages/Ekin.Clarizen/
Sample .Net project: Download samples.zip or browse/fork on GitHub

Getting Started

1. Install Ekin.Clarizen Nuget package

You can install the Ekin.Clarizen Nuget package in your project using the package manager in Visual Studio. The below example uses Visual Studio 2015 Community Edition, which is free of charge.




2. Test login

Next, you should test if you can use the API to log in to Clarizen. Replace the username and password below with your Clarizen username/password. 

using System;
using Ekin.Clarizen;

namespace ClarizenSamples.Authentication
{
    class Login
    {
        static Login()
        {
            API ClarizenAPI = new API();
            if (!ClarizenAPI.Login("username", "password"))
                return;

            Console.WriteLine("Login successful");
            Console.WriteLine("Server location: {0}", ClarizenAPI.serverLocation);
            Console.WriteLine("Session Id: {0}", ClarizenAPI.sessionId);

            // Your API code goes here...

            if (ClarizenAPI.Logout())
                Console.WriteLine("Logout successful. {0} API calls made in this session", ClarizenAPI.TotalAPICallsMadeInCurrentSession);
        }
    }
}

When you run the above code, you should see something like this:


If you don't see this, check your username/password.

Note that you can open a free 30-day trial account at https://www.clarizen.com/free-trial.

Code Structure

If you are familiar with the Clarizen API structure...

Clarizen_API_V2_0 follows Clarizen's API structure at https://api.clarizen.com/V2.0/services/. Namespace for the project is Ekin.Clarizen, and under that you can find namespaces for the 7 groups of endpoints:

  • Ekin.Clarizen.Authentication
  • Ekin.Clarizen.Data
  • Ekin.Clarizen.Files
  • Ekin.Clarizen.Metadata
  • Ekin.Clarizen.Applications
  • Ekin.Clarizen.Bulk
  • Ekin.Clarizen.Utils

The .Net library has (mostly) matching class names (note the differences in camelCasing) for Clarizen endpoints. For example for the https://api.clarizen.com/V2.0/services/metadata/DescribeEntities endpoint there is a .Net function Ekin.Clarizen.Metadata.describeEntities(), which takes as input Ekin.Clarizen.Metadata.Request.describeEntities and one of the outputs is Ekin.Clarizen.Metadata.Result.describeEntities. 

Two exceptions to the Namespace.endpoint name convention are CRUD operations for Data objects (/data/objects) and Metadata objects, which are (at Ekin.Clarizen.Data) objects_get, objects_put, objects_post and objects_delete, and (at Ekin.Clarizen.Metadata) objects_put, objects_delete.

The only exception to the Namespace.Request convention are Query requests, such as /data/EntityQuery, which are located in Ekin.Clarizen.Data.Queries, e.g. Ekin.Clarizen.Data.Queries.entityQuery instead of Ekin.Clarizen.Data.Queries.Request.entityQuery.

API helper class

With the .Net wrapper, you don't need to use the above structure. There is a Ekin.Clarizen.API() class that provides session and authentication management as well as bulk query execution. All of the above functions can be accessed through the API class. See the ClarizenAPI.DescribeMetadata() example below (note the Pascal case):

using System;
using Ekin.Clarizen;
using Ekin.Clarizen.Metadata;

namespace ClarizenSamples.Metadata
{
    class DescribeMetadata_Entity
    {
        static DescribeMetadata_Entity()
        {
            API ClarizenAPI = new API();
            if (!ClarizenAPI.Login("username", "password"))
                return;

            string entityName = "User";  // Could be Customer, Project, User, UserGroup, Task, DiscussionPost, etc.
            describeMetadata metadata = ClarizenAPI.DescribeMetadata(new string[] { entityName }, new string[] { "relations", "fields" });
            if (metadata.IsCalledSuccessfully)
            {
                Console.WriteLine("Fields for the {0} object:", entityName);
                metadata.Data.entityDescriptions[0].SortFields();
                foreach (fieldDescription field in metadata.Data.entityDescriptions[0].fields)
                {
                    Console.WriteLine("\t{0} ({1}) {2}", field.name, field.label, field._type);
                }
            }
            else
                Console.WriteLine(metadata.Error);

            if (ClarizenAPI.Logout())
                Console.WriteLine("{0} API calls made in this session", ClarizenAPI.TotalAPICallsMadeInCurrentSession);
        }

    }
}

The API class has the following functions:

Login(string username, string password)
Logout()
GetSessionInfo()

StartBulkService()
CommitBulkService(bool transactional = false)

GetObject(string id, string[] fields)
GetObject(string id)
CreateObject(string id, object obj)
UpdateObject(string id, object obj)
DeleteObject(string id)
CreateAndRetrieve(object entity, string[] fields)
RetrieveMultiple(Data.Request.retrieveMultiple request)
RetrieveMultiple(string[] fields, string[] ids)

ExecuteQuery(Interfaces.IClarizenQuery query)

Count(IQuery query)
EntityQuery(Data.Queries.entityQuery request)
GetAllEntities(string typeName, string[] fields)
GroupsQuery(Data.Queries.groupsQuery request)
GroupsQuery(string[] fields)
AggregateQuery(Data.Queries.aggregateQuery request)
RelationQuery(Data.Queries.relationQuery request)
NewsFeedQuery(Data.Queries.newsFeedQuery request)
NewsFeedQuery(newsFeedMode mode, string[] fields, string[] feedItemOptions, paging paging)
NewsFeedQuery(newsFeedMode mode, string[] fields)
EntityFeedQuery(Data.Queries.entityFeedQuery request)
EntityFeedQuery(string entityId, string[] fields, string[] feedItemOptions, paging paging)
EntityFeedQuery(string entityId, string[] fields)
RepliesQuery(Data.Queries.repliesQuery request)
RepliesQuery(string postId, string[] fields, string[] feedItemOptions, paging paging)
RepliesQuery(string postId, string[] fields)
ExpenseQuery(Data.Queries.expenseQuery request)
TimesheetQuery(Data.Queries.timesheetQuery request)

Search(Data.Request.search request)
Search(string q)
Search(string q, paging paging)
Search(string q, string typeName, string[] fields)
Search(string q, string typeName, string[] fields, paging paging)
CreateDiscussion(object entity, string[] relatedEntities, string[] notify, string[] topics)
CreateDiscussion(object entity, string[] relatedEntities, string[] notify)
CreateDiscussion(object entity, string[] relatedEntities)
CreateDiscussion(object entity)
CreateDiscussion(Data.Request.createDiscussion request)
Lifecycle(Data.Request.lifecycle request)
Lifecycle(string[] ids, string operation)
ChangeState(string[] ids, string state)
ExecuteCustomAction(Data.Request.executeCustomAction request)
ExecuteCustomAction(string targetId, string customAction, fieldValue[] values)
GetTemplateDescriptions(string typeName)
CreateFromTemplate(object entity, string templateName, string parentId)
GetCalendarInfo(string id)

AppLogin()
SendEmail(recipient[] recipients, string subject, string body, string relatedEntityId, Utils.Request.sendEMail.CZAccessType accessType)

GetApplicationStatus(string applicationId)
InstallApplication(string applicationId, bool autoEnable)

Download(string documentId, bool redirect)
GetUploadUrl()
Upload(Files.Request.upload request)
Upload(string documentId, fileInformation fileInformation, string uploadUrl)
Upload(string documentId, storageType storage, string url, string fileName, string subType, string extendedInfo, string uploadUrl)
UpdateImage(string entityId, string uploadUrl, bool reset)

DescribeMetadata(string[] typeNames, string[] flags)
DescribeMetadata(string[] typeNames)
DescribeMetadata()
ListEntities()
DescribeEntities(string[] typeNames)
DescribeEntityRelations(string[] typeNames)
CreateWorkflowRule(string forType, string name, string description, string triggerType, string criteria, string action_url, string action_method, string action_headers, string action_body)
CreateWorkflowRule(string forType, string name, string description, string triggerType, string criteria, action action)
CreateWorkflowRule(Metadata.Request.objects_put request)
DeleteWorkflowRule(string id)
GetSystemSettingsValues(string[] settings)
SetSystemSettingsValues(fieldValue[] settings)

Code Samples

Authentication Examples: Provides the basic calls to authenticate with the REST API, get session information and access the correct data centre where your organisation is located

CRUD & Data ExamplesProvides the calls to create, update, retrieve and delete objects in Clarizen

Query Examples: Provides the calls to query and search for objects in Clarizen

Bulk Example: Allows executing several API calls in a single round trip to the server

Utils Examples: Send an email and attach it to an object in Clarizen

Metadata Examples: Provides information about the Clarizen data model including supported entities, entity fields and data types, and relations between entities

You can get all of the samples above in samples.zip.

About the Author

Ekin Caglar
I’m a business-minded techie and I help medium-to-large organisations build complex online solutions. I've been coding since 1987 and I've been on the Internet since 1993. You can reach me at ekin@caglar.com and follow me on twitter.com/ekincaglar.

Comments