Skip to main content

Azure Functions - Common Developer Requirements


In this blog, I am going to cover some of the most frequent issues/requirements people face when developing Azure Functions via Visual Studio. These topics are based on my learnings while developing Azure Functions and I wanted to share the same with community out there.

Here are the topics that I will cover in this blog post -

  1. Local Debugging of Service Bus Triggered Azure Functions
  2. Solving CORS Issue - Local Debugging and after deployment to Azure
  3. Run Azure Functions Locally on a different Port
  4. Debug Timer Triggered Azure Functions


So let's get started.

  1. Local Debugging of Service Bus Triggered Azure Functions

When you try to debug your Service Bus triggered Azure Function locally, you would need to ensure that there are no other listeners active for your Service Bus Topic and Subscription. Listeners here refer to other people trying to debug on same Service Bus, Topic and Subscription, other Azure Functions or any WebJobs deployed on Azure and running continuously and listening to same Service Bus, etc. This is important because if there are other listeners active for the same Service Bus, Topic and Subscription combination, then there is a HIGH chance that the messages might get picked up by other listeners and your Debug point is not hit. 

The approach mentioned below works for both version 1 and version 2 of Azure Functions.

Having said that, now lets set up our local environment to be able to debug the Service Bus Triggered Azure Function - 
  • Place a break point in the Azure Function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace ASBListenerNameSpace
{
    public static class ASBListener
    {
        [FunctionName("ASbListener")]
        public static void Run([ServiceBusTrigger("test", "test", Connection = "SBConnectionString")]string mySbMsg, ILogger log)
        {
            log.LogInformation($"C# ServiceBus topic trigger function processed message: {mySbMsg}");
        }
    }
}

  • Add a localsettings.json file in your Azure Functions project and ensure it has the Service Bus Connection string added to it.

1
2
3
4
5
6
7
8
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "SBConnectionString": "Your-Service-Bus-connection-string-goes-here"
  }
}

  • Run the Azure Function by pressing F5


  • Send a message to Service Bus Topic.
  • You will see that your break point is hit in Visual Studio and if you analyze the message parameter, it will have the message contents that was just sent to Service Bus Topic.


  1. Solving CORS Issue - while Local Debugging and after deployment to Azure

Often when we develop HTTP Triggered Azure Functions, we can easily test them out using Postman or VS Code, but there are scenarios when we are using the HTTP Triggered Azure Functions from within another Web Application, and during debugging locally, we might encounter CORS issue and the error as follows -

Access to XMLHttpRequest at 'http://localhost:5860/api/Function1' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here is a sample HTML app that i build to demonstrate this issue, it has a button and a div tag to show output of the response returned by Azure Function - 



And here is the output that my Azure Function returns upon calling via Get HTTP method -



Now when I click on the Test Azure Function button, internally it will invoke the Azure Function URL via AJAX and then return the response if all good, else return a user friendly message in case of an error -



You can see the CORS error being logged in browser console window on the right.

CORS issue is basically because our Web Application and Azure Functions are running on a different port, thereby making their origins different. The same scenario will occur if you deploy the Web Application and Azure Function to Azure.

To solve this issue, we need to enable CORS in our Azure Function project. This will take care of our local debugging requirements of allowing CORS. For the deployed version on Azure, we need to enable CORS in the deployed Azure Function App Service in Azure.

Let's tackle both these scenarios one by one.

First, the local debugging issue. So, to enable CORS in your Azure Functions project, from within Visual Studio go to localsettings.json file within your project and add an entry for CORS like shown below -



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  },
  "Host": {
    "LocalHttpPort": 7079,
    "CORS": "*"
  }
}


Now, if you restart the Azure Function by pressing F5, and click on the Test Azure Function again, you should see the output returned by Azure Function being displayed in the UI, and no error this time in the browser console window -





So we have successfully enabled CORS in our Azure Function via localsettings.json file and this will take care of the local debugging scenario that we were talking about.

Now about the deployed version of Azure Function on Azure, you need to follow below steps to enable CORS there -

  • Navigate to your Function App in Azure
  • Go to Platform Features -> CORS
  • Then in the Allowed Origins section, add all your origin URLs that will be calling your Azure Function. To enable all origins, just enter * there.
  • Save and restart your Function App.
That it, this will take care of CORS for your deployed Function App in Azure now.


  1. Run Azure Functions Locally on a different Port

Often people encounter this issue when the default port used by Azure Functions CLI i.e. 7071 is already used by any other process and when we try to debug Azure Function locally, we get this error-

Port 7071 is unavailable. Close the process using that port, or specify another port using --port [-p].

Now in order to overcome this error, you have two options,

  • Either ensure that the port 7071 is not used by any other process
  • Configure your Azure Functions project so that it runs on a different port.

Second option is more easy and straight forward, as we never know if the port 7071 is going to be used again by any other process. Hence here are the simple steps to run Azure Functions on a different port -

  • In your localsettings.json, add a entry for LocalHttpPort, and specify the port number that you want your Azure Function to run on.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  },
  "Host": {
    "LocalHttpPort": 7079
  }
}

  • Go to your Azure Functions project properties, and add below command in Application Arguments section under Debug
