Thursday, May 17, 2018

ASP.NET Core 2.1 : ActionResult<TValue>

ASP.NET Core 2.1 is almost released, we now have access to ASP.NET Core 2.1 RC1. Among other nice features like SignalR (Yes, SignalR is included in ASP.NET Core 2.1) which is getting shipped with ASP.NET Core 2.1, one of my favorites is the introduction of ActionResult<TValue>.

Consider the following API action with ASP.NET Core prior to 2.1.
public Employee Get(int id)
{
    Employee employee = null;
 
    // TODO: Get employee by Id
 
    return employee;
}
So this is very simple, and we are searching for an Employee by Id and returning an Employee. Having Employee is the return type here is very useful for things like documenting the API using Swagger for instance.

But this looks like a bad code, what if there is no Employee by given Id. In that we don’t usually return null, we return HTTP Status Code: NotFound.

But if we are to return that, we no longer can return an Employee type, we are returning an IActionResult. And the code changes to following.
public ActionResult Get(int id)
{
    Employee employee = null;
 
    // TODO: Get employee by Id
 
    if (employee == null)
    {
        return NotFound();
    }
 
    return Ok(employee);
}
Now there is no easy way to know what the encapsulated type of the result.

But we don’t have to face this situation any longer. ASP.NET Core 2.1 introduces this new return type ActionResult<TValue>.
public ActionResult<Employee> Get(int id)
{
    Employee employee = null;
 
    // TODO: Get employee by Id
 
    if (employee == null)
    {
        return NotFound();
    }
 
    return employee;
}
So here ActionResult<Employee> will either wrap Employee or ActionResult based on the result at runtime.

I like this very much, hope you all do!

Happy Coding.

Regards,
Jaliya

Wednesday, May 16, 2018

Entity Framework Core 2.1 : Lazy Loading

Last week (to be exact 7th of May, 2018) Entity Framework Core 2.1 RC 1 was released to the public. And one of the features that got released with EF Core 2.1 was Lazy Loading of related data.

In this post, let’s see how you can use that feature.

Consider I have the following code with an EF Core version prior to 2.1.
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Department Department { get; set; }
}
 
public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Employee> Employees { get; set; }
}
 
public class MyDbContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlServer(@"Server=.;Database=EfCoreLazyLoadingDemo;Trusted_Connection=True;");
    }
}
And I have some Departments and Employees in the database.

Departments
image
Departments
Employees
image
Employees
And I have the following code to print out different Departments and Employees of each of the Department.
static void Main(string[] args)
{
    using (MyDbContext context = new MyDbContext())
    {
        foreach (var department in context.Departments)
        {
            Console.WriteLine(department.Name);
            if (department.Employees != null)
            {
                foreach (var employee in department.Employees)
                {
                    Console.WriteLine($"--{employee.Name}");
                }
            }
        }
    }
}
So if you run this, you should be seeing something like below.
image
Output
No Employees were loaded, and to fix that, you will need to do something like below which is known as Eager Loading.
foreach (var department in context.Departments.Include(d => d.Employees))
Basically, the virtual properties have no effect unlike EF.

And to make Lazy Loading work, we need to update EF Core references to 2.1.0-rc1-final. And in addition, we need to install another package, Microsoft.EntityFrameworkCore.Proxies.

After packages are updated/installed, we have two ways.

1. UseLazyLoadingProxies

This is the easiest way, you just need to add UseLazyLoadingProxies to OnConfiguring override (or within AddDbContext).
public class MyDbContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseLazyLoadingProxies()
            .UseSqlServer(@"Server=.;Database=EfCoreLazyLoadingDemo;Trusted_Connection=True;");
    }
}
And now following should be loading each Departments Employees.
foreach (var department in context.Departments)
image
Output
You don’t have to explicitly Include the Employees. But remember, navigational properties should be virtual.

2. Lazy-loading without proxies

This includes polluting your entities with additional code.
public class Employee
{
    private ILazyLoader _lazyLoader { get; set; }
 
    public Employee(ILazyLoader lazyLoader)
    {
        _lazyLoader = lazyLoader;
    }
 
    public int Id { get; set; }
    public string Name { get; set; }
 
    private Department _department;
    public Department Department
    {
        get => _lazyLoader?.Load(this, ref _department);
        set => _department = value;
    }
}
 
public class Department
{
    private ILazyLoader _lazyLoader { get; set; }
 
    public Department(ILazyLoader lazyLoader)
    {
        _lazyLoader = lazyLoader;
    }
 
