Share via


Migrating a WCF Service to an API App

Introduction

I recently responded to a question about moving or re-implementing an existing WCF Service running on a BizTalk cluster. The customer wanted to utilize Azure Logic Apps instead of BizTalk on premise.  The WCF Service is running as a Windows Service.

  1. Create a Swagger for a new API that will replace the WCF Service.

    NOTE: When creating your Swagger, add descriptions for each operation and parameter

  2. Use the same signature (operation names and input parameters) for the Methods in the WCF Service.

  3. Create a new Azure API App in Visual Studio.

  4. You can include Application Insights as an option.

  5. Using the add REST API CLIENT,  Select an existing  Swagger metadata file, as shown below.

  6. Use the Swagger that you created.

https://docdb.info/wp-content/uploads/2016/01/AddRestApi.png

The following figure is a sample showing the classes created.
https://docdb.info/wp-content/uploads/2016/01/vs-project.png

The generated code will include Models, which represent Request and Response objects.

There are three additional classes created.

// Code generated by Microsoft (R) AutoRest Code Generator 0.9.7.0
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
 
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using DocDbStoredProcApi.Models;
using Microsoft.Rest;
 
namespace DocDbStoredProcApi
{
    /// <summary>
    /// 
    /// </summary>
    public interface  IDocDbSpApi : IDisposable
    {
        /// <summary>
        ///     The base URI of the service.
        /// </summary>
        Uri BaseUri { get; set; }
 
        /// <summary>
        ///     Credentials for authenticating with the service.
        /// </summary>
        ServiceClientCredentials Credentials { get; set; }
 
        /// <summary>
        ///     Returns the Response as a string
        /// </summary>
        /// <param name='storedProcedureId'>
        ///     Required. Stored Procedure Id
        /// </param>
        /// <param name='queryRequest'>
        ///     Required. The Query body
        /// </param>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        Task<HttpOperationResponse<StoredProcedureResponse>> ExecuteAStoredProcedureWithOperationResponseAsync(
            string storedProcedureId, QueryRequest queryRequest,
            CancellationToken cancellationToken = default(CancellationToken));
 
        /// <summary>
        ///     Get an array of all stored procedures.
        ///     - Read the feed 10 items at a time until there are no more items to
        ///     read
        /// </summary>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        Task<HttpOperationResponse<IList<StoredProcedure>>> GetListOfStoredProceduresWithOperationResponseAsync(
            CancellationToken cancellationToken = default(CancellationToken));
    }
}
DocDbSpAPI.cs

The following is a sample of the code generated.

// Code generated by Microsoft (R) AutoRest Code Generator 0.9.7.0
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
 
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DocDbStoredProcApi.Models;
using Microsoft.Rest;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
 
namespace DocDbStoredProcApi
{
    /// <summary>
    /// 
    /// </summary>
    public class  DocDbSpApi : ServiceClient<DocDbSpApi>, IDocDbSpApi
    {
        /// <summary>
        ///     Initializes a new instance of the DocDbSpApi class.
        /// </summary>
        public DocDbSpApi()
        {
            BaseUri = new  Uri("https://docdbspapi.azurewebsites.net");
        }
 
        /// <summary>
        ///     Initializes a new instance of the DocDbSpApi class.
        /// </summary>
        /// <param name='handlers'>
        ///     Optional. The set of delegating handlers to insert in the http
        ///     client pipeline.
        /// </param>
        public DocDbSpApi(params DelegatingHandler[] handlers)
            : base(handlers)
        {
            BaseUri = new  Uri("https://docdbspapi.azurewebsites.net");
        }
 
        /// <summary>
        ///     Initializes a new instance of the DocDbSpApi class.
        /// </summary>
        /// <param name='rootHandler'>
        ///     Optional. The http client handler used to handle http transport.
        /// </param>
        /// <param name='handlers'>
        ///     Optional. The set of delegating handlers to insert in the http
        ///     client pipeline.
        /// </param>
        public DocDbSpApi(HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
            : base(rootHandler, handlers)
        {
            BaseUri = new  Uri("https://docdbspapi.azurewebsites.net");
        }
 
        /// <summary>
        ///     Initializes a new instance of the DocDbSpApi class.
        /// </summary>
        /// <param name='baseUri'>
        ///     Optional. The base URI of the service.
        /// </param>
        /// <param name='handlers'>
        ///     Optional. The set of delegating handlers to insert in the http
        ///     client pipeline.
        /// </param>
        public DocDbSpApi(Uri baseUri, params DelegatingHandler[] handlers)
            : this(handlers)
        {
            if (baseUri == null)
            {
                throw new  ArgumentNullException(nameof(baseUri));
            }
            BaseUri = baseUri;
        }
 
        /// <summary>
        ///     Initializes a new instance of the DocDbSpApi class.
        /// </summary>
        /// <param name='credentials'>
        ///     Required. Credentials for authenticating with the service.
        /// </param>
        /// <param name='handlers'>
        ///     Optional. The set of delegating handlers to insert in the http
        ///     client pipeline.
        /// </param>
        public DocDbSpApi(ServiceClientCredentials credentials,  params  DelegatingHandler[] handlers)
            : this(handlers)
        {
            if (credentials == null)
            {
                throw new  ArgumentNullException(nameof(credentials));
            }
            Credentials = credentials;
 
            Credentials?.InitializeServiceClient(this);
        }
 
        /// <summary>
        ///     Initializes a new instance of the DocDbSpApi class.
        /// </summary>
        /// <param name='baseUri'>
        ///     Optional. The base URI of the service.
        /// </param>
        /// <param name='credentials'>
        ///     Required. Credentials for authenticating with the service.
        /// </param>
        /// <param name='handlers'>
        ///     Optional. The set of delegating handlers to insert in the http
        ///     client pipeline.
        /// </param>
        public DocDbSpApi(Uri baseUri, ServiceClientCredentials credentials, params  DelegatingHandler[] handlers)
            : this(handlers)
        {
            if (baseUri == null)
            {
                throw new  ArgumentNullException(nameof(baseUri));
            }
            if (credentials == null)
            {
                throw new  ArgumentNullException(nameof(credentials));
            }
            BaseUri = baseUri;
            Credentials = credentials;
 
            Credentials?.InitializeServiceClient(this);
        }
 
        /// <summary>
        ///     The base URI of the service.
        /// </summary>
        public Uri BaseUri { get; set; }
 
        /// <summary>
        ///     Credentials for authenticating with the service.
        /// </summary>
        public ServiceClientCredentials Credentials { get; set; }
 
        /// <summary>
        ///     Returns the Response as a string
        /// </summary>
        /// <param name='storedProcedureId'>
        ///     Required. Stored Procedure Id
        /// </param>
        /// <param name='queryRequest'>
        ///     Required. The Query body
        /// </param>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        public Task<HttpOperationResponse<StoredProcedureResponse>> ExecuteAStoredProcedureWithOperationResponseAsync(string storedProcedureId, QueryRequest queryRequest,
            CancellationToken cancellationToken = new  CancellationToken())
        {
            throw new  NotImplementedException();
        }
 
        /// <summary>
        ///     Get an array of all stored procedures.
        ///     - Read the feed 10 items at a time until there are no more items to
        ///     read
        /// </summary>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        public Task<HttpOperationResponse<IList<StoredProcedure>>> GetListOfStoredProceduresWithOperationResponseAsync(CancellationToken cancellationToken = new  CancellationToken())
        {
            throw new  NotImplementedException();
        }
 
        /// <summary>
        ///     Returns the Response as a string
        /// </summary>
        /// <param name='storedProcedureId'>
        ///     Required. Stored Procedure Id
        /// </param>
        /// <param name='queryRequest'>
        ///     Required. The Query body
        /// </param>
        /// <param name='ridDB'>
        ///     Required. The Database Id
        /// </param>
        /// <param name='ridColl'>
        ///     Required. The Collection Id
        /// </param>
        /// <param name='ridProc'>
        ///     Required. The Proc Id
        /// </param>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        public async Task<HttpOperationResponse<StoredProcedureResponse>>
            ExecuteAStoredProcedureWithOperationResponseAsync(string storedProcedureId, QueryRequest queryRequest,
                string ridDB, string ridColl, string ridProc,
                CancellationToken cancellationToken = default(CancellationToken))
        {
            // Validate
            if (storedProcedureId == null)
            {
                throw new  ArgumentNullException(nameof(storedProcedureId));
            }
            if (queryRequest == null)
            {
                throw new  ArgumentNullException(nameof(queryRequest));
            }
            if (ridDB == null)
            {
                throw new  ArgumentNullException(nameof(ridDB));
            }
            if (ridColl == null)
            {
                throw new  ArgumentNullException(nameof(ridColl));
            }
            if (ridProc == null)
            {
                throw new  ArgumentNullException(nameof(ridProc));
            }
 
            // Tracing
            var shouldTrace = ServiceClientTracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = ServiceClientTracing.NextInvocationId.ToString();
                var tracingParameters = new  Dictionary<string, object>
                {
                    {nameof(storedProcedureId), storedProcedureId},
                    {"queryRequest", queryRequest},
                    {"ridDB", ridDB},
                    {"ridColl", ridColl},
                    {"ridProc", ridProc}
                };
                ServiceClientTracing.Enter(invocationId, this, "ExecuteAStoredProcedureAsync", tracingParameters);
            }
 
            // Construct URL
            var url = "";
            url = url + "/";
            url = url + Uri.EscapeDataString(ridDB);
            url = url + "/colls/";
            url = url + Uri.EscapeDataString(ridColl);
            url = url + "/sprocs/";
            url = url + Uri.EscapeDataString(ridProc);
            var queryParameters = new  List<string> {"StoredProcedureId=" + Uri.EscapeDataString(storedProcedureId)};
            if (queryParameters.Count > 0)
            {
                url = url + "?" + string.Join("&", queryParameters);
            }
            var baseUrl = BaseUri.AbsoluteUri;
            // Trim '/' character from the end of baseUrl and beginning of url.
            if (baseUrl[baseUrl.Length - 1] == '/')
            {
                baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
            }
            if (url[0] == '/')
            {
                url = url.Substring(1);
            }
            url = baseUrl + "/" + url;
            url = url.Replace(" ", "%20");
 
            // Create HTTP transport objects
            using (var httpRequest = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = new  Uri(url)
            })
            {
 
                // Set Headers
 
                // Set Credentials
                if (Credentials != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                }
 
                // Serialize Request
 
                var requestDoc = queryRequest.SerializeJson(null);
                var requestContent = requestDoc.ToString(Formatting.Indented);
                httpRequest.Content = new  StringContent(requestContent, Encoding.UTF8);
                httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
 
                // Send Request
                if (shouldTrace)
                {
                    ServiceClientTracing.SendRequest(invocationId, httpRequest);
                }
                cancellationToken.ThrowIfCancellationRequested();
                var httpResponse = await HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                if (shouldTrace)
                {
                    ServiceClientTracing.ReceiveResponse(invocationId, httpResponse);
                }
                var statusCode = httpResponse.StatusCode;
                cancellationToken.ThrowIfCancellationRequested();
                var responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                if (statusCode != HttpStatusCode.OK && statusCode != HttpStatusCode.BadRequest &&
                    statusCode != HttpStatusCode.InternalServerError)
                {
                    var ex = new  HttpOperationException
                    {
                        Request = httpRequest,
                        Response = httpResponse,
                        Body = null
                    };
                    if (shouldTrace)
                    {
                        ServiceClientTracing.Error(invocationId, ex);
                    }
                    throw ex;
                }
 
                // Create Result
                var result = new  HttpOperationResponse<StoredProcedureResponse>
                {
                    Request = httpRequest,
                    Response = httpResponse
                };
 
                // Deserialize Response
                if (statusCode == HttpStatusCode.OK)
                {
                    var resultModel = new  StoredProcedureResponse();
                    JToken responseDoc = null;
                    if (string.IsNullOrEmpty(responseContent) == false)
                    {
                        responseDoc = JToken.Parse(responseContent);
                    }
                    if (responseDoc != null)
                    {
                        resultModel.DeserializeJson(responseDoc);
                    }
                    result.Body = resultModel;
                }
 
                if (shouldTrace)
                {
                    ServiceClientTracing.Exit(invocationId, result);
                }
                return result;
            }
        }
 
        /// <summary>
        ///     Get an array of all stored procedures.
        ///     - Read the feed 10 items at a time until there are no more items to
        ///     read
        /// </summary>
        /// <param name='ridDB'>
        ///     Required. The Database Id
        /// </param>
        /// <param name='ridColl'>
        ///     Required. The Collection Id
        /// </param>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        public async Task<HttpOperationResponse<IList<StoredProcedure>>>
            GetListOfStoredProceduresWithOperationResponseAsync(string ridDB, string ridColl,
                CancellationToken cancellationToken = default(CancellationToken))
        {
            // Validate
            if (ridDB == null)
            {
                throw new  ArgumentNullException(nameof(ridDB));
            }
            if (ridColl == null)
            {
                throw new  ArgumentNullException(nameof(ridColl));
            }
 
            // Tracing
            var shouldTrace = ServiceClientTracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = ServiceClientTracing.NextInvocationId.ToString();
                var tracingParameters = new  Dictionary<string, object> {{"ridDB", ridDB}, {"ridColl", ridColl}};
                ServiceClientTracing.Enter(invocationId, this, "GetListOfStoredProceduresAsync", tracingParameters);
            }
 
            // Construct URL
            var url = "";
            url = url + "/";
            url = url + Uri.EscapeDataString(ridDB);
            url = url + "/colls/";
            url = url + Uri.EscapeDataString(ridColl);
            url = url + "/sprocs";
            var baseUrl = BaseUri.AbsoluteUri;
            // Trim '/' character from the end of baseUrl and beginning of url.
            if (baseUrl[baseUrl.Length - 1] == '/')
            {
                baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
            }
            if (url[0] == '/')
            {
                url = url.Substring(1);
            }
            url = baseUrl + "/" + url;
            url = url.Replace(" ", "%20");
 
            // Create HTTP transport objects
            var httpRequest = new  HttpRequestMessage
            {
                Method = HttpMethod.Get,
                RequestUri = new  Uri(url)
            };
 
            // Set Credentials
            if (Credentials != null)
            {
                cancellationToken.ThrowIfCancellationRequested();
                await Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);
            }
 
            // Send Request
            if (shouldTrace)
            {
                ServiceClientTracing.SendRequest(invocationId, httpRequest);
            }
            cancellationToken.ThrowIfCancellationRequested();
            var httpResponse = await HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
            if (shouldTrace)
            {
                ServiceClientTracing.ReceiveResponse(invocationId, httpResponse);
            }
            var statusCode = httpResponse.StatusCode;
            cancellationToken.ThrowIfCancellationRequested();
            var responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
            if (statusCode != HttpStatusCode.OK && statusCode != HttpStatusCode.NotFound && (int) statusCode != 429 &&
                statusCode != HttpStatusCode.InternalServerError)
            {
                var ex = new  HttpOperationException
                {
                    Request = httpRequest,
                    Response = httpResponse,
                    Body = null
                };
                if (shouldTrace)
                {
                    ServiceClientTracing.Error(invocationId, ex);
                }
                throw ex;
            }
 
            // Create Result
            var result = new  HttpOperationResponse<IList<StoredProcedure>>
            {
                Request = httpRequest,
                Response = httpResponse
            };
 
            // Deserialize Response
            if (statusCode == HttpStatusCode.OK)
            {
                IList<StoredProcedure> resultModel = new  List<StoredProcedure>();
                JToken responseDoc = null;
                if (string.IsNullOrEmpty(responseContent) == false)
                {
                    responseDoc = JToken.Parse(responseContent);
                }
                if (responseDoc != null)
                {
                    resultModel = StoredProcedureCollection.DeserializeJson(responseDoc);
                }
                result.Body = resultModel;
            }
 
            if (shouldTrace)
            {
                ServiceClientTracing.Exit(invocationId, result);
            }
            return result;
        }
    }
}
DocDbSpAPIExtensions.cs

This is the class that you use in your Controller.

The following is a sample of the code generated.

// Code generated by Microsoft (R) AutoRest Code Generator 0.9.7.0
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
 
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using DocDbStoredProcApi.Models;
 
namespace DocDbStoredProcApi
{
    /// <summary>
    /// 
    /// </summary>
    public static  class DocDbSpApiExtensions
    {
        /// <summary>
        ///     Returns the Response as a string
        /// </summary>
        /// <param name='operations'>
        ///     Reference to the DocDbStoredProcApi.IDocDbSpApi.
        /// </param>
        /// <param name='storedProcedureId'>
        ///     Required. Stored Procedure Id
        /// </param>
        /// <param name='queryRequest'>
        ///     Required. The Query body
        /// </param>
        /// <param name='ridDB'>
        ///     Required. The Database Id
        /// </param>
        /// <param name='ridColl'>
        ///     Required. The Collection Id
        /// </param>
        /// <param name='ridProc'>
        ///     Required. The Proc Id
        /// </param>
        public static  StoredProcedureResponse ExecuteAStoredProcedure(this IDocDbSpApi operations,
            string storedProcedureId, QueryRequest queryRequest,  string  ridDB, string  ridColl, string  ridProc)
        {
            return
                Task.Factory.StartNew(
                    s => ((IDocDbSpApi) s).ExecuteAStoredProcedureAsync(storedProcedureId, queryRequest, ridDB,
                        ridColl, ridProc), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)
                    .Unwrap()
                    .GetAwaiter()
                    .GetResult();
        }
 
        /// <summary>
        ///     Returns the Response as a string
        /// </summary>
        /// <param name='operations'>
        ///     Reference to the DocDbStoredProcApi.IDocDbSpApi.
        /// </param>
        /// <param name='storedProcedureId'>
        ///     Required. Stored Procedure Id
        /// </param>
        /// <param name='queryRequest'>
        ///     Required. The Query body
        /// </param>
        /// <param name='ridDB'>
        ///     Required. The Database Id
        /// </param>
        /// <param name='ridColl'>
        ///     Required. The Collection Id
        /// </param>
        /// <param name='ridProc'>
        ///     Required. The Proc Id
        /// </param>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        public static  async Task<StoredProcedureResponse> ExecuteAStoredProcedureAsync(this IDocDbSpApi operations,
            string storedProcedureId, QueryRequest queryRequest,  string  ridDB, string  ridColl, string  ridProc,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var result =
                await
                    operations.ExecuteAStoredProcedureWithOperationResponseAsync(storedProcedureId, queryRequest, ridDB,
                        ridColl, ridProc, cancellationToken).ConfigureAwait(false);
            return result.Body;
        }
 
        /// <summary>
        ///     Get an array of all stored procedures.
        ///     - Read the feed 10 items at a time until there are no more items to
        ///     read
        /// </summary>
        /// <param name='operations'>
        ///     Reference to the DocDbStoredProcApi.IDocDbSpApi.
        /// </param>
        /// <param name='ridDB'>
        ///     Required. The Database Id
        /// </param>
        /// <param name='ridColl'>
        ///     Required. The Collection Id
        /// </param>
        public static  IList<StoredProcedure> GetListOfStoredProcedures(this IDocDbSpApi operations, string ridDB,
            string ridColl)
        {
            return
                Task.Factory.StartNew(
                    s => ((IDocDbSpApi) s).GetListOfStoredProceduresAsync(ridDB, ridColl), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)
                    .Unwrap()
                    .GetAwaiter()
                    .GetResult();
        }
 
        /// <summary>
        ///     Get an array of all stored procedures.
        ///     - Read the feed 10 items at a time until there are no more items to
        ///     read
        /// </summary>
        /// <param name='operations'>
        ///     Reference to the DocDbStoredProcApi.IDocDbSpApi.
        /// </param>
        /// <param name='ridDB'>
        ///     Required. The Database Id
        /// </param>
        /// <param name='ridColl'>
        ///     Required. The Collection Id
        /// </param>
        /// <param name='cancellationToken'>
        ///     Cancellation token.
        /// </param>
        public static  async Task<IList<StoredProcedure>> GetListOfStoredProceduresAsync(this IDocDbSpApi operations,
            string ridDB, string ridColl, CancellationToken cancellationToken =  default(CancellationToken))
        {
            var result =
                await
                    operations.GetListOfStoredProceduresWithOperationResponseAsync(ridDB, ridColl, cancellationToken)
                        .ConfigureAwait(false);
            return result.Body;
        }
    }
}

The next step is to create a Controller class.  This is the class where you will be adding in your existing code from the operations in the WCF Service.  The following is an example of a controller class.

using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using DocDbStoredProcApi.Models;
using Swashbuckle.Swagger.Annotations;
using TRex.Metadata;
 
namespace DocDbStoredProcApi.Controllers
{
    /// <summary>
    ///     DocumentDB Stored Procedure Controller
    /// </summary>
    public class  StoredProcedureController : ApiController
    {
        
 
        /// <summary>
        ///     Execute a Stored Procedure
        /// </summary>
        /// <remarks>Returns the Response as a string</remarks>
        /// <param name="StoredProcedureId">Stored Procedure Id</param>
        /// <param name="queryRequest">SQL Query</param>
        /// <param name="RidDb">Database Id</param>
        /// <param name="RidColl">Collection Id</param>
        /// <param name="operations">IDocDbSpApi</param>
        /// <response code="200">OK</response>
        /// <response code="400">BadRequest -The syntax of the SQL statement is incorrect</response>
        /// <response code="500">Internal Server Error</response>
        /// <returns>Result of Stored Procedure Execution</returns>
        [Metadata("Execute a Stored Procedure")]
        [Route("{DatabaseId}/colls/{CollectioId}/sprocs/{SprocId}")]
        [SwaggerResponse(HttpStatusCode.OK)]
        [SwaggerResponse(HttpStatusCode.BadRequest)]
        [SwaggerResponse(HttpStatusCode.InternalServerError)]
        [SwaggerOperation("ExecuteStoredProcedure")]
        public async Task<StoredProcedureResponse> ExecuteStoredProcedureAsync(
            [Metadata("Stored Procedure Id")] string  StoredProcedureId,
            [Metadata("Query Request body")] [FromBody] QueryRequest queryRequest,
            [Metadata("Database Id")] string  RidDb,
            [Metadata("Collection Id ")] string  RidColl,
            [Metadata(nameof(IDocDbSpApi))] IDocDbSpApi operations)
        {
            var sprcResponse =
                await
                    operations.ExecuteAStoredProcedureAsync(StoredProcedureId, queryRequest, RidDb,
                       RidColl, StoredProcedureId);
 
 
            return sprcResponse;
        }
 
 
 
 
        /// <summary>
        /// Get Stored Procedures List
        /// </summary>
        /// <remarks>Get an array of all stored procedures</remarks>
        /// <param name="operations"></param>
        /// <param name="ridDB"></param>
        /// <param name="ridColl"></param>
        /// <response code="200">OK</response>
        /// <response code="404">Not Found - This means the resource feed you tried to read did not exist.</response>
        /// <response code="429">TooManyRequests - This means you have exceeded the number of request units per second. </response>
        /// <response code="500">Internal Server Error</response>
        /// <returns>StoredProcedures</returns>
        [Metadata("Get Stored Procedures List")]
        [Route("{DatabaseId}/colls/{CollectioId}/sprocs")]
        [SwaggerResponse(HttpStatusCode.OK)]
        [SwaggerResponse(HttpStatusCode.NotFound)]
        [SwaggerResponse(HttpStatusCode.InternalServerError)]
        [SwaggerResponse(429, "Too Many Requests")]
        [SwaggerOperation("GetListOfStoredProcedures")]
        public IList<StoredProcedure> GetListOfStoredProcedures(
           [Metadata(nameof(IDocDbSpApi))] IDocDbSpApi operations,
           [Metadata("Database Id")] string  ridDB,
           [Metadata("Collection Id ")] string  ridColl)
        {
            return
                Task.Factory.StartNew(
                    s => ((IDocDbSpApi)s).GetListOfStoredProceduresAsync(ridDB, ridColl), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)
                    .Unwrap()
                    .GetAwaiter()
                    .GetResult();
        }
    }
}

In the above example, the methods are decorated with attributes.  It is a Best Practice to use the Swagger attributes.

[SwaggerResponse(HttpStatusCode.OK)]
[SwaggerResponse(HttpStatusCode.NotFound)]
[SwaggerResponse(HttpStatusCode.InternalServerError)]
[SwaggerOperation(“GetListOfStoredProcedures”)]

Just add *using Swashbuckle.Swagger.Annotations; *