Uploading file IFormFile to Azure C# function - c#

I have this regular C# Azure function:
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log) ...
And I need to upload here file, e.g. image. How can I add here IFormFile or is there other way to upload file to function?

To upload a file to an Azure Function, have a look at the Form of the incoming HttpRequest.
This works for me:
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "files")] HttpRequest req,
ILogger log)
{
foreach(var file in req.Form.Files)
{
using (var ms = new MemoryStream())
{
var file = req.Form.Files[0];
await file.CopyToAsync(ms);
ms.Seek(0, SeekOrigin.Begin);
// Do something with the file
}
}
return new OkResult();
}

Related

C# Azure blob storage dependency injection in azure function

In my azure function project i'm using the sonarlint Extension, i have this code for example
using Azure.Storage.Blobs;
public static class HttpPostSaveFilesIndexed
{
[FunctionName("Http_Post_Save_Files_Indexed")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
ILogger log)
{
BlobServiceClient blobServiceClient =new BlobServiceClient(Environment.GetEnvironmentVariable("AzureStorageSimem");
}
}
SonarLint Highlights this "BlobServiceClient blobServiceClient =new BlobServiceClient(Environment.GetEnvironmentVariable("AzureStorageSimem");" with the code S6420 'Client instances should not be recreated on each Azure Function invocation'.
In my mind i was thinking of creating a readonly variable at the start of the function
using Azure.Storage.Blobs;
public static class HttpPostSaveFilesIndexed
{
private static readonly BlobServiceClient blobServiceClient
[FunctionName("Http_Post_Save_Files_Indexed")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
ILogger log)
{
blobServiceClient.something....
}
}
what is a better aproach of this? like dependency injection but i don't know how

context.GetInput<T> getting null in Durable Function

i am facing a weird issue. Searched for multiple question but didn't really get the real fix for this. I have below default template code.
[FunctionName("OrchFunction_HttpStart")]
public async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync("OrchFunction", null);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
In Orchstrator function i have below code
[FunctionName("OrchFunction")]
public async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var outputs = new List<string>();
var data = context.GetInput<JobPayload>();
var inst=context.InstanceId;
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return outputs;
}
Issue here is i am getting NULL in var data = context.GetInput<JobPayload>();. Not sure why, as its the T type i am passing in the HttpRequestMessage. i know its wrong but tried with var data = context.GetInput<HttpResponseMessage>(); , stil its null. What is wrong here? i am getting context.InstanceId value.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.webjobs.extensions.durabletask.idurableorchestrationclient.startnewasync?view=azure-dotnet#Microsoft_Azure_WebJobs_Extensions_DurableTask_IDurableOrchestrationClient_StartNewAsync_System_String_System_String_
Here are different overloads for StartNewAsync. The one you are using does not pass any input to the orchestrator so you wont have any input in orchestrator.
Use this as the starter
[FunctionName("OrchFunction_HttpStart")]
public async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
var payload = new JobPayload()
{
//Fill with data
}
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync<JobPayload>("OrchFunction", payload);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
Note: JobPayload has to be serializable

How to use Azure functions with partial classes

I have the following Azure Function implemented as partial c# class which spans two files.
myfunction.cs and myfunction.mypartial.cs
public static partial class MyFunction
{
[FunctionName("MyFunction")]
public static async Task<IActionResult> MyFunction(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "myfunction/{id}")] HttpRequest req,
ILogger log, int id)
{
// DO SOME STUFF
}
}
If the implementation of MyFunction is located in myfunction.mypartial.cs it is not detected by the Azure Function runtime.
Does Azure Function not support partial classes?
My test was successful:
First file:
public static partial class Function1
{
[FunctionName("Sample1")]
public static async Task<IActionResult> Sample1(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
Seconde file
public static partial class Function1
{
[FunctionName("Sample2")]
public static async Task<IActionResult> Sample2(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
Please find my working solution on GitHub:
https://github.com/MarkusMeyer13/PartialFunction

Facebook integration with azure function

I developed an Azure function and its running fine on Azure.
But I am finding it difficult to modify that function to set it up as a Facebook web hook so that my 'get()' and 'post()' methods get called with the required Facebook parameters.
Any help appreciated.
Here is example for webhook from facebook
namespace Facebook.Function
{
public class AddLeadWebhook
{
[FunctionName("AddLeadWebhook")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequest req,
ILogger log)
{
this.log = log;
log.LogInformation("C# HTTP trigger function processed a request.");
//Facebook challenge (facebook test webhook)
if (!string.IsNullOrEmpty(req.Query["hub.challenge"]))
{
log.LogInformation("Facebook challenged");
return new OkObjectResult(req.Query["hub.challenge"].FirstOrDefault());
}
TODO process request
...
return new OkResult();
}
}
}

How to set session id or create custom field into ApplicationInsights from FunctionApp

Function app is as below:
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]HttpRequestMessage request, ILogger log)
{
log.LogInformation("Information", infoOBject);
}
local.json file has applicationInstrument key.
How to add additional field and set "Session_Id" for "Request" entry in application insights.
You need to this using some custom logging from Application Insights
First, install the Nuget package
Install-Package Microsoft.ApplicationInsights -Version 2.7.2
Then change your above code like below
public static class Function1
{
private static TelemetryClient GetTelemetryClient()
{
var telemetryClient = new TelemetryClient();
telemetryClient.InstrumentationKey = "<your actual insight instrumentkey>";
telemetryClient.Context.Session.Id = "124556";
//update 1-Custom properties- Start
telemetry.Context.Properties["tags"] = "PROD";
telemetry.Context.Properties["userCorelateId"]="1234";
//update 1-Custom properties- Ends
return telemetryClient;
}
[FunctionName("Function1")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, ILogger log)
{
var appInsights = GetTelemetryClient();
appInsights.TrackRequest(req.RequestUri.ToString(), DateTime.Now, Stopwatch.StartNew().Elapsed, "200", true);
return req.CreateResponse(HttpStatusCode.OK, "message");
}
}
Finally in the appinsights
Update 1
You can also add your own additional properties within the request.
E.g,
telemetry.Context.Properties["tags"] = "PROD";
This will add the properties under the customDimension properties
You can also refer here

Categories

Resources