    public int Id { get; set; }
    public string Name { get; set; }
 
    private ICollection<Employee> _employees;
    public virtual ICollection<Employee> Employees
    {
        get => _lazyLoader?.Load(this, ref _employees);
        set => _employees = value;
    }
}
Now when using this, you don’t need to have UseLazyLoadingProxies and navigation properties doesn’t need to be virtual. EF Core will be injecting ILazyLoader where it’s required, and he is going to load the related data.

This will also give us the following output.
image
Output
And before winding up, note, Lazy Loading should be used with care. It doesn’t matter whether it’s EF or EF Core, it can affect the performance big time.

Happy Coding.

Regards,
Jaliya

Tuesday, May 15, 2018

Dependency Injection in Blazor

[Content in this post is based on Blazor 0.3.0]

In my last post, I wrote about how you can get yourself started on Blazor. If you are new to Blazor, maybe you can read it first, so you can easily catch along with this. In this post let’s see how we can use Dependency Injection within Blazor.

DI is a first class citizen is Blazor meaning Blazor has DI built in.

If you have a look at the Program.cs of an Blazor application, you should be seeing this.
public class Program
{
    static void Main(string[] args)
    {
        var serviceProvider = new BrowserServiceProvider(services =>
        {
                
        });
 
        new BrowserRenderer(serviceProvider).AddComponent<App>("app");
    }
}
Now we have the following Interface and the implementation.

IMyService.cs
interface IMyService
{
    string Echo();
}

MyService.cs
public class MyService : IMyService
{
    public string Echo()
    {
        return "Hello Blazor";
    }
}

And say, I want to be able to use MyService.Echo() method in any of my component.

First what we need to do is register the service.
image
Service Registration
Here you can see that we can use the ServiceDescriptor to register the service mainly in three different ways, Scoped, Singleton and Transient.
  • Scope,d: Currently no scoping is supported. Behaves like Singleton.
  • Singleton: Single instance. When requested, everyone gets the same instance.
  • Transient: When requested, gets a new instance.
All these registrations are getting added into Blazor’s DI.

For the demo, I will use Singleton.
var serviceProvider = new BrowserServiceProvider(services =>
{
    services.Add(ServiceDescriptor.Singleton<IMyService, MyService>());
})

Now let’s see how we can make use of this. I am going to modify the index.cshtml file.

There is two ways to inject a service into a component.

1. Use @inject
@page "/"
 
@inject IMyService service
 
<h1>Hello, world!</h1>
<h3>@service.Echo()</h3>
 
Welcome to your new app.
 
<SurveyPrompt Title="How is Blazor working for you?" />

2. Use [Inject] attribute
@page "/"
 
<h1>Hello, world!</h1>
<h3>@service.Echo()</h3>
 
Welcome to your new app.
 
<SurveyPrompt Title="How is Blazor working for you?" />
 
@functions{     
   [Inject]     
   IMyService service { get; set; }
}
Both of the approaches will be giving us following.
image
Output
If you have a look at the FetchData.cshtml file which is getting added when we have created a Blazor project using Visual Studio, you must have noticed injecting of HttpClient.
@page "/fetchdata"
@inject HttpClient Http
Have you wondered where that is coming from. HttpClient  and IUriHelper (Service for working with URIs and navigation state) is by default configured for DI in Blazor.

Pretty straightforward, isn't it. Hope this helps!

Happy Coding.

Regards,
Jaliya

Sunday, May 13, 2018

First Look at Blazor

Blazor is web UI framework based on C#, Razor, and HTML for building single-page applications. Yes, with Blazor, we can use C#, which is a server-side language and it’s going to be executed on the browser. That is done via WebAssembly (shortened wasm). Blazor provides all of the benefits of a client-side web UI framework using .NET on the client and optionally on the server.

As of today, Blazor is still in its experimental phase and the latest version is 0.3.0. Even though it’s in its early stages, you, of course, can create a basic to average size web application. So let’s see how you can get started with Blazor.

You need to have,
Once you have them, you can just fire up Visual Studio, select Create new project and select ASP.NET Core Web Application as below.
image
ASP.NET Core Web Application
Now you should be seeing something like below, two Blazor related templates. You can select either ASP.NET Core 2.0 or ASP.NET Core 2.1.
image
New Application
First template here is a standalone Blazor app which will run on the client side on the browser and it has no dependency on .NET Core in server side. Second is for running on top of ASP.NET Core host.

