Azure function throwing exceptions when called even with default template - azure

I'm baffled by how to just make a simple Azure function. In Visual Studio 2017 (I'm on version 15.5.6) I create a simple project following the instructions here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-develop-vs
My steps:
Make new Azure Functions project and leave the framework at the default of .Net Framework 4.6.1
On the next screen I choose HttpTrigger and the drop down says "Azure Functions v1 (.NET Framework)"
I set the storage to be my azure storage that I already created in the portal and set the authorization to "admin"
Everything compiles fine. I call the function via PostMan and get this error:
"A ScriptHost error has occurred
Exception while executing function: Functions.Function1. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'log'. Microsoft.Azure.WebJobs.Host: No value was provided for parameter 'log'."
For reference, here is the template function they created that I haven't modified at all:
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
namespace TestFunc
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Admin, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
// parse query parameter
string name = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;
// Get request body
dynamic data = await req.Content.ReadAsAsync<object>();
// Set name to query string or body data
name = name ?? data?.name;
return name == null
? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
: req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}
}
}
If I remove the "TraceWriter log" and the call to "log.Info(...." and then try again, I instead get this error:
"A ScriptHost error has occurred
Exception while executing function: Functions.Function1. mscorlib: Exception has been thrown by the target of an invocation. TestFunc: Method not found: 'System.Net.Http.HttpResponseMessage System.Net.Http.HttpRequestMessageExtensions.CreateResponse(System.Net.Http.HttpRequestMessage, System.Net.HttpStatusCode, !!0)'."
I've tried changing the .Net version to 4.7 but nothing changed. I tried changing the function version to v2 instead of v1 (even though it's in beta at the moment) but nothing happened either. The only NuGet package that's added by the template is Microsoft.NET.Sdk.Functions version 1.0.6. There's an update to 1.0.7 available but that doesn't help either.
I have no idea what to try. This is the default template. I have another function project that works fine but that was done a while ago when VS2015 was the latest, and was during the time when you had to have those function.json files to make your precompiled DLL. I was hoping to be able to use the current system as it seems to be the best way going forward but if I can't get this to work I may just go back to the old way of doing things. Thanks.

Related

Assembly could not be find in azure function

I am new to Azure Functions and facing the issue related to assembly.
Problem :
I want to read a PPT file which is being uploaded in Sharepoint.
Using Power Automate to start a flow which sends the file content to Azure function.
Azure function should read the content of PPT file.
I have added DocumentFormat.OpenXml (version - 2.13.0) and System.IO.Packaging (version 6.0.0) to bin folder
the code I have written is compiled without errors but when I run the code to test it gives assembly error, please refer to the images.
I have read that it is a known issue that Azure function removes assembly during runtime and this property _FunctionsSkipCleanOutput can be updated but if this is a solution then how to do this via portal?
I am using Azure Portal only.
#r "Newtonsoft.Json"
#r "System.IO.Packaging.dll"
#r "DocumentFormat.OpenXml.dll"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Text;
using System;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using System.IO.Packaging;
using DocumentFormat.OpenXml.Presentation;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
//string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string file=data?.file;
byte[] filarray=Convert.FromBase64String(file);
MemoryStream m=new MemoryStream();
m.Write(filarray,0,filarray.Length);
int count=0;
using (PresentationDocument presnt=PresentationDocument.Open(m,true))
{
PresentationPart p=presnt.PresentationPart;
if(p!=null)
{
count=p.SlideParts.Count();
}
}
//name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty("jogi")
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: Convert.ToString(count);
//:file;
return new OkObjectResult(responseMessage);
}
I couldn't get the above working rather I tried to make the azure function using visual studio code and I could read the PPT file by adding reference to OpenXml.

Azure Functions v3 Could not load file or assembly 'Microsoft.Extensions.Primitives, Version=5.0.0.0

I'm having the above error after running an azure function called "Test" that redirects to an external URL of a service we want to use.
[FunctionName("Test")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequest req)
{
Log.Information("C# HTTP trigger function processed a request.");
string url = _authenticationService.GetAuthorizationUri().ToString();
return new RedirectResult(url);
}
The site at the URL prompts the user to authorize use of their data and performs a redirect to the previously authorized url of our "AuthorizationCallback", along with a query string parameter.
[FunctionName("AuthorizationCallback")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
{
Log.Information("C# HTTP trigger function processed a request.");
string code = req.Query["code"];
try
{
if (!string.IsNullOrEmpty(code))
{
await _authenticationService.ExchangeCodeForAccessToken(code);
return new OkResult();
}
}
catch (System.Exception)
{
return new UnauthorizedResult();
}
return new NotFoundResult();
}
The AuthorizationCallback function is hit but produces the following error in the console:
These are the dependencies of the current project on the solution (which is set as the startup project):
I've tried installing both the latest stable version (5.0.0) and the version before that (3.1.13) of Microsoft.Extensions.Primitives in the current project, but I'm still getting the same error. I've noticed the package that can't be loaded is within microsoft.azure.webjobs (3.0.23), which is within microsoft.azure.webjobs.extensions.storage (4.0.4), but these are used in another project entirely, for another azure function (blob triggered). Any ideas on how to overcome this error? Thank you all.
The Azure Functions host for .NET Core 3 uses an in-process hosting model, which essentially means you are limited in what versions of Microsoft assemblies you can use. What's happening is that something in your project has a reference to a newer version of Microsoft.Extensions.Primitives, but an older version of that library is already loaded by the Azure Functions host application.
For Azure Functions .NET Core 3, you should restrict all Microsoft.Extensions.* libraries to v3.x. You currently have Microsoft.Extensions.DependencyInjection 5.0.1, which should be changed to 3.x. Check for any other Microsoft.Extensions.* libraries either at the Packages level or anywhere beneath (tip: you can find them quickly by putting Microsoft.Extensions in the input box at the top of the Solution Explorer). You may need to downgrade some other library that has Microsoft.Extensions.Primitives as a dependency.
You might also be able to get away with manually writing a bindingRedirect pointing the newer version to an older version. The Microsoft.Extensions.* packages are relatively stable across versions, so that may work. It would make me very nervous, though.

404 after setting output of Azure Function to Cosmos DB

I use site editor for Azure Function. I modified initial function code, so it is now:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation(requestBody);
return new OkObjectResult(requestBody);
}
then added an output to Cosmos Db using output parameter $return
when I'm testing my function I get 404 and nothing else
has anybody faced this issue and what can be done?
The problem was that I have set 2 output bindings to my function. Initially it was bound to HTTP and I have added Cosmos Db. I removed HTTP output binding and now it works like a charm

