Try for free Book a demo

Creating an Upsert with Azure Functions for a Table Storage Entity

Microsoft Azure

5 Mins Read

Storage-Entity

Azure Functions are great when you need small pieces of code, or “functions” in the cloud. You also get a lot of Templates with sample code to speed up the development even more. For most scenarios, this is sufficient but for more advanced scenarios however, there is not always a lot of documentation.

The “HttpPOST(CRUD)-C#” template for example, creates a C# Function that adds entities to a Storage Table when it receives a HTTP request. That is great but what if an entity already is stored in the Storage Table? In that case you probably want to update the entity in the Storage Table. This is what becomes called Upserts and in this article we’ll describe how you can achieve that with Azure Functions.

In the following section is described how to modify the generated code from the “HttpPOST(CRUD)-C#” Template, so that the function adds new orders to a Storage Table and modifies the order when it already exists in the Storage Table.

Creating Azure Functions in Visual Studio

You can use the Azure Portal to create Azure functions but in this demo Visual Studio is used to develop the function.

Once the Visual Studio Tools for Azure Functions Preview are installed, you can easily create a new Azure Functions project within Visual Studio 2015. In the New Project dialog, it’s located under Visual C# in the Cloud section.

Azure-Functions-New-Project-screen

To add a New Azure Function to the project:

  • Right-click on the Project within the Solution Explorer window
  • Click on Add, then New Azure Function

Azure-Functions-creating-a-new-function

Within the New Azure Function dialog, select the “HttpPOST(CRUD)-C#” Azure Function template from the list. This will create a C# Function that adds entities to a Storage Table when it receives a HTTP request.

HttpPOSTCRUD

The files created for a new Azure Functions project are similar when you would create an Azure Function through the Azure Portal.

Azure-Functions-Files-created

Modify the generated bindings in the function.json file. Use a variable named OrderStorage for the connection name and add an extra table parameter to be able to search and update in Azure Table Storage.

{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
],
"authLevel": "function"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "table",
"name": "outTable",
"tableName": "Orders",
"connection": "OrderStorage",
"direction": "out"
},
{
"name": "table",
"type": "table",
"connection": "OrderStorage",
"tableName": "Orders",
"direction": "in"
}
],
"disabled": false
}

In the appsettings.json file add the connection string to your Azure storage account.

{
"IsEncrypted": false,
"Values": {
"OrderStorage": "DefaultEndpointsProtocol=https;AccountName=myAccountName;AccountKey=myAccountKey"
}
}

In the run.csx file, add an extra table parameter in the function to be able to search for orders.  Then add the extra code to retrieve and update the order.

#r "Microsoft.WindowsAzure.Storage"

using System.Net;
using Microsoft.WindowsAzure.Storage.Table;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ICollector<Order> outTable, CloudTable table, TraceWriter log)
{
dynamic data = await req.Content.ReadAsAsync<object>();

string orderId = data?.OrderId;

TableOperation operation = TableOperation.Retrieve<Order>("Orders", orderId);
TableResult result = table.Execute(operation);

if (result.Result != null)
{
Order order = (Order)result.Result;
order.Name = data?.customer.Name;
order.City = data?.customer.City;
order.Brand = data?.item.Brand;
order.ProductType = data?.item.ProductType;
order.Article = data?.item.Article;
order.Amount = data?.item.Amount;

operation = TableOperation.Replace(order);
table.Execute(operation);
}
else
{
outTable.Add(new Order()
{
PartitionKey = "Orders",
RowKey = orderId,
Name = data?.customer.Name,
City = data?.customer.City,
Brand = data?.item.Brand,
ProductType = data?.item.ProductType,
Article = data?.item.Article,
Amount = data?.item.Amount
});
}

return req.CreateResponse(HttpStatusCode.Created);
}

public class Order : TableEntity
{
public string Name { get; set; }
public string City { get; set; }
public string Brand { get; set; }
public string ProductType { get; set; }
public string Article { get; set; }
public int Amount { get; set; }
}

Local Debugging

Azure Functions projects can be run on the local development machine. This is great because now you can set break points in Visual Studio and debug the Azure Function locally.

Azure-Functions-debug-the-function

When you try to run the Azure Project and the bindings in the function.json file are not correct, you get an error message that the Connection string is missing.

Error-Message

Also note that when the connection string of your Azure storage account is not correct, you get another error message that the initialization of the ScripHost failed when you try to run the Azure Function.

initialization-failed

When all settings are correct, the Azure Function can be tested with a tool like Postman.

testing-using-postman

After the HTTP request is posted use the Azure Storage Explorer, tool to see it the order is added and also modified in Table Storage.

Azure-Storage-Explorer

Conclusion

I really like Azure Functions because you get a lot of functionality out of the box. However, the part I didn’t like was developing in the Azure Portal, but this is now solved by using the Visual Studio Tools. The only thing I now wish for, is a little bit more documentation and then Azure Functions is really awesome!

This article was published on Feb 1, 2017.

Related Articles