For this post, let’s go ahead with Blazor template. Once the project is created, you should see something like below in the Solution Explorer.
image
Solution Explorer
1: index.html

This is the only html page (That’s any way the nature of single-page applications). All the other content get rendered on this page.
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <title>FirstBlazorApp</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
</head>
<body>
    <app>Loading...</app>
 
    <script type="blazor-boot"></script>
</body>
</html>

2: Program.cs

Blazor apps are built with components. This is where we are creating the root component.
using Microsoft.AspNetCore.Blazor.Browser.Rendering;
using Microsoft.AspNetCore.Blazor.Browser.Services;
 
namespace FirstBlazorApp
{
    public class Program
    {
        static void Main(string[] args)
        {
            var serviceProvider = new BrowserServiceProvider(services =>
            {
                // Add any custom services here
            });
 
            new BrowserRenderer(serviceProvider).AddComponent<App>("app");
        }
    }
}
Here we are creating the root component of type App.

3: App.cshtml

This is the root component. A component is a piece of UI, such as a page, dialog, or data entry form. Components can be nested, reused, and shared between projects.
<!--
    Configuring this here is temporary. Later we'll move the app config
    into Program.cs, and it won't be necessary to specify AppAssembly.
-->
<Router AppAssembly=typeof(Program).Assembly />

Next let's have a look at the content on Pages folder. This is where we have the pages. Pages are also components. First let’s examine _ViewImports.cshtml  file inside Pages folder.

_ViewImports.cshtml
@layout MainLayout
Here What it says is, we are using MainLayout for all the pages inside Pages folder. Technically layouts are also components. Alternatively you can specify the @layout in individual pages as well. And if you have another folder inside Pages folder, you can have a _ViewImports.cshtml  file there and place a @layout, so for all the pages in that folder, that particular @layout is being used. Basically _ViewImports.cshtml is used to place common usings.

So here the MainLayout is residing inside Shared –> MainLayout.cshtml.

MainLayout.cshtml
@inherits BlazorLayoutComponent
 
<div class="sidebar">
    <NavMenu />
</div>
 
<div class="main">
    <div class="top-row px-4">
        <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
    </div>
 
    <div class="content px-4">
        @Body
    </div>
</div>
You can see it uses NavMenu component which is residing in Shared folder. When this layout is being used in pages, pages’ content will get rendered where we have @Body.

Let’s open up Index.cshtml.

Index.cshtml
@page "/"
 
<h1>Hello, world!</h1>
 
Welcome to your new app.
 
<SurveyPrompt Title="How is Blazor working for you?" />
So this is the page, which will get rendered when we hit “http://{url}/” on the browser. And you can see the page contains another component SurveyPrompt. And this component has a Parameter named Title.

SurveyPrompt.cshtml
<div class="alert alert-secondary mt-4" role="alert">
    <span class="oi oi-pencil mr-2" aria-hidden="true"></span> 
    <strong>@Title</strong>
 
    <span class="text-nowrap">
        Please take our
        <a target="_blank" class="font-weight-bold" href="https://go.microsoft.com/fwlink/?linkid=873042">
            brief survey
        </a>
    </span>
    and tell us what you think.
</div>
 
@functions {
    [Parameter]
    string Title { get; set; } // Demonstrates how a parent component can supply parameters
}
Note how the Title is exposed as a property within @functions.

Now if we examine the Counter.cshtml page, you can see the content which is getting displayed when we hit “http://{url}/counter”.

Counter.cshtml
@page "/counter"
 
<h1>Counter</h1>
 
<p>Current count: @currentCount</p>
 
<button class="btn btn-primary" onclick="@IncrementCount">Click me</button>
 
@functions {
    int currentCount = 0;
 
    void IncrementCount()
    {
        currentCount++;
    }
}
And here we have a good use of property binding as well as calling a method. We have a C# method, and it’s getting called by HTML buttons’ onclick event.

Lastly let's look at csproj file.

csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
 
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <RunCommand>dotnet</RunCommand>
    <RunArguments>blazor serve</RunArguments>
    <LangVersion>7.3</LangVersion>
  </PropertyGroup>
 
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Blazor.Browser" Version="0.3.0" />
    <PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.3.0" />
    <DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.3.0" />
  </ItemGroup>
 
  <ItemGroup>
    <BlazorGenerate Remove="Pages\Index.cshtml" />
  </ItemGroup>
 
  <ItemGroup>
    <BlazorGenerate Remove="App.cshtml" />
  </ItemGroup>
 
</Project>

