X

Using Oracle Cloud Infrastructure Software Development Kit for .NET with VS Code or VS Codespaces

This post was co-authored with Nabeel Al-Saber, my colleague at Oracle.

In this blog, I demonstrate how to use Visual Studio Code and Oracle Cloud software development kit (SDK) for .NET to build an application that can access Oracle Cloud. I cover the steps for onboarding to Oracle Cloud, the general setup required to use Oracle Cloud Infrastructure developer tools with some more specifics for .NET SDK, and how to run and debug this application in VS Codespaces.

Oracle Cloud software development kit (SDK) for .NET was released in July 2020. An addition to the Oracle Cloud developer tools family, it enables developers who prefer .NET/C# to interact with Oracle Cloud.

Oracle Cloud Free Tier Offering

Before getting started with the application, let’s briefly talk about Oracle Cloud Infrastructure account.

If you’re new to Oracle Cloud, the first step required is to create an Oracle Cloud Infrastructure account. Oracle Cloud Free Tier is a great way to sign up and get a feel for Oracle’s cloud services.

Configuration for Authentication with Oracle Cloud

With an active Oracle Cloud account, you need to authenticate yourself when interacting with Oracle Cloud through Oracle Cloud Infrastructure SDK for .NET. This process uses an API key pair and a configuration file that the SDK can read.

Oracle Cloud SDK for .NET, like the other public SDKs, relies on an RSA key pair in PEM format to authenticate you. Complete the following steps to generate the key pair and related information:

  • Create a user with appropriate permissions to access Oracle Cloud services. See How to Create Users, Groups, and Set Permissions. If you’ve already created a user, you can skip this step.

  • Generate a key pair if not already available: See How to Generate an API Signing Key. We recommend that you protect your private key with a passphrase. Keep the private key safely to yourself, and upload the public key in one of the following steps.

  • Get the fingerprint of the public key: See How to Get Fingerprint. An easier way to get the fingerprint is from Console. After uploading the public key in the next step, Console displays the fingerprint, and you can copy it from there.

  • Upload public key in Console to the user account if it’s not already there: See How to Upload Public Key.

The configuration file supplies information to the Oracle Cloud SDK for .NET. Its default location is in your home directory (~/.oci/config), but you can store it in other locations, too. Along with the generated key and the fingerprint, the configuration file also needs to include the tenancy OCID and user OCID. You can find these unique identifiers in the Console. See how to find tenancy OCID and user OCID.

You can copy the following sample configuration file to your environment. Update the actual values in this file to match your user account.

[DEFAULT]
user=ocid1.user.oc1..
fingerprint=f7:12:34:56:78:90:ab:bc:cd:de:ef:98:87:65:43:21
key_file=~/.oci/my_oci_api_key.pem
tenancy=ocid1.tenancy.oc1..
region=us-phoenix-1
pass_phrase=SomePassPhrase

Uploading the OCI Config File in VS Codespaces

If you’re using an online IDE like VS Codespaces, you need to upload the config file and the required keys to be able to access Oracle Cloud resources when you run your application.

You can upload the files to the remote IDE in a few different ways. In this blog, I highlight creating a config from the terminal.

Open the terminal in VS Codespace if it’s not visible. Open the menu, then go to View, and select Terminal. Then follow these steps:

# Create a new config file under ~/.oci
mkdir ~/.oci
# Copy the content of the config
vi ~/.oci/config
# Select the correct path for the key file in the config: key_file=~/.oci/oci_api_key.pem
 
# Copy the content of the local oci_api_key.pem file and paste it in the remote file
vi ~/.oci/oci_api_key.pem
 
# Copy the content of the local oci_api_key_public.pem file and paste it in remote file
vi ~/.oci/oci_api_key_public.pem

The following screenshot shows the Terminal in VS Codespaces after creating the config file and the key files.

A screenshot of the terminal in VS Codespaces.

Working with .NET Core Application

Installing C# Extension

C# support in VS Code is through an optional extension that you can install from the Marketplace. To install this extension, click the Extensions icon on the left, and search for C#. Install the extension from Microsoft.

A screenshot of the C# extension installation screen in the Marketplace.

C# extension is powered by OmniSharp and provides a lot of convenience to C# development, including support for project.json and csproj projects and editing support, such as IntelliSense, go to definition, syntax highlighting, find references, and so on.

Creating New .NET Core Application

One feature that’s not available in VS Code is an application creation wizard, which means that you need to create an application outside of VS Code.

Assuming .NET Core SDK has been installed, you can create a project through .NET Core CLI

  1. Open a terminal and change directory to the folder where a project is created. The folder name is used as the project name in the next step.

  2. Run the following .NET Core CLI command, and a fully functioning project is created:

    dotnet new console
  3. To build and run the new project, run the following .NET Core CLI command. When it succeeds, it prints “Hello World!”

    dotnet run

For VS Codespaces, you can create a project by following the previous steps in the terminal.

Loading Existing Project

VS Code

With C# extension installed and a .NET Core application already created, we can open the project in VS Code.

  1. From File menu, select Open...

  2. Navigate to the folder containing the C# project.

  3. Click Open.

  4. If VS Code shows a notification that says “Required assets to build and debug are missing. Add them?” select Yes and let VS Code load dependencies automatically.

Now we can view the project structure and source code in VS Code. It should contain a .csproj file and a Program.cs file.

VS Codespaces

First, upload the project files to GitHub. Then you can create a Codespace and provide the GitHub link for the project that you want to import.

Importing Oracle Cloud Infrastructure SDK for .NET Packages

Oracle Cloud Infrastructure SDKs for .NET are published as NuGet packages. To use the SDK to interact with Oracle Cloud, we need to import the packages. Similar to C# support, in VS Code, you need to install an extension “NuGet Package Manager.” Again, go to Extensions view and search for “nuget package manager.” The extension should show up at the top of the results list.

With the extension installed, you can search and install individual NuGet packages.

  1. From the View menu, select Command Palette... (or use keyboard shortcut).

  2. In the pop-up, type “nuget,” and the search result should show “NuGet Package Manager: Add Package.” Select that option.

    A screenshot of 'nuget' typed into the search bar above the expanded options that include nuget.

  3. In the next dialog box, enter the name of the package you want to import and hit Enter. You can enter a partial name, such as OCI.DotNetSDK. All packages containing that partial name are returned and displayed the search box:

    A screenshot of the search results for OCI.DotNetSDK.

  4. Select the package you want to import, and all versions found for this package are displayed. Along with the package you want to work with, you should also import OCI.DotNetSDK.Common package, because it contains all the key functionalities, including authenticating and sending HTTP requests.

    A screenshot of the version options for the package.

  5. Pick a version that you want to use, typically the latest one, and the package is added to the project automatically.

Now, if you look at the .csproj file in the project, it should contain a new PackageReference in the ItemGroup section.

In this application, we search and import two NuGet packages from Oracle Cloud SDK for .NET:

  • OCI.DotNetSDK.Common

  • OCI.DotNetSDK.Identity

The .csproj file should have an ItemGroup section:

<ItemGroup>
  <PackageReference Include="OCI.DotNetSDK.Common" Version="4.1.0"/>
  <PackageReference Include="OCI.DotNetSDK.Identity" Version="4.1.0"/>
</ItemGroup>

Writing Your First Oracle Cloud .NET Application

Now we’re ready to work on the source code and interact with Oracle Cloud in our application. Since all the information needed to authenticate the user with Oracle Cloud is already included in the configuration file, we only need to configure the service client to use the configuration file, and call service APIs using the service client. Update the autogenerated Program.cs with the following changes:

  1. Ensure that all the correct using statements are included. The following examples are important:

    • System.Threading.Tasks: Used for asynchronous methods

    • Oci.Common.Auth: Used to build the authentication details provider

    • Oci.<Service>: Used to create the service client

    • Oci.<Service>.Requests and Oci.<Service>.Responses: Used for API request and response objects

The following example uses IdentityService:

using System.Threading.Tasks;
using Oci.Common.Auth;
using Oci.IdentityService;
using Oci.IdentityService.Requests;
using Oci.IdentityService.Responses;
  • In the Main function, remove the original statement that prints “Hello World!” and create an authentication details provider that uses values from the configuration file. You have multiple variations of authentication details providing initialization using the configuration file.

    If the configuration file is stored in the default location (~/.oci/config), we only need to provide the profile name to create an authentication details provider:

    var config = new ConfigFileAuthenticationDetailsProvider("DEFAULT");
    

    If the configuration file is stored in a custom location, we also need to supply the file path:

    var config = new ConfigFileAuthenticationDetailsProvider("/path/to/config/file", "DEFAULT");
    
  • Use the authentication details provider to build a service client:

    using (var client = new IdentityClient(config))
    {
    }
    
  • Create a request object, send it out using the service client, and receive the response returned by the service:

    var listCompartmentsRequest = new ListCompartmentsRequest
    {
        CompartmentId = compartmentId
    };
    
    using (var client = new IdentityClient(config))
    {
        ListCompartmentsResponse response = await client.ListCompartments(listCompartmentsRequest);
    }
    
  • Because we’re calling the previous asynchronous function, we also need to update the Main function into an asynchronous function:

    static async Task Main(string[] args)
    

The final code looks like the following block:

using System;
using System.Threading.Tasks;
using Oci.Common.Auth;
using Oci.IdentityService;
using Oci.IdentityService.Requests;
using Oci.IdentityService.Responses;

namespace oci_sdk_dotnet_blog
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Needs a valid compartment ocid from your tenancy.
            var compartmentId = "ocid1.tenancy.oc1..";
            try
            {
                var config = new ConfigFileAuthenticationDetailsProvider("DEFAULT");

                var listCompartmentsRequest = new ListCompartmentsRequest
                {
                    CompartmentId = compartmentId
                };

                using (var client = new IdentityClient(config))
                {
                    ListCompartmentsResponse response = await client.ListCompartments(listCompartmentsRequest);
                    Console.WriteLine($"Found {response.Items.Count} compartments.");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }
}

Running and Debugging the Application in VS Code

Now, we’re ready to run or debug our application, and you can do this inside VS Code.

Running the Application

To run the application without debugging, go to the Run menu and select “Run Without Debugging.”

If you’re running this application for the first time, VS Code might not have been configured properly for it. If it can’t decide automatically, it asks for the environment to run in. When prompted for environment during this step, select “.NET Core.” VS Code automatically creates two files in a folder called “.vscode” under the project directory. These two files tasks.json and launch.json, tell VS Code how to build and run the application.

A screenshot of the options for selecting an environment where VS Codespaces creates the tasks.json and launch.json files.

After the tasks.json and launch.json files have been created, run the project again, and you should see logs in debug console at the bottom of VS Code window. If everything goes well, the project should pass the build and produce the following outputs (or similar):

-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
/
Visual Studio Code, Visual Studio, or Visual Studio for Mac software

to help you develop and test your applications.
-------------------------------------------------------------------

Found 40 compartments.

Debugging Application

Like using other IDEs to debug our code, we can set breakpoints in our code by clicking to the left of the line numbers.

To start debugging, go to the Run menu and select Start Debugging. Again, if VS Code hasn’t been configured to run or debug your program, follow the same previous steps on running application to create tasks.json and launch.json files. Once the debugging session starts, you can monitor the progress and see it stop at the breakpoint you set. One the left side of VS Code window, click the Run icon to go to the run or debug view, where you can find call stacks, variables, and so on, that are common among all IDEs.

A screenshot of the debugging function in the Run section.

A floating control shows up at the top-right corner of VS Code window. This control allows you to perform normal debugging operations, such as step over, step into, step out, continue, stop, and so on.

A screenshot of the floating control in the VS Code window.

Logging

Logging is an important way to debug your program, and Oracle Cloud Infrastructure SDK for .NET uses NLog for logging. Any application using this SDK can capture the logs from the SDK, but you must include your own NLog configuration file to the project. This configuration file defines the logging targets and wanted logging levels.

