Dec 20

Written by: Michael Washington
12/20/2018 10:03 PM  RssIcon

image

Calling a REST based API from .Net Core is usually more complicated than many of the samples you may have seen. The reason is that each REST based API can implement its own unique security measures. In addition, passing complex parameters, and uploading files though a REST based API, can prove challenging.

image

In this example, we will look at consuming the REST Based API for the popular open source Help Desk application ADefHelpDesk.com. This API has the following features that we will explore:

  • Requires callers to first obtain a JSON Web Token (JWT) (also called a Bearer Token), using a combination of a UserName, Password, and Application GUID. The token is then passed in the header of the subsequent requests to the other methods to authenticate the requests.
  • Allows external caller to create Help Desk Tickets (and perform all other functionality).
  • As part of creating Help Desk Tickets, the API allows the external caller to upload files.

 

Install ADefHelpDesk

image

You can download and install ADefHelpDesk from the site at: http://ADefHelpDesk.com.

image

After you have the site running, follow the directions at the link: API Security (Swagger Rest API) on the documentation page that can be found at this link to create an account that can call the API.

image

You will need to copy the information on the Connection Information tab to use later.

image

In the ADefHelpDesk site there is a Swagger page (see: https://swagger.io/) that documents the REST based API endpoints at: http://{your default web address}/swagger/ (for example: http://adefhelpdesk.azurewebsites.net/swagger/).

We will refer to this page frequently.

 

Create The Application

image

Open Visual Studio.

image

Select Web, then ASP.NET Core Web Application.

Enter AdefHelpDeskMVC for the Name.

Press OK.

image

Select the Web Application template and press OK.

The project will be created.

 

Load Application Settings

image

In the Solution Explorer, open the appsettings.json file.

image

Replace the contents with the following (replacing the settings with your own values gathered earlier):

 

{
  "AllowedHosts": "*",
  "CustomSettings": {
    "APIWebAddress": "** Your Web Address **",
    "ApplicationGUID": "** Your ApplicationGUID **",
    "UserName": "** Your UserName **",
    "Password": "** Your Password **"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

 

image

Add a folder called Models and a class file called CustomSettings.cs using the following code:

 

namespace AdefHelpDeskMVC.Models
{
    // This allows us to retrieve custom settings 
    // from appsettings.json
    public class CustomSettings
    {
        public string APIWebAddress { get; set; }
        public string ApplicationGUID { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
    }
}

 

image

Next, open the Startup.cs file.

Change the Startup method to the following:

 

        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

 

Change the ConfigureServices method to the following:

 

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            // Get the CustomSettings from appsettings.json
            // allow them to be passed to any class using dependency injection
            services.Configure<Models.CustomSettings>(
                Configuration.GetSection("CustomSettings"));
        }

 

 

This will load the settings in the appsettings.json file and make them available, through the CustomSettings class, using dependency injection.

 

Get The JSON Web Token (JWT) (Authentication Token)

image

The ADefHelpDesk API requires that you use the UserName and Password to call the /api/V1/GetAuthToken API method, to obtain a JSON Web Token (JWT) to use as authentication for subsequent calls to the other API methods.

Note that the method has the word Post in the green box. This indicates that it must be called by sending a Post request.

Note that the JWT will expire after a few minutes, and when it does, you will have to call the /api/V1/GetAuthToken API method again to obtain another JWT.

So, as the first step, we will create code to allow a JWT to be retrieved.

image

The Swagger page will provide the format (the class definition) of the parameter the endpoint requires.

image

Create a class file called DTOApiToken.cs using the following code:

 

namespace AdefHelpDeskMVC.Models
{
    public class DTOApiToken
    {
        public string userName { get; set; }
        public string password { get; set; }
        public string applicationGUID { get; set; }
    }
}

 

image

Next, open the page at Pages/Index.cshtml and change all the code to the following:

 

@page
@model IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    ViewData["Title"] = "ADefHelpDesk API Client";
}
<div class="row">
    <div class="col-md-12">
        <h4>ADefHelpDesk API Client</h4>
        <p class="clearfix"><b>@Model.Message</b></p>
    </div>
</div>
<div class="row">
    <form asp-page-handler="AuthToken" method="post">
        <button class="btn btn-default">Get Auth Token</button>
    </form>
</div>
<div class="row">
    <p class="col-md-12">@Model.BearerToken</p>
</div>
<br />

 

This creates the page layout with a button that will retrieve the Auth Token (the JWT) and a label to display it.

 

image

Finally, open the Index.cshtml.cs file and change all the code to the following:

 

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using AdefHelpDeskMVC.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace AdefHelpDeskMVC.Pages
{
    [BindProperties]
    public class IndexModel : PageModel
    {
        // Used to make REST calls
        public static HttpClient client;
        // To store the settings from the appsettings.json file
        private CustomSettings _CustomSettings;
        // To hold any error messages
        public string Message { get; set; }
        // To store the JWT (Authentication token)
        public string BearerToken { get; set; }
        // This method is called when this class is initialized
        public IndexModel(IOptions<CustomSettings> CustomSettings)
        {
            // Get the custom settings using dependency injection
            _CustomSettings = CustomSettings.Value;
        }
    }
}

 

This provides the code to load the CustomSettings, using dependency injection, that were registered in the Startup.cs file.

Add the following methods:

 

        private void InitializeForm()
        {
            // Initialization code to be added later...
        }
        // This method called when the page is loaded
        public void OnGet()
        {
            InitializeForm();
        }

 

Now, to implement the code to handle the button click (to retrieve the JWT), add the following method:

 

        public async void OnPostAuthTokenAsync()
        {
            // Instantiate the DTOApiToken class and set the parameters
            // using the values from CustomSettings 
            DTOApiToken paramApiToken = new DTOApiToken();
            paramApiToken.userName = _CustomSettings.UserName;
            paramApiToken.password = _CustomSettings.Password;
            paramApiToken.applicationGUID = _CustomSettings.ApplicationGUID;
            // Call the GetAuthToken method and retrieve the BearerToken (JWT - Auth Token)
            // The BearerToken will then display on the page because it has
            // the following code: @Model.BearerToken
            BearerToken = await GetAuthToken(_CustomSettings.APIWebAddress, paramApiToken);
            InitializeForm();
        }

 

Finally, add the following code to implement the GetAuthToken method:

 

       private static async Task<string> GetAuthToken(string APIWebAddress, DTOApiToken paramApiToken)
        {
            // Store the final result
            string strResult = "";
            // Use the HttpClient 
            using (client)
            {
                // Initialize the HttpClient
                client = new HttpClient();
                // Create a new REST request
                using (var request = new HttpRequestMessage())
                {
                    // The Swagger page indicates this must be a "Post"
                    request.Method = HttpMethod.Post;
                    // Set the destination to the method indicated on the Swagger page
                    // to: api/V1/GetAuthToken
                    request.RequestUri = new Uri($"{APIWebAddress}api/V1/GetAuthToken");
                    // Convert the parameters to JavaScript Object Notation (JSON) format 
                    var json = JsonConvert.SerializeObject(paramApiToken);
                    request.Content = new StringContent(json, Encoding.UTF8, "application/json");
                    // Make the request to the API endpoint on the ADefHelpDesk site
                    var response = client.SendAsync(request).Result;
                    // Receive the response
                    var JsonDataResponse =
                        await response.Content.ReadAsStringAsync();
                    // Convert the response (the JWT (Auth Token)) to a String value
                    strResult =
                        JsonConvert.DeserializeObject<string>(JsonDataResponse);
                    // Strip the word Bearer from the token
                    strResult = strResult.Replace("Bearer ", " ");
                }
            }
            // Return the JWT
            return strResult;
        }

 

image

Hit F5 to run the project.

image

You can now click the Get Auth Token button and the code will call the API method on the ADefHelpDesk site, passing the UserName, Password, and ApplicationGUID, and retrieve the JWT that will then be displayed on the page.

Retrieve The Current User

To demonstrate how the JWT is used to authenticate a request, we will call the GetCurrentUser API method.

image

When we look at the Swagger page we can get the API endpoint address, see that we call it as a Get, and that we pass no parameters.

However, we will need to pass an valid and unexpired JWT in the header of the request, otherwise we will get an unauthorized response.

Add the following code to the Index.cshtml page:

 

<div class="row">
    <form asp-page-handler="CurrentUser" method="post">
        <input type="hidden" name="paramBearerToken" value="@Model.BearerToken" />
        <button class="btn btn-default">Get Current User</button>
    </form>
</div>
<div class="row">
    <p class="col-md-12">@Model.CurrentAPIUser</p>
</div>

 

This will create a button to click to retrieve the name of the API User and a div to display it.

Note that there is a hidden field called paramBearerToken that contains the value of the JWT. Because it is in the form tag it will be passed to the CurrentUser method specified in the asp-page-handler tag.

Add the following code to the Index.cshtml.cs page:

 

        // Store the name of the current API User
        public string CurrentAPIUser { get; set; }

 

Next, add the following method to handle the button click:

 

        public async void OnPostCurrentUserAsync(string paramBearerToken)
        {
            // paramBearerToken is passed to this method (when the button is clicked)
            // by the hidden field
            if (paramBearerToken == null)
            {
                // Set error message
                Message = "The Auth Token is required";
            }
            else
            {
                // Call the API
                var response = 
                    await GetCurrentUser(_CustomSettings.APIWebAddress, paramBearerToken);
                if (response == "Unauthorized")
                {
                    // Set error message
                    Message = "The Auth Token is expired or invalid";
                }
                else
                {
                    // Return the Current User
                    CurrentAPIUser = response;
                    // Save the Bearer Token
                    BearerToken = paramBearerToken;
                }
            }
            InitializeForm();
        }

 

Finally, add the following code to implement the GetCurrentUser method that is being called by the code above:

 

        private static async Task<string> GetCurrentUser(string APIWebAddress, string paramBearerToken)
        {
            // Store the final result
            string strResult = "";
            // Use the HttpClient 
            using (client)
            {
                // Initialize the HttpClient
                client = new HttpClient();
                // Create a new REST request
                using (var request = new HttpRequestMessage())
                {
                    // The Swagger page indicates this must be a "Post"
                    request.Method = HttpMethod.Get;
                    // Set the destination to the method indicated on the Swagger page
                    // to: api/V1/GetCurrentUser
                    request.RequestUri = new Uri($"{APIWebAddress}api/V1/GetCurrentUser");
                    // Pass the JWT in the 'header' of the request with the word "Bearer" in front
                    client.DefaultRequestHeaders.Authorization =
                        new AuthenticationHeaderValue("Bearer", paramBearerToken);
                    // Make the request to the API endpoint on the ADefHelpDesk site
                    var response = client.SendAsync(request).Result;
                    // Handle if the JWT is expired
                    if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                    {
                        return "Unauthorized";
                    }
                    // Receive the response
                    var JsonDataResponse =
                        await response.Content.ReadAsStringAsync();
                    // Convert the response to a String value
                    strResult =
                        JsonConvert.DeserializeObject<string>(JsonDataResponse);
                }
            }
            // Return the response
            return strResult;
        }

 

image

When we run the application, we first click the Get Auth Token button to get a JWT, then we click the Get Current User button to pass the JWT to the method that will retrieve the name of the current API user.

Create A Help Desk Ticket

image

We will now create a Help Desk Ticket by calling the CreateTask method.

We see that this one has a lot of parameters.

image

The parameters are a combination of the DTOTask class and the DTOTaskDetail class.

Their full definition for the classes is available by scrolling down toward the bottom of the Swagger page.

image

We can also see the class that the method will return.

image

To represent these classes, add three class files to the Models folder using the following code:

DTOStatus.cs

 

namespace AdefHelpDeskMVC.Models
{
    public class DTOStatus
    {
        public string StatusMessage { get; set; }
        public bool Success { get; set; }
    }
}

 

DTOTask.cs

 

using System.Collections.Generic;
namespace AdefHelpDeskMVC.Models
{
    public class DTOTask
    {
        public int? taskId { get; set; }
        public int? portalId { get; set; }
        public string description { get; set; }
        public string status { get; set; }
        public string priority { get; set; }
        public string createdDate { get; set; }
        public string estimatedStart { get; set; }
        public string estimatedCompletion { get; set; }
        public string dueDate { get; set; }
        public int? assignedRoleId { get; set; }
        public string assignedRoleName { get; set; }
        public string ticketPassword { get; set; }
        public int? requesterUserId { get; set; }
        public string requesterName { get; set; }
        public string requesterEmail { get; set; }
        public string requesterPhone { get; set; }
        public int? estimatedHours { get; set; }
        public bool? sendEmails { get; set; }
        public List<int> selectedTreeNodes { get; set; }
        public List<DTOTaskDetail> colDTOTaskDetail { get; set; }
    }
}

 

DTOTaskDetail.cs

 

using System.Collections.Generic;
namespace AdefHelpDeskMVC.Models
{
    public class DTOTaskDetail
    {
        // Note: this field is renamed from description to
        // taskDetailDescription to prevent collision when passed
        // as a parameter with the field description in the Task object
        public string taskDetailDescription { get; set; }
        public int detailId { get; set; }
        public string detailType { get; set; }
        public string contentType { get; set; }
        public string insertDate { get; set; }
        public int userId { get; set; }
        public string userName { get; set; }
        public string emailDescription { get; set; }
        public string startTime { get; set; }
        public string stopTime { get; set; }
        public bool? sendEmails { get; set; }
    }
}

 

To create a form that will allow the Ticket to be input, add the following code to the Index.cshtml page:

 

<div>
    <form asp-page-handler="CreateTicket" method="post" enctype="multipart/form-data">
        <input type="hidden" name="paramBearerToken" value="@Model.BearerToken" />
        <div class="row">
            <p class="col-md-1">Name:</p>
            <p class="col-md-11">
            <input asp-for="@Model.TicketForm.Name" /></p>
        </div>
        <div class="row">
            <p class="col-md-1">Email:</p>
            <p class="col-md-11">
            <input type="email" asp-for="@Model.TicketForm.Email" /></p>
        </div>
        <div class="row">
            <p class="col-md-1">Phone:</p>
            <p class="col-md-11">
            <input type="tel" asp-for="@Model.TicketForm.Phone" /></p>
        </div>
        <div class="row">
            <p class="col-md-1">Description:</p>
            <p class="col-md-11">
            <input asp-for="@Model.TicketForm.Description" /></p>
        </div>
        <div class="row">
            <p class="col-md-1">Due Date:</p>
            <p class="col-md-11">
            <input type="date" asp-for="@Model.TicketForm.DueDate" /></p>
        </div>
        <div class="row">
            <p class="col-md-1">Priority:</p>
            <p class="col-md-11">
            <select asp-for="@Model.TicketForm.Priority" asp-items="Model.Options"></select></p>
        </div>
        <div class="row">
            <button class="btn btn-default">Create Help Desk Ticket</button>
        </div>
    </form>
</div>

 

Add the following class (outside of the IndexModel class but inside the AdefHelpDeskMVC namespace), to hold the properties used in the form, to the Index.cshtml.cs file:

 

    public class Ticket
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Description { get; set; }
        public string Detail { get; set; }
        public DateTime? DueDate { get; set; }
        public string Priority { get; set; }
    }

 

Add this extension method class that will be used later to serialize parameters to append to the URL:

 

    public static class ObjectExtensions
    {
        // From: https://bit.ly/2A5R70I
        public static IDictionary<string, string> ToKeyValue(this object metaToken)
        {
            if (metaToken == null)
            {
                return null;
            }
            JToken token = metaToken as JToken;
            if (token == null)
            {
                return ToKeyValue(JObject.FromObject(metaToken));
            }
            if (token.HasValues)
            {
                var contentData = new Dictionary<string, string>();
                foreach (var child in token.Children().ToList())
                {
                    var childContent = child.ToKeyValue();
                    if (childContent != null)
                    {
                        contentData = contentData.Concat(childContent)
                            .ToDictionary(k => k.Key, v => v.Value);
                    }
                }
                return contentData;
            }
            var jValue = token as JValue;
            if (jValue?.Value == null)
            {
                return null;
            }
            var value = jValue?.Type == JTokenType.Date ?
                jValue?.ToString("o", CultureInfo.InvariantCulture) :
                jValue?.ToString(CultureInfo.InvariantCulture);
            return new Dictionary<string, string> { { token.Path, value } };
        }
    }

 

Add the following properties inside the IndexModel class:

 

        // To hold values for the Ticket form
        public Ticket TicketForm { get; set; }
        // To hold values for the dropdown on the Ticket form
        public List<SelectListItem> Options { get; set; }

 

Change the InitializeForm method to the following:

 

        private void InitializeForm()
        {
            // Instatiate the values for the form
            TicketForm = new Ticket();
            // Create options for the dropdown on the form
            Options = new List<SelectListItem>();
            Options.Add(new SelectListItem { Value = "Normal", Text = "Normal" });
            Options.Add(new SelectListItem { Value = "High", Text = "High" });
            Options.Add(new SelectListItem { Value = "Low", Text = "Low" });
            // Set the default Priority value
            TicketForm.Priority = "Normal";
        }

 

Next, add the method that will handle the button click when the form is submitted:

 

        public async void OnPostCreateTicketAsync(string paramBearerToken)
        {
            if (paramBearerToken == null)
            {
                // Set error message
                Message = "The Auth Token is required";
            }
            else
            {
                // Format the fields
                DTOTask objDTOTask = new DTOTask();
                DTOTaskDetail objDTOTaskDetail = null;
                IFormFile objIFormFile = null;
                objDTOTask.createdDate = DateTime.Now.ToShortDateString();
                objDTOTask.requesterUserId = -1;
                objDTOTask.status = "New";
                objDTOTask.sendEmails = true;
                // Set values from form
                objDTOTask.description = TicketForm.Description;
                objDTOTask.dueDate = TicketForm.DueDate?.ToShortDateString();
                objDTOTask.priority = TicketForm.Priority;
                objDTOTask.requesterEmail = TicketForm.Email;
                objDTOTask.requesterName = TicketForm.Name;
                objDTOTask.requesterPhone = TicketForm.Phone;
                // Call the API
                var response = await CreateTicket(
                    objDTOTask,
                    objDTOTaskDetail,
                    objIFormFile,
                    _CustomSettings.APIWebAddress,
                    paramBearerToken);
                if (response.StatusMessage == "Unauthorized")
                {
                    // Set error message
                    Message = "The Auth Token is expired or invalid";
                }
                else
                {
                    // Save the Bearer Token
                    BearerToken = paramBearerToken;
                    if (response.Success)
                    {
                        Message = "Ticket Created!";
                    }
                    else
                    {
                        Message = response.StatusMessage;
                    }
                }
            }
            InitializeForm();
        }

 

Finally, add the code to implement the CreateTicket method that the code above calls:

 

        private static async Task<DTOStatus> CreateTicket(
            DTOTask paramDTOTask,
            DTOTaskDetail paramDTOTaskDetail,
            IFormFile paramIFormFile,
            string APIWebAddress,
            string paramBearerToken)
        {
            HttpResponseMessage response;
            DTOStatus Result = new DTOStatus();
            using (client)
            {
                client = new HttpClient();
                using (var request = new HttpRequestMessage())
                {
                    client.DefaultRequestHeaders.Authorization =
                        new AuthenticationHeaderValue("Bearer", paramBearerToken);
                    // Add Task parameters
                    var TaskParameters = paramDTOTask.ToKeyValue();
                    // If there are Task Details add them
                    if (paramDTOTaskDetail != null)
                    {
                        var TaskDetailParameters = paramDTOTaskDetail.ToKeyValue();
                        foreach (var item in TaskDetailParameters)
                        {
                            TaskParameters.Add(item);
                        }
                    }
                    request.RequestUri =
                        new Uri(QueryHelpers.AddQueryString(
                            $"{APIWebAddress}api/V1/CreateTask"
                            , TaskParameters));
                    request.Method = HttpMethod.Post;
                    // Send request
                    response = client.SendAsync(request).Result;
                    if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                    {
                        Result.Success = false;
                        Result.StatusMessage = "Unauthorized";
                        return Result;
                    }
                    var JsonDataResponse =
                        await response.Content.ReadAsStringAsync();
                    Result =
                        JsonConvert.DeserializeObject<DTOStatus>(JsonDataResponse);
                }
            }
            return Result;
        }

 

Note, the IFormFile paramIFormFile parameter is being passed but is not being implemented yet. We will use it to upload a file in the final section of this tutorial.

image

When we run the project, we can obtain an Auth Token, fill out the form, and submit a new Help Desk Ticket.

image

If we log into the ADefHelpDesk application, we can see the new Ticket.

Note: In this instance, the user specified in the Email parameter would be emailed a special link to the Ticket that allowed them to view and add comments to it. You can set a property to suppress emails on a per Ticket basis if needed. You also have the option to call the API method to create an account for a user and connect the Ticket to that account.

Upload A File

The ADefHelpDesk API allows a file to be uploaded when creating (or updating) a Help Desk Ticket.

It requires the file to be attached to a Task Detail object.

To hold the optional Detail text for the Task Detail object, add the following code to the form on the Index.cshtml page:

 

        <div class="row">
            <p class="col-md-1">Detail:</p>
            <p class="col-md-11">
            <textarea asp-for="@Model.TicketForm.Detail"></textarea></p>
        </div>

 

Also, add the following code to the form to allow a file to be uploaded:

 

        <div class="row">
            <p class="col-md-1">File:</p>
            <p class="col-md-11">
            <input type="file" asp-for="@Model.TicketForm.FormFile" /></p>
        </div>

 

In the Index.cshtml.cs file, add the following property to the Ticket class to hold the value of the file:

 

public IFormFile FormFile { get; set; }

 

Add the following code to the OnPostCreateTicketAsync method:

 

                // If there is a file we need a Task Detail
                if (TicketForm.FormFile != null)
                {
                    objDTOTaskDetail = new DTOTaskDetail();
                    // Note: this field is renamed from description to
                    // taskDetailDescription to prevent collision when passed
                    // as a parameter with the field description in the Task object
                    objDTOTaskDetail.taskDetailDescription = TicketForm.FormFile.FileName;
                    // Set File
                    objIFormFile = TicketForm.FormFile;
                }

 

Finally, in the CreateTicket method, remove the line:

 

response = client.SendAsync(request).Result;

 

Replace it with:

 

                    if (paramIFormFile != null)
                    {
                        using (var readStream = paramIFormFile.OpenReadStream())
                        {
                            MultipartFormDataContent _multiPartContent =
                                new MultipartFormDataContent();
                            // Serialize Request
                            StreamContent _fileData =
                                new StreamContent(readStream);
                            _fileData.Headers.ContentType =
                                new MediaTypeHeaderValue("application/octet-stream");
                            ContentDispositionHeaderValue _contentDispositionHeaderValue =
                                new ContentDispositionHeaderValue("form-data");
                            _contentDispositionHeaderValue.Name = "objFile";
                            _contentDispositionHeaderValue.FileName = paramIFormFile.FileName;
                            _fileData.Headers.ContentDisposition = _contentDispositionHeaderValue;
                            _multiPartContent.Add(_fileData, "objFile");
                            // Set content
                            request.Content = _multiPartContent;
                            // Send request
                            response = client.SendAsync(request).Result;
                        }
                    }
                    else
                    {
                        // Send request
                        response = client.SendAsync(request).Result;
                    }

 

 

image

Now we can upload a file when creating a new Help Desk Ticket.

image

If we upload a .EML file we can see its contents displayed in ADefHelpDesk, and any attachments in the .EML file will have download links.

If we upload a file that is not a .EML file, that file will display a download link.

 

Advantages Of A REST API

The ADefHelpDesk API demonstrates the power of using REST APIs. Rather than having multiple Help Desk applications to support your various applications, that require your users to exit the application to create a Ticket, you can use the API to allow your users to create tickets from inside those applications.

The API provides methods that will allow you to create a user account for the user, if needed, so their tickets can be tracked, and email notifications sent.

This allows a single installation of ADefHelpDesk to support unlimited applications, yet your support personnel manages it all from one interface. This also allows processes such as auto responders to periodically check for new tickets, and update, and route them.

 

Links

AdefHelpDesk (Documentation)

A Few Great Ways to Consume RESTful API in C#

https://www.asp.net/web-api

 

Download

The project is available at http://lightswitchhelpwebsite.com/Downloads.aspx

You must have Visual Studio 2017 (or higher) installed to run the code.

Tags: ADefHelpDesk
Categories:

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation