Azure Function: Call a web service and return the result as a class
My current project is using Azure Functions as action triggers. Thanks to some nifty work from the Visual Studio team, we now have a local development environment.
The following POC function will call a Web API (configured through API Management) and convert the resultant JSON into a class object.
1. Create a 'Model' solution that stores the class to be used. I called my MyModel. My class is called ApiResult.
namespace MyModel
{
public class ApiResult
{
public string Message { get; set; }
}
}
2. Create an API to invoke
using MyModel;
using System.Web.Http;
namespace MyControllers
{
public class MyController : ApiController
{
[System.Web.Http.HttpGet]
[System.Web.Http.Route("api/myapiendpoint")]
public ApiResult ValidateFile()
{
return new ApiResult()
{
Message = "Success!"
};
}
}
}
3. Copy the MyModel.dll to a folder in my Azure Function folder (I called in References)
4. Here is the code to call the endpoint and return the result object
// add the dll references
#r "..\References\MyModel.dll"
#r "..\References\System.Runtime.Serialization.dll"
// add the namespaces
using System.Net;
using System.IO;
using System.Text;
using System.Runtime.Serialization.Json;
using MyModel;
// I used an HttpTrigger action for simplicity
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
// create a few constants to make things easier
const string WEBSERVICE_URL = @"http://myapimanagement.azure-api.net/api/myapiendpoint";
const string SUBSCRIPTION_KEY = @"123456";
try
{
// Call a method to do the work
ExecuteWebRequest(WEBSERVICE_URL, SUBSCRIPTION_KEY);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return req.CreateResponse(HttpStatusCode.OK);
}
private static void ExecuteWebRequest(string url, string key)
{
WebRequest webRequest = WebRequest.Create(url);
if (webRequest != null)
{
webRequest.Method = "GET";
webRequest.Timeout = 20000;
webRequest.ContentType = "application/json";
webRequest.ContentLength = 0;
// Add the subscription key to the header so the call will authenticate
webRequest.Headers.Add("Ocp-Apim-Subscription-Key", key);
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
// convert the Json to the base object
var jsonResponse = ReadApiResultToObject(sr.ReadToEnd());
}
}
}
}
private static ApiResult ReadApiResultToObject(string json)
{
ApiResult deserializedUser = new ApiResult();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedUser.GetType());
deserializedUser = ser.ReadObject(ms) as ApiResult;
}
return deserializedUser;
}
My biggest learning from this exercise is that the compilation is late bound, so any errors will be at runtime. So, make small changes and test often.
The following POC function will call a Web API (configured through API Management) and convert the resultant JSON into a class object.
1. Create a 'Model' solution that stores the class to be used. I called my MyModel. My class is called ApiResult.
namespace MyModel
{
public class ApiResult
{
public string Message { get; set; }
}
}
using MyModel;
using System.Web.Http;
namespace MyControllers
{
public class MyController : ApiController
{
[System.Web.Http.HttpGet]
[System.Web.Http.Route("api/myapiendpoint")]
public ApiResult ValidateFile()
{
return new ApiResult()
{
Message = "Success!"
};
}
}
}
3. Copy the MyModel.dll to a folder in my Azure Function folder (I called in References)
4. Here is the code to call the endpoint and return the result object
// add the dll references
#r "..\References\MyModel.dll"
#r "..\References\System.Runtime.Serialization.dll"
// add the namespaces
using System.Net;
using System.IO;
using System.Text;
using System.Runtime.Serialization.Json;
using MyModel;
// I used an HttpTrigger action for simplicity
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
// create a few constants to make things easier
const string WEBSERVICE_URL = @"http://myapimanagement.azure-api.net/api/myapiendpoint";
const string SUBSCRIPTION_KEY = @"123456";
try
{
// Call a method to do the work
ExecuteWebRequest(WEBSERVICE_URL, SUBSCRIPTION_KEY);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return req.CreateResponse(HttpStatusCode.OK);
}
private static void ExecuteWebRequest(string url, string key)
{
WebRequest webRequest = WebRequest.Create(url);
if (webRequest != null)
{
webRequest.Method = "GET";
webRequest.Timeout = 20000;
webRequest.ContentType = "application/json";
webRequest.ContentLength = 0;
// Add the subscription key to the header so the call will authenticate
webRequest.Headers.Add("Ocp-Apim-Subscription-Key", key);
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
// convert the Json to the base object
var jsonResponse = ReadApiResultToObject(sr.ReadToEnd());
}
}
}
}
private static ApiResult ReadApiResultToObject(string json)
{
ApiResult deserializedUser = new ApiResult();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedUser.GetType());
deserializedUser = ser.ReadObject(ms) as ApiResult;
}
return deserializedUser;
}
My biggest learning from this exercise is that the compilation is late bound, so any errors will be at runtime. So, make small changes and test often.
Comments
Post a Comment