Wednesday, 22 March 2017

Azure Service Bus: Serialization operation failed due to unsupported type

When trying to add an object property to my Service Bus Queue, I encountered the following error:

"Serialization operation failed due to unsupported type RichardLeeman.Model.MyObject."

So I added the  [Serializable] annotation to the class, but to no avail. The issue seems to be that the property bag only likes simple types like int or string.

So, my simple fix was to convert the class to JSON and put that in the bus. I used System.Web.Script.Serialization.JavaScriptSerializer to convert the object and placed the resulting string in the property bag.

var client = QueueClient.CreateFromConnectionString(SERVICE_BUS_CNN, "myqueue");
var json = new JavaScriptSerializer().Serialize(myObjectInstance);
var message = new BrokeredMessage("my test message");
message.Properties.Add(new KeyValuePair<string, object>("MyObjectProperty",json));
client.Send(message);





Tuesday, 21 March 2017

Swagger: How do I add custom return codes to my Web API?

Swagger is great tool to document APIs, The standard return codes (200 - OK) do not always give enough detail about the endpoint. Fortunately, there are some simple annotations that can be added to give a better description about the return code.

using Swashbuckle.Swagger.Annotations;
using System.Web.Http;

namespace MyNameSpace
{
    public class MyAPIController : ApiController
    {
        [HttpGet]
        [Route("api/my_custom_api_route")]
        [SwaggerResponse(System.Net.HttpStatusCode.OK, "All good here, thanks for asking")]
        [SwaggerResponse(601, "foo message")]
        public bool MyAPI()
        {
            return true;
        }
    }
}

The result is as follows:



Monday, 20 March 2017

Azure: How do I delete my function?

I have been playing with Azure functions (which are great), but there does not seem to be an intuitive way to delete them.

The first option (which requires forethought) is to create its own Resource Group (with the associated storage accounts) and delete the RG. Easy - if you knew it was coming and planned for it.

The other option is go into 'Function App Settings'  -> 'Go to App Service Settings'.




You can then delete the app.


Thursday, 9 March 2017

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.

Azure SQL Database: Cannot connect to XXXXX.database.windows.net PART 2

My first attempt to resolve this issue (see this post), I was able to get past the first barrier.

However, for some reason, my SSO credentials were not working. My account was configured as the system administrator account, but I could not authenticate.

Then I remember that my user password was different AT THE TIME THE SQL SERVER INSTANCE WAS CREATED. I was successfully able to connect using SQL Authentication with my username and the OLD PASSWORD.

Azure SQL Database: Cannot connect to XXXXX.database.windows.net

While creating an Azure POC, I create a new SQL Database and tried to connect via the online tools. I then received the following message:



Fortunately, the resolution is very simple. Open the database and navigate to the Firewall Settings at the top of the Overview blade.

Select 'Add client IP' to resolve the problem.