The following sample config file tells NLog to log to both Console and file. For console output, NLog prints messages from Info logging level and above. For the log file, Nlog includes everything from Debug logging level and above. You can find more details about logging levels from the NLog official documentation.

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <targets>
        <target name="console" xsi:type="ColoredConsole" />
        <target name="file" xsi:type="File" fileName="${CurrentDir}/logs/${date:format=yyyy-MM-dd}.log" />
    </targets>
    <rules>
        <logger name="*" minlevel="Info" writeTo="console" />
        <logger name="*" minlevel="Debug" writeTo="file" />
    </rules>
</nlog>

To see logging from the SDK, create and add an NLog.config file to the root of your project. Then update the .csproj file by adding the following section:

<ItemGroup>
  <Content Include="NLog.config">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

Now, run or debug the program. Along with the normal console logging, a folder called “logs” (as defined in NLog.config was added to your project. It contains a log file with a timestamp as its name (again defined in NLog.config). Both the Console output and the log file contain some information that didn’t show before. Those logging lines came from the Oracle Cloud SDK for .NET..

By adding NLog.config to the project, you only see logging from Oracle Cloud SDK for .NET. You can choose to use NLog to log information from your application, too. The only change you need to make is to add the following logger to your class.

private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

Then, you can replace all statements that were writing to Console with the following logger methods, or similar:

logger.Info($"Found {response.Items.Count} compartments.");

Providing User Values

In the previous example, we explicitly set the value of “CompartmentId” that’s required by the ListCompartmentRequest object. If you don’t want to expose the value from the source code, or you want to allow other people to customize the values, consider using one of the following approaches to supply the information to your application.

Reading from Environment Variables

VS Code can access environment variables that are available in all terminal sessions, such as the environment variables set through .bash_profile in MacOS or Linux. Optionally, you can define environment variables only for your application in VS Code by adding an “env” section in launch.json file. See the “Running and Debugging Application in VS Code” section on how to generate the launch.json file.

For example, we add an environment variable “VSCODE_COMPARTMENT_ID” that’s used when running or debugging this application.

A screenshot of the .NET Core Launch (console) with the added VSCODE_COMPARTMENT_ID variable.

Then, instead of hardcoding the value to compartmentId variable, we can retrieve it from the following environment variable:

var compartmentId = Environment.GetEnvironmentVariable("VSCODE_COMPARTMENT_ID");

When you set environment variable in launch.json file, you can’t access it when you run your application from a terminal, including the terminal in VS Code. Your application can read this value as environment variable-only when VS Code launches it.

Reading from Configuration File

We can also supply values to our application through the configuration file. So far, you included user authentication information in that file. You can also supply other data as key value pairs. Oracle Cloud SDK for .NET provides functions to read values from the configuration. Let’s add an extra key value pair at the end of the default profile in the existing configuration file:

[DEFAULT]
user=ocid1.user.oc1..
fingerprint=f7:12:34:56:78:90:ab:bc:cd:de:ef:98:87:65:43:21
key_file=~/.oci/my_oci_api_key.pem
tenancy=ocid1.tenancy.oc1..
region=us-phoenix-1
pass_phrase=SomePassPhrase
config_compartment_id=ocid1.tenancy.oc1..

Now you can update the code to read the value from the configuration file using its key “config_compartment_id.” To access ConfigFileReader, add “using Oci.Common;”.

var config = ConfigFileReader.Parse(ConfigFileReader.DEFAULT_FILE_PATH);
var compartmentId = config.GetValue("config_compartment_id");

Summary

In this blog, we walked through an end-to-end example of creating, configuring, and running or debugging a .NET Core application that uses Oracle Cloud Infrastructure SDK for .NET in VS Code. As one of many IDE choices, VS Code has its own advantages and limitations. Once configured for C# development, you can use VS Code to develop .NET Core applications with ease by providing features to browse, search, and import Oracle Cloud SDK for .NET NuGet packages, edit source code, and run or debug the application.

If you’re a .NET developer and interested in Oracle Cloud, I strongly recommend that you experience it through our SDK and take advantage of the great offering from Oracle through the Free Tier program. I hope this blog helps you get started with your own application interacting with Oracle Cloud. Leave comments if you have any questions or feedback.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.