How do I post a message to a Azure Service Bus from my Azure function?

I am playing around with Azure functions and trying to setup an intricate construct of pipes and filters (the pattern). I am using Azure functions for this.
My starting point is a HTTP triggered Azure function. That collects some JSON from the body of the request and should pass this message to a Azure Service Bus.
I must be missing something here (I have done this before in RabbitMQ with console apps) but how do I post a message to a service bus from a HTTP triggered Azure function.
I found several references talking about configuring my function.json (what ever that is - im building in Visual Studio).
How does this input/output (trigger/binding) thing work - im guessing that is the problem here...or??
I have my first Azure function in place and is receiving the data from the HTTP - so far so good. But how to proceed?
** Update **
Still cant get it to Work. Got this code and it fails with an http500. (it also says i need to see the og - where is that log?)
public static class EI_WooCommerce_Hub
{
[FunctionName("EI_WooCommerce_Hub")]
[return: ServiceBus("eilogging", Connection = "EIIntegrationServiceBusConnection")]
public async static Task<string> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "EIWooCommerceHub/name/")]HttpRequestMessage req, TraceWriter log)
{
log.Info("Webhook triggered from: ");
return "Hello World to queue";
}
}
** Update 2 **
This seems to be a config problem. In the application settings on the function app I kept getting an authorization error for the servicebus. I added the default "AzureWebJobsServiceBus" setting with the connectionstring, then it worked. It could not pick up my own connection string for some reason.
You should use Service Bus output binding. Since you mentioned Visual Studio, I assume C#. The simplest ever example looks like this:
[FunctionName("ServiceBusOutput")]
[return: ServiceBus("myqueue", Connection = "ServiceBusConnection")]
public static string ServiceBusOutput([HttpTrigger] dynamic input)
{
return input.Text;
}
Then add an application setting called ServiceBusConnection with the connection string to a namespace with queue myqueue (or rename in attribute constructor).
You can find more in Azure Service Bus bindings for Azure Functions - Output.
When you build in Visual Studio, then the function.json is created automatically. All you have to do is to define your triggers and output as attributes of the function parameters (see here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#output)
A minimalistic example:
[FunctionName("HttpTriggerCSharp")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestMessage req,
[ServiceBus("myqueue")] out string sbMessage,
TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
// parse query parameter
string name = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;
sbMessage = name;
}

Query CosmosDB from Azure Function .csx

I want to query a CosmosDB collection to see if a document already exists from within a Azure Function using csx.
As well as the following code I have an implicit binding towards the cosmosDB collection to be able to create new documents. This is done using
binder.BindAsync<IAsyncCollector<string>>(new CosmosDBAttribute("test", "collection")
This a simple version of my function.
#r "System"
#r "Microsoft.Azure.WebJobs.Extensions.CosmosDB"
using System;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
public static async Task<string> Run(string localityId, Binder binder, TraceWriter log)
{
...
string EndpointUrl = "<your endpoint URL>";
string PrimaryKey = "<your primary key>";
DocumentClient client = new DocumentClient(new Uri(EndpointUrl), PrimaryKey);
...
}
This results in the following error message:
error CS0246: The type or namespace name 'DocumentClient' could not be found (are you missing a using directive or an assembly reference?)
I have installed the extension Microsoft.Azure.WebJobs.Extensions.CosmosDB
I am running on MacOS using the func host start command to test locally.
error CS0246: The type or namespace name 'DocumentClient' could not be found (are you missing a using directive or an assembly reference?)
It seems that you need to reference #r "Microsoft.Azure.Documents.Client". You also could get demo code from Azure Cosmos DB bindings for Azure Functions
#r "Microsoft.Azure.Documents.Client"
using System;
using Microsoft.Azure.Documents;
using System.Collections.Generic;
public static void Run(IReadOnlyList<Document> documents, TraceWriter log)
{
log.Verbose("Documents modified " + documents.Count);
log.Verbose("First document Id " + documents[0].Id);
}
Update:
To use NuGet packages in a C# function, upload a project.json file to the function's folder in the function app's file system. Here is an example project.json file that adds a reference

Resources