Article

Using .NET ODataCLI with DSS REST API Authentication

Jirapongse Phuriphanvichai
Developer Advocate Developer Advocate

Open Data Protocol (OData) is an open protocol introduced by Microsoft in 2007. It defines a standard way for developing and consuming HTTP-based Web service APIs. This allows users to only focus on the business logic instead of worrying about other RESTful specifications. OData provides the service document that describes how a model constructs and the metadata document that contains a complete description of the feeds, types, properties, relationships exposed by the service. Both documents are defined by using an XML language.

Currently, Datascope Select and Tick History use OData to define HTTP-based REST APIs. The service and metadata documents are available on https://selectapi.datascope.refinitiv.com/restapi/v1

This article demonstrates how to use a .NET OData CLI tool to develop a C# application to get a token from an DSS Authentication service. The application uses Visual Studio 2022 and .NET 8.0.

OData CLI

odata-cli is a .NET command line interface tool for generating strongly-typed C# and Visual Basic proxy code from a metadata document of an OData service. It generates a DataServiceContext class for the service and all strong data types defined in the service model.

Run the following command on a .NET command line interface to install OData CLI.

    	
            dotnet tool install --global Microsoft.OData.Cli
        
        
    

For example:

    	
            

C:\>dotnet tool install --global Microsoft.OData.Cli

You can invoke the tool using the following command: odata-cli

Tool 'microsoft.odata.cli' (version '0.3.1') was successfully installed.

Then, run the following command to show the odata-cli help of the generate command. 

    	
            odata-cli generate --help
        
        
    

The generate command is used to generate proxy classes for OData endpoints.

At least, the -m and -o parameters are required.

Option Description
-m <metadata-uri> The URI of the metadata document. The value must be set to a valid service document URI or a local file path.
-o <outputdir> Full path to output directory.

For example:

    	
            odata-cli generate -m "<metadata-uri>" -o "<outputdir>"
        
        
    

C# Example: Datascope Select Authentication

This section demonstrates how to use the OData CLI tool to generate classes from the OData metadata document of Datascope Select Authentication service. Then, use the generated classes to develop a C# application on Visual Studio 2022 (.NET 8.0) to get a DSS token. 

1. Create a new C# project

First, create a new C# project on Visual Studio 2022 with .NET 8.0.

The project name is ODataDSSAuth

Select .NET 8.0. 

Then, close the solution.

2. Generate proxy classes for the DSS authentication service

Open a command line prompt and change the directory to the directory that contains the solution file (.sln). For this example, it is C:\examples\OdataDSSAuth.

Check the version of .NET.

Run the odata-cli tool to generate proxy client classes for the DSS Authentication service.

    	
            odata-cli generate -m "https://selectapi.datascope.refinitiv.com/restapi/v1/Authentication/$metadata" -o "ODataDSSAuth" -fn "DSS_Authentication" -ns DSSAuthentication -s DSSAuthentication
        
        
    

The command uses the following parameters:

Parameter

Description

-m

The URI of the metadata document (The metadata of the DSS authentication service)

-o

Full path to output directory (The project directory)

-fn

The name of the generated file (DSS_Authentication.cs)

-ns

The namespace of the client code generated (DSSAuthentication)

-s

Human-readable display name of the service instance (DSSAuthentication)

After running the command, the required packages and resource are added to the project file (ODataDSSAuth.csproj).

    	
            

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>net8.0</TargetFramework>

    <ImplicitUsings>enable</ImplicitUsings>

    <Nullable>enable</Nullable>

  </PropertyGroup>

  <ItemGroup>

    <PackageReference Include="Microsoft.OData.Client" Version="8.0.2" />

    <PackageReference Include="Microsoft.OData.Core" Version="8.0.2" />

    <PackageReference Include="Microsoft.OData.Edm" Version="8.0.2" />

    <PackageReference Include="Microsoft.Spatial" Version="8.0.2" />

    <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />

    <PackageReference Include="System.Text.Json" Version="8.0.4" />

  </ItemGroup>

  <ItemGroup>

    <EmbeddedResource Include="DSSAuthenticationCsdl.xml" />

  </ItemGroup>

</Project>

The DSS_Authentication.cs and DSSAuthenticationCsdl.xml files are created in the project directory.

3.  Use the generated proxy classes

Open the project file. The DSS_Authentication.cs and DSSAuthenticationCsdl.xml files are also added to the project. The namespace of the generated proxy classes is DSSAuthentication, as specified in the -ns parameter. 

Therefore, use the using directive to import types defined in the DSSAuthentication namespaces.

    	
            using DSSAuthentication;
        
        
    

The DSS_Authentication.cs contains a service class (Authentication) derived from the DataServiceContext and the generated strong types defined in the DSS Authentication metadata document. 

There are two ways to use the strong types generated by the odata-cli: using them with the derived DataServiceContext class or using them with HttpClient. The code is available on GitHub.