Take a look at RunCommand and RunArguments. So when we run this, what's getting executed is dotnet blazor serve. Kind of Angular.

Isn’t this all nice, I just can’t wait to see what Microsoft will bring with Blazor in upcoming releases.

Head on to https://blazor.net/ and read more.

Happy Coding.

Regards,
Jaliya

Saturday, April 28, 2018

Visual C# Technical Guru - March 2018

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

Post in WikiNinjas Official Blog,
https://blogs.technet.microsoft.com/wikininjas/2018/04/27/march-2018-microsoft-technet-wiki-guru-winners/
image
Visual C# Technical Guru - March 2018
Happy Coding.

Regards,
Jaliya

Thursday, April 26, 2018

Running Service Bus 1.1 and Service Fabric Side by Side?

I had a requirement where I wanted to have both Service Bus 1.1 and Service Fabric Side by Side on my laptop. One of the applications that I am working on required Service Bus 1.1 and another required Service Fabric. Apparently, it turned out only one can be running at a time, not the both.

Service Bus 1.1 was released back in late 2013 and uses Windows Fabric. So if you have Service Bus 1.1 installed before it installs a service named Windows Fabric Host Service.  But if you install Service Fabric Runtime and SDK on top of that, Windows Fabric Host Service which is required for Service Bus 1.1 is no longer there under Services, it’s getting removed by Service Fabric. So currently there is no way to have both the Service Bus 1.1 and Service Fabric running Side by Side in one single machine.

But there are two options. Unfortunately, both the options require moving Service Bus 1.1 away from your computer. If you are a developer, you need to have Service Fabric Runtime and SDK installed on your machine for sure.

1. Have the Service Bus Farm in a VM.

This option is kind of hard. You need to set up the Service Bus Farm on a different machine and configure the certificates required for hosts to connect to the server. Then you need to grab those and install on your local machine. That is a pain.

2. Use Azure Service Bus

This is pretty much straightforward, you just need to create a Service Bus application in Azure. You just need to change the connection string and most of the time it should work without any code changes.

Hope this helps someone who is having the same requirement and save him/her some time.

Happy Coding.

Regards,
Jaliya

Tuesday, April 24, 2018

Wrote a post on Wiki Life at Official Blog of TechNet Wiki

Wrote a post in Wiki Ninjas - Official Blog of TechNet Wiki. The title of the post is TNWiki Article Spotlight – Logic Apps: Integrating LUIS Application With Logic Apps To Predict Intent in User Utterances.
image
TNWiki Article Spotlight – Logic Apps: Integrating LUIS Application With Logic Apps To Predict Intent in User Utterances
Read the rest on,
TNWiki Article Spotlight – Logic Apps: Integrating LUIS Application With Logic Apps To Predict Intent in User Utterances

Happy Coding.

Regards,
Jaliya

Saturday, April 21, 2018

Session : Serverless Computing with Azure Functions at Global Azure Bootcamp 2018 - Colombo, Sri Lanka

I was fortunate enough to make it on stage and deliver a session at Global Azure Bootcamp 2018 - Colombo, Sri Lanka.

Global Azure Bootcamp is a worldwide event happening on April 21 each year and this time it has happened for the 6th time all around the world. In Sri Lanka, the event was organized by a couple of Microsoft MVPs lead by Shameera Prajapriya who is an MVP on Microsoft Azure.

The entire day was filled with great sessions delivered by industry experts from a variety of areas.
30715905_991374004371409_1581081584549756928_o
 Global Azure Bootcamp 2018 - Colombo, Sri Lanka Speaker Panel
I delivered my hour-long session on the topic Serverless Computing with Azure Functions.
30708440_993063324202477_3978026227410665472_o
Serverless Computing with Azure Functions
There I went through the following areas along with a demo,
  • Serverless Computing
  • Azure Functions
  • Azure Functions Proxies
  • Performance Considerations

Slide Deck



Demo Source Code
   https://github.com/jaliyaudagedara/AzureFunctionApplication

Happy Coding.

Regards,
Jaliya

Thursday, April 19, 2018

Session : Jumpstart to Azure Functions at Sri Lanka Developer Forum

Delivered an hour-long session titled Jumpstart to Azure Functions at Sri Lanka Developer Forum meetup for the month of April 2018. There I went through the following areas along with a demo,
  • Serverless Computing
  • Azure Functions
  • Azure Functions Proxies
  • Performance Considerations
highres_469721004
Sri Lanka Developer Forum - April, 2018
For more information,
   Meetup Event

