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
Related
I'm using .net 5 azure function with ServiceBus. I want to send multiple messages from trigger function.
In previous version you could usr IAsyncCollector to do something like that:
[FunctionName("HttpToServiceBusQueue")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
[ServiceBus("testqueue",Connection ="connectionString")] IAsyncCollector<string> outputEvents,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
// ...
await outputEvents.AddAsync("message1");
await outputEvents.AddAsync("message2");
// ...
return new OkObjectResult(responseMessage);
}
But as I read there in documentation is no support of IAsyncCollector in newer version.
Is there any alternative ways to do it or?
Example of my code:
[Function("FileTriggerFunction")]
[ServiceBusOutput("fileupload", Connection = "ServiceBusConnectionWrite")]
public string Run(
[BlobTrigger("file-storage/{name}", Connection = "ConnectionString")] string myBlob, string name,
FunctionContext context)
{
var logger = context.GetLogger("FileTriggerFunction");
var res = JsonConvert.SerializeObject(*List of messages*);
logger.LogInformation(res);
return res;
}
Actually it separates each object of list for separate message, but I don't think that it is correct to do this in such way.
Instead of IAsyncCollector we have multiple output binding in .net 5
On this function we will give the multiple output values.
public static class MultiOutput
{
[Function("MultiOutput")]
public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
FunctionContext context)
{
var response = req.CreateResponse(HttpStatusCode.OK);
response.WriteString("Success!");
string myQueueOutput = "some output";
return new MyOutputType()
{
Name = myQueueOutput,
HttpResponse = response
};
}
}
public class MyOutputType
{
[QueueOutput("myQueue")]
public string Name { get; set; }
public HttpResponseData HttpResponse { get; set; }
}
Refer .NET isolated process guide for .NET 5.0 in Azure Functions
Thanks # Stephen Cleary
I had tried with SeviceBus Client to send a multiple messages to a queue I am able to process it.
Refer here
Here is a sample code how to do it
[Function("MultiOutput")]
public static DispatchedMessages Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
FunctionContext context)
{
return new DispatchedMessages
{
Messages = new List<string> { "aaa", "bbb" } // todo: serialize
};
}
public class DispatchedMessages
{
[ServiceBusOutput(queueOrTopicName: "dest", Connection = "AzureServiceBus")]
public IEnumerable<string> Messages { get; set; }
}
}
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();
}
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
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();
}
}
}
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