host start --pause-on-error
  • Now run the Azure Function again by pressing F5 and you will see your Function running on the port specified in localsettings.json file.



  • Alternatively, you can just specify the port number in the Application arguments like below, and you don't have to add anything in localsettings.json file.
host start --pause-on-error --port 5860

  • An interesting point to notice here is that if you specify the port in both places - in localsettings.json and in Application Arguments also, then your Application Arguments will take precedence and your Azure Function will run on the port number specified in the Application Arguments itself. This can be an interview question though, right ? 😃😃

  1. Debug Timer Triggered Azure Functions

Debugging Timer Triggered Azure Functions can be a little tricky, as unlike HTTP or Service Bus Triggered Azure Functions, you can't really invoke them via a Request or Message. However with the right knowledge, you can Debug Timer Triggered Azure Functions as well in a really simple way.

Let's say our Timer Triggered Azure Function looks like this -



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace FunctionApp1
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        }
    }
}

So our NCRONTAB Expression for Timer Trigger is 0 */5 * * * * this tells Functions CLI that the Azure Function should run every 5 minutes. You can read more about NCRONTAB Expressions here.

Now if you run this Azure Function by pressing F5, you will see that Functions CLI automatically detects your NCRONTAB expression, and also list down the next 5 schedules of your Function run in the CLI command window -



Now you can either wait for the schedule to see the break point being hit, or add the RunOnStartup attribute to your Function method. This attribute ensures that whenever you run your Azure Function locally, your debug point will hit. Basically it does what its name suggests, it runs your Function Code on startup. 🙂

So, your Function Class should look like this after adding the RunOnStartup attribute -



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace FunctionApp1
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static void Run([TimerTrigger("0 */5 * * * *", RunOnStartup = true)]TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        }
    }
}
    


Now if you run your Azure Function by pressing F5, you will see your break point being hit.




Hope this read was helpful to you.
Happy Learning !! 🙂🙂

Comments

  1. Microsoft azure has it own unique features. I am also the learner of Microsoft azure

    ReplyDelete
  2. Are you looking to know about azure cloud migration services. This blog provides a completed guide on it. Keep sharing like this informative blog.
    azure cloud migration services

    ReplyDelete

Post a Comment

Popular posts from this blog

Handling Concurrency in Azure Functions (HTTP Triggered)

Concurrency & Isolation Concurrency is one of the most common requirements when we don't want the resource to be accessed by multiple requests at the same time. Lets say we have a Database that holds products stock information, then it is very important that any read/write operation that happens on the Database must hold the property of Isolation . The isolation property ensures that the concurrent execution of transactions results in a system state that would be obtained if transactions were executed sequentially, i.e., one after the other. Providing isolation is the main goal of concurrency control. Depending on the concurrency control method (i.e., if it uses strict – as opposed to relaxed – serializability), the effects of an incomplete transaction might not even be visible to another transaction. Options Available in Azure Functions Recently while working on Azure Functions, I discovered a really simple way of handling Concurrency via code. There are ways to con

Azure Functions - Retrieve data from Dynamics 365 CRM/CE Online using CRM OData Web API

Introduction: This blog describes how you can retrieve data from Dynamics 365 CRM/CE Online in an Azure Function, using CRM OData Web API. The CRM Web API has a couple of advantages over the traditional SOAP based approach to interact with CRM. These are rest based services, its easy to use and transport over http protocol , and there is no need to use additional web resources (XrmServiceToolkit ) of SDK (SDK.REST). Here is a detailed documentation on CRM OData Wbeb API. I will be using an Azure Function Application in Visual Studio 2017 to retrieve records from Dynamics 365 CRM/CE, by making use of OData API Endpoint provided by CRM. Prerequisites: Dynamics 365 CRM Online Trial https://trials.dynamics.com/ https://signup.microsoft.com/Signup?OfferId=bd569279-37f5-4f5c-99d0-425873bb9a4b&dl=DYN365_ENTERPRISE_PLAN1&Culture=en-us&Country=us&ali=1 Azure Subscription related to CRM Online instance https://portal.azure.com/ Visual Studio 2017 with Cl

Retrieve 5000+ Records in Dynamics 365 CE using CRM OData, Fetch XML and C#

If you want to retrieve 5000+ records in Dynamics 365 CE, you need to make use of Paging concept of CRM. By default 5000 records are retrieved in a single OData call in CRM. To get more, you need to make subsequent calls to OData Endpoint by passing a paging cookie in the request. I will be using a simple C# Console Application to retrieve 5000+ records from Dynamics 365 CE, by making use of OData API Endpoint provided by CRM and passing Fetch XML in OData Call . Concept: CRM OData Endpoints allows us to use Fetch XML to retrieve data from Microsoft Dynamics 365 CE.  If your resultset has more than 5000 records, you will be returned with first 5000 records ONLY in one OData call. To know if the resultset has more than 5000 records, we make use of the response from OData call. The response is added with a cookie value contained in a key - "@Microsoft.Dynamics.CRM.fetchxmlpagingcookie" If you wish to fetch the next set of resultset data, you will have to pass this c