Happy Coding.

Regards,
Jaliya

Tuesday, April 10, 2018

Durable Functions in Azure Functions for Function Chaining

When designing Azure functions one of the best practices that Microsoft recommends is Azure functions should be stateless.

But imagine you have this requirement, where you to need call an Azure function and the output of that function needs to be applied as the input of another function and so on and so forth.
image
Function Chaining
This scenario is known as Function chaining. The very first function (say F0) which orchestrates F1, F2, F3, and F4 will need to maintain the return values and control the flow. But what if after x amount of time, the process running F0 recycles or the VM which F0 is running on rebooted. If we use regular Azure Functions, since we aren’t maintaining state, we can’t track at which point the F0 got failed.

Enter Durable Functions.

Durable Functions are designed to do all the hard work of maintaining the function state for us. It's built on top of Durable Task Framework. As of today (10th April 2018) Durable Functions are in the preview stage.

In this post let's see how Durable Functions can be used to chain functions. It’s always best to go by an example. First, let’s see how we can create Durable Functions. Please note all the instructions given are as of today, these steps might change over time.

If you are using Azure Portal, if you create a new Function App, by default it’s using Runtime 1.x. And because of that, you won’t be able to see any Durable Function templates when creating new functions. For that, you need to go to Function App Settings and change the runtime to beta.
image
Function App Settings
image
Runtime Version
Here I have already switched to beta. Alternatively, you can go to Application Settings and change the FUNCTIONS_EXTENSION_VERSION to beta.

And then if you try to create a new function, you can see all the Durable Functions related templates.
image
Durable Functions Templates
When you try to create a new function using one of the above templates, you will be prompted to install Durable Functions extension.

If you are using Visual Studio, make sure you are on 15.3 or greater and Azure Development workload is included in your setup.

And when you are creating new Function App, make sure to select Azure Functions V2 Preview (.NET Core).
image
New Project
For this demo, let’s go ahead with Visual Studio. Once the project is created, let’s add a new function using Durable Functions Orchestration template.

image
Templates
Once it’s created, you can see that Microsoft.Azure.WebJobs.Extensions.DurableTask NuGet package is added for us.
image
project.csproj
I have modified the default file to something like below.
public static class Function1
{
    [FunctionName("Function1")]
    public static async Task<int> RunOrchestrator(
        [OrchestrationTrigger] DurableOrchestrationContext context)
    {
        int x = await context.CallActivityAsync<int>("GetSum", new SumModel(1, 10));
        int y = await context.CallActivityAsync<int>("GetSum", new SumModel(x, 10));
        int z = await context.CallActivityAsync<int>("GetSum", new SumModel(y, 10));
 
        return z; // z = 31
    }
 
    [FunctionName("GetSum")]
    public static int GetSum([ActivityTrigger] SumModel model, TraceWriter log)
    {
        // Time consuming operation
        return model.Number1 + model.Number2;
    }
 
    [FunctionName("Function1_HttpStart")]
    public static async Task<HttpResponseMessage> HttpStart(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
        [OrchestrationClient]DurableOrchestrationClient starter,
        TraceWriter log)
    {
        // Function input comes from the request content.
        string instanceId = await starter.StartNewAsync("Function1", null);
 
        log.Info($"Started orchestration with ID = '{instanceId}'.");
 
        return starter.CreateCheckStatusResponse(req, instanceId);
    }
}
 
public class SumModel
{
    public int Number1 { get; private set; }
    public int Number2 { get; private set; }
 
    public SumModel(int number1, int number2)
    {
        Number1 = number1;
        Number2 = number2;
    }
}
Here at the bottom, we have a HttpTrigger Function1_HttpStart to trigger the Orchestrator function which is Function1. Function1 will call GetSum multiple times to make it like a chain.

There are a couple of interesting things happening here. Imagine GetSum takes 10 seconds to complete. So that means Function1 will be running for more than 30 seconds. But it’s not. After calling GetSum, Function1 goes to sleep. And when GetSum returns completing his functionality, he notifies Function1 with the return values and Function1 resumes its operation. For all these time, the state is getting managed by the runtime.

Isn’t it fascinating.

There are different scenarios where Durable Functions is coming really handy, please do check those out using the link below.
https://docs.microsoft.com/en-us/azure/azure-functions/durable-functions-overview

Happy Coding.

Regards,
Jaliya

Tuesday, March 27, 2018

Visual C# Technical Guru - February 2018

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

image
Visual C# Technical Guru - February 2018
Happy Coding.