3.1  Using the derived DataServiceContext class

This is a straightforward way to use the generated classes. First, initialize the Authentication class (the derived DataServiceContext class) with the DSS authentication endpoint.

    	
            Authentication auth = new Authentication(new Uri("https://selectapi.datascope.refinitiv.com/restapi/v1/Authentication"));
        
        
    

Then, invoke its methods with the required parameters. 

    	
            

try

{

    Authentication auth = new Authentication(new Uri("https://selectapi.datascope.refinitiv.com/restapi/v1/Authentication"));

    var resp = auth.RequestToken(new Credentials { Username = DSSUsername, Password = DSSPassword });

    var token = resp.GetValue();

 

    Console.WriteLine($"Token: {token}");

 

}

catch (DataServiceQueryException ex)

{

    Console.WriteLine(ex.InnerException?.Message);

    return;

}

The code above calls the RequestToken method with the Credentials type and then print the retrieved token on the screen. Moreover, the application should also handle the DataServiceQueryException exception thrown by the DataServiceContext.

3.2  Using HttpClient

This method does not use the derived DataServiceContext class but it uses the JSON library to serialize the generated strong types to JSON strings and then uses the HTTPClient to send the strings to the DSS endpoints. Although this method is quite complex, it is more flexible than the first method.

The example uses the System.Text.Json and System.Net.Http packages. First, initialize a JSON object from the Credentials type

    	
            

Credentials creds = new Credentials();

creds.Username = DSSUsername;

creds.Password = DSSPassword;

var jsonBody = new

{

    Credentials = creds

};

Next, use the JsonSerializer to serialize the Credentials JSON object to a JSON string.

    	
            

JsonSerializerOptions options = new JsonSerializerOptions();

options.WriteIndented = true;

options.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;

var jsonStr = JsonSerializer.Serialize(jsonBody, options);

Then, create a HttpRequestMessage with the Post method to the RequestToken endpoint and set the JSON string in the request’s body. 

    	
            

HttpRequestMessage requestMessage = new HttpRequestMessage(

    HttpMethod.Post,

    "https://selectapi.datascope.refinitiv.com/RestApi/v1/Authentication/RequestToken");

 

requestMessage.Headers.Add("Prefer", "respond-async");          

 

requestMessage.Content = new StringContent(jsonStr, Encoding.UTF8, "application/json");

Next, create a HttpClient to send the request message and then check the status of the HTTP response. The example uses the EnsureSuccessStatusCode method to check the status code of the HTTP response.  It will throw an exception if the IsSuccessStatusCode property for the HTTP response is false.

    	
            

HttpClient client = new HttpClient();

var response = client.Send(requestMessage);

try

{

    response.EnsureSuccessStatusCode();

}

catch (HttpRequestException ex)

{

    Console.WriteLine(ex.Message.ToString());

    Console.WriteLine(response.Content.ReadAsStringAsync().Result);

    return;

}

Finally, use the JsonSerializer to deserialize the response’s content to a JsonNode and retrieve a token from the JsonNode

    	
            

JsonNode? authResponse = JsonSerializer.Deserialize<JsonNode>(response.Content.ReadAsStringAsync().Result);

string? token = null;

if (authResponse is not null)

    token = authResponse["value"].GetValue<string>();

           

if(token is not null)

{

    Console.WriteLine($"Token: {token}");

}

Using the HttpClient involves more steps than using the derived DataServiceContext class. However, using the HttpClient, developers can gain more control over processing retrieved HTTP responses. For example, the application can check the HTTP status codes and process them accordingly. This is particularly useful when checking the status codes (200 or 202) from DSS extraction requests.

Summary

OData is an open standard for defining HTTP-based web service APIs. It defines a metadata document that provides a complete description of the service including its types, and functions. Odata-cli is a .NET tool that can parse a metadata document and generate a DataServiceContext class with all strongly typed data types defined in the web service.   

OData is also used by the Datascope Select and Tick History products to define HTTP-based REST APIs, allowing the odata-cli tool to generate the C# service classes and C# strongly typed data types for the DSS and Tick History REST APIs. Developers can use the generated service classes with the strongly typed data types directly or utilize the HttpClient library with the JSON strings serialized from the generated types. While the latter method requires more steps, it offers greater flexibility than the former.

References

  1. OData. (n.d.). OData: The Protocol for Building and Consuming RESTful APIs. Retrieved October 21, 2024, from https://www.odata.org
  2. Wikipedia contributors. (n.d.). Open Data Protocol. In Wikipedia, The Free Encyclopedia. Retrieved October 21, 2024, from https://en.wikipedia.org/wiki/Open_Data_Protocol
  3. Microsoft. (n.d.). Getting started with OData CLI. Retrieved October 21, 2024, from https://learn.microsoft.com/en-us/odata/odatacli/getting-started