Regards,
Jaliya

Monday, March 26, 2018

Azure App Service: Enabling Static Content

I had an AngularJS application running as an Azure App Service and noted that it doesn’t serve JSON files.

The fix was simple, adding a web.config file manually and allowing static content.
<configuration>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension="json" mimeType="application/json" />
    </staticContent>
  </system.webServer>
</configuration>
Happy Coding.

Regards,
Jaliya

Tuesday, March 20, 2018

Azure Functions : Map Data to Output Bindings

From Azure Functions, we can map data to Output bindings using following three options.
  1. Using function return value
  2. Using out parameter
  3. Using ICollector or IAsyncCollector
In this post let’s have a look at them in detail. I have created a Azure Function App using the Azure Portal and I will be using portals’ editor in this post.

The scenario I am going use is, I will have a Azure Function which can be triggered manually. From there I will be outputting messages to a Azure Storage Queue.

So first let’s create a Queue trigger.
image
Queue trigger
image
Queue trigger Properties
using System;
 
public static void Run(string myQueueItem, TraceWriter log)
{
    log.Info($"Queue trigger function processed: {myQueueItem}");
}
So every time a message get queued to myqueue-demo, QueueTriggerCSharp1 function will get triggered. It will just log the message, so we can see whether the data is getting correctly mapped when we are using Output bindings in our Manual trigger.

Now let’s create the Manual trigger.
image
Manual trigger
image
Manual trigger Properties
using System;
 
public static void Run(string input, TraceWriter log)
{
    log.Info($"Manually triggered function called with input: {input}");
}


1. Using function return value


The most easiest way to map data to Output binding is using the functions return value.

I am changing our ManualTriggerCSharp1 as follows.
using System;
 
public static string Run(string input, TraceWriter log)
{
    log.Info($"Manually triggered function with input: {input}");
    return $"Using Return: {input}";
}
Now we have a function which returns a string. Our requirement is map this return value to a Output binding.

For that, let’s go to Integrate menu under our ManualTriggerCSharp1 function.
image
Integrate
And you will see something like below.
image
Integrate
Click on New Output under Outputs. Select Azure Queue Storage.
image
Select Output Type
From next wizard page, you can simply select the “Use function return value”. Then you will need to select the Queue name and it’s Storage account connection which you want to write the output into.
image
New Output Properties
Click on Save, and run our Manual trigger. After running it, if you go to Monitor menu under QueueTriggerCSharp1, you can see the return value has been read.
SNAGHTML1ec1504c
Monitor
image
Monitor


2. Using out parameter


Now let’s modify our ManualTriggerCSharp1 function to have out parameter and set it’s value in the function body.
using System;
 
public static string Run(string input, TraceWriter log, out string outParameter)
{
    log.Info($"Manually triggered function with input: {input}");
 
    outParameter = $"Using Out: {input}";

    return $"Using Return: {input}";
}
Now let’s add this Output binding.

Again add a New Output and select Azure Queue Storage and then do as following (remember to specify the correct Queue name which our QueueTriggerCSharp1 is watching).
image
New Output Properties
Important thing to keep in mind is Message parameter name needs to be same as your out parameter name.

Save and run the manual trigger and examine the Monitor menu under QueueTriggerCSharp1.

Now you should be seeing the value of out parameter has been added to queue and is read.
image
Monitor
Now what if the function is an async one. Then we can’t use out parameters.

3. Using ICollector or IAsyncCollector


This is my preferred way of mapping data to Output bindings. One reason of course is most of the time, functions are async. And the other reason is, using Collectors we can pass multiple data. Let’s modify the ManualTriggerCSharp1 as follows.
using System;
 
public static async Task<string> Run(string input, TraceWriter log, IAsyncCollector<string> queueCollector)
{
    log.Info($"Manually triggered function with input: {input}");
 
    await queueCollector.AddAsync($"Using Collector: {input} 1");
    await queueCollector.AddAsync($"Using Collector: {input} 2");
 
    return $"Using Return: {input}";
}
Right now since we don’t have the existing outParameter and it’s binding, let’s change the previous Output binding.
image
Output Properties
Again, we need to make sure Message parameter name is same as the function parameter name.

And if we save and run, we should be seeing the message is queued and read by QueueTriggerCSharp1.
image
Monitor
And note: ICollector is the synchronous counterpart of IAsyncCollector and I don’t think it deserves a demonstration of it’s use.

Hope this helps.

Happy Coding.

Regards,
Jaliya