NuGet Packages do not compile Azure CSX - azure

I have included a NuGet Package in an Azure Function app that I downloaded to work on in Visual Studio. I have added it to the project.json and I still get "error CS0246: The type or namespace name 'NetTopologySuite' could not be found (are you missing a using directive or an assembly reference?)". I've read through microsoft's documentation and cannot find what I could be doing wrong.
Here is a sample of what my csx looks like:
#r "System.Data"
using System;
using System.Data;
using System.Data.SqlClient;
using System.Net;
using NetTopologySuite;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
\\ Code to retrieve data from database and turn it into an array
\\ of GeoJSON features called DataFromDatabase not shown
NetTopologySuite.Features.Feature[] TrailSegments = DataFromDatabase;
HttpResponseMessage resp = req.CreateResponse(HttpStatusCode.OK);
resp.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(DataFromDatabase), System.Text.Encoding.UTF8, "application/json");
return resp;
}
Here is my project.json:
{
"frameworks": {
"net46": {
"dependencies": {
"NetTopologySuite.IO.GeoJSON": "1.14.0"
}
}
}
}
Does anyone have more experience with this that could offer a little more than what's in the documentation?
"FUNCTIONS_EXTENSION_VERSION": "~1"
"WEBSITE_NODE_DEFAULT_VERSION": "6.5.0"

If you do upload the project.json file to your function folder(not function app folder), what you have done is exactly right. I have followed your steps and things work fine on my side.
Nuget restoring for function editable online is not so sensitive, so you may wait for a while(you can do some edit in function code and click save or directly restart whole function app).
After that, you can see a project.lock.json under the function folder. It means the package has been installed successfully. Then everything goes well.
Update for multiple functions sharing reference.
One function package restore can't be used by others. So we have to upload dlls manually if you don't want to add project.json to every function. See shared assemblies.
Download NetTopologySuite.IO.GeoJSON.
Find four dlls(NetTopologySuite.dll/NetTopologySuite.IO.GeoJSON.dll/GeoAPI.dll/PowerCollections.dll) in package and upload them to a bin folder under function app folder.
Add four assemblies in code like #r "..\bin\NetTopologySuite.IO.GeoJSON.dll". You may also need add #r "Newtonsoft.Json" as it's one dependency in that package.
If you use the dll with namespace like NetTopologySuite.Features.Feature[], you don't have to import namespaces. And vice versa.
If you know those dependencies clearly, you can only upload and reference dlls you need.

I see that you are using 3rd party library which is widely available in Nuget official repository. In such cases, you need to let Azure know which Nuget repository your package, 'NetTopologySuite' resides in..
Github: https://github.com/NetTopologySuite/NetTopologySuite
NuGet v3: https://www.myget.org/F/nettopologysuite/api/v3/index.json
NuGet v2: https://www.myget.org/F/nettopologysuite/api/v2
Create Nuget.config file
Add the following contents in that file and re-configure it for your environment.
Nuget.config content - you can find exhaustive file online.

Related

Azure function: Could not load file or assembly Microsoft.IdentityModel.Tokens, Version=5.2.1.0

Im writing an azure function to generate a JWT token and return it to the client. The code is tested locally in a console app and all seems to work fine. This is the package reference included in the working console app, and in my functions app:
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.2.1" />
When running the function host locally with func host start and executing the code it results in the error:
Could not load file or assembly 'Microsoft.IdentityModel.Tokens, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."
I don't understand why this is happening, the dll is laying in the output folder along with my application dll. The only other thing I can think of is that the function host has its own set of packages that it sources from and this one is not available yet, having been only released 12 days ago.
I'm not sure. Any help on why this is happening or how to get around it?
Details:
Azure Functions Core Tools (2.0.1-beta.22)
Function Runtime Version: 2.0.11415.0
I got this issue and it seems to be related to some kind of bug in the Azure function SDK. the fix was to add:
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
to your csproj file. As documented here
I had installed this package Microsoft.AspNetCore.Authentication.JwtBearer
And for me, the issue was resolved.
You can uninstall System.IdentityModel.Tokens.Jwt
Because the Microsoft package depends on the system package, so it gets installed automatically.
I was able to solve this exact issue by using an older version of the nuget package. My starting point was that I had copied a class file from an old project to a new one. The class file referenced JwtSecurityToken. This did not compile in the new project, so I added Security.IdentityModel.Tokens.Jwt from nuget package manager. I just added latest version. This worked fine locally, but just like you, it failed when published to azure. I then looked at the old project and noticed that it was using 5.1.4 of that Security.IdentityModel.Tokens.Jwt. So, I downgraded to that version and it now works when published.
fwiw: this is the v2 preview runtime version at the time I did this.
https://<mysite>.azurewebsites.net/admin/host/status?code=<myadminkey>
{
"id": "<mysite>",
"state": "Running",
"version": "2.0.11587.0",
"versionDetails": "2.0.11587.0-beta1 Commit hash: 1e9e7a8dc8a68a3eff63ee8604926a8d3d1902d6"
}
tl;dr
None of the above worked for me and this would randomly happen from time to time until today it happened all the time. The only reason I could see was that Microsoft.IdentityModel.Tokens was not directly referenced in the executing project, but was on a referenced project. The library was sitting in the bin folder, it just wouldn't load.
Reference
Taking a clue from this solution to another problem I was able to resolve it like so:
Solution
Create a static constructor in the app's entry point class
static MainClass()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
Add the handler
private static System.Reflection.Assembly? CurrentDomain_AssemblyResolve(object? sender, ResolveEventArgs args)
{
var domain = sender as AppDomain;
var assemblies = domain.GetAssemblies();
foreach(var assembly in assemblies)
{
if (assembly.FullName.IsEqualTo(args.Name))
{
return assembly;
}
}
var folder = AppDomain.CurrentDomain.BaseDirectory;
var name = args.GetLibraryName().Name.Split(Symbols.Comma).FirstOrDefault();
var library = $"{name}.dll";
var file = Path.Combine(folder, library);
if (File.Exists(file))
{
return Assembly.LoadFrom(file);
}
return null;
}

Precompiled Azure Function Behaving Unexpectedly

MyLibrary.dll
public class Person
{
[JsonProperty("name")]
public string Name { get; set; }
public static async Task Save(Person person)
{
DocumentClient client = CreateDocumentClient();
await client.OpenAsync();
await client.CreateDocumentAsync(CreateDocumentCollectionUri(), person);
}
}
MyFunctionApp.dll
public class SimpleHttpTrigger
{
public static async Task Run(HttpRequestMessage req)
{
Person bob = new Person() { Name = "Bob" };
await Person.Save(bob);
}
}
MyLibrary depends on:
Newtonsoft.Json 10.0.2
Microsoft.Azure.Documents.Client 1.13.1
And MyFunctionApp depends on MyLibrary.
The issue observed in this example is that the JsonProperty attribute is ignored when SimpleHttpTrigger.Run is called by the Azure Function CLI. SimpleHttpTrigger behaves as expected when called directly from a console app.
The issue can be resolved by changing MyLibrary's dependencies to match the versions currently used by the Azure Functions CLI:
Newtonsoft.Json 9.0.1
Microsoft.Azure.Documents.Client 1.11.4
It appears that Azure Function CLI ignores libraries in MyFunctionApp/bin when it has its own version of the library (found in node_modules/azure-functions-cli/bin). In this small example it's fine to match the dependencies but it isn't feasible when MyFunctionApp has a much larger dependency.
Is my understanding of this behaviour correct?
Is there any way to specify which version of these libraries to use in precompiled functions? I believe that one could get this behaviour in scripted functions by putting the dependencies inside the function's bin folder.
Update
My assumptions about the cause of this behaviour appear to be incorrect.
The newer versions of the Newtonsoft.Json and Microsoft.Azure.Documents.Client assemblies are in fact loaded alongside the Azure Function CLI's automatically loaded assemblies.
Which makes me even more confused as SimpleHttpTrigger.Run still behaves differently when called directly from a console app than it does when called by the Azure function host.
Any ideas what's going on? Possibly something stupid on my part.
Update 2
It looks like two different versions of the Newtonsoft.Json are used, whichever way the assemblies are loaded:
MyLibrary uses Newtonsoft.Json 10.0.2 as intended, but its dependency, Microsoft.Azure.Documents.Client 1.13.1, uses Newtonsoft.Json 9.0.1
Which might explain the incompatibility of the JsonProperty attribute.
Possibly? Please help, I'm very confused!
Basically, you are correct about the diagnosis of the problem.
This is an open issue with Azure Functions.
I stumbled on this myself and sympathize with your frustration.
Until the issue is solved, you must use the same major version of all the dependencies you happen to share with the implementation of Azure Functions.
Here is the list of Azure Functions dependencies : https://github.com/Azure/azure-webjobs-sdk-script/blob/dev/src/WebJobs.Script/packages.config
Open issues to track:
https://github.com/Azure/azure-webjobs-sdk-script/issues/573
https://github.com/Azure/azure-webjobs-sdk-script/issues/1311

Missing dll error from Azure function when updating pipeline

I have an Azure function which triggers when I copy a blob into a container. The function successfully copies the blob into a subfolder for processing but I then want to change the pipeline schedule to trigger the pipeline to run. However, when I try and change the pipeline schedule in code, I get the following error:
Could not load file or assembly 'Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, ... or one of its dependencies. The system cannot find the file specified.
I've been through the list of nuget packages to remove those that aren't being used and ensure I'm using the latest versions. I've also commented out come of the unnecessary usings in my csx file but I'm still getting the error. If I comment out the pipeline update call, the error disappears and the function runs to the end.
My project.json file looks like this (not that I've included commented out packages to show what other packages I've tried previously):
{
"frameworks": {
"net46": {
"dependencies": {
////"Hyak.Common": "1.1.0",
"Microsoft.Azure.Common": "2.1.0",
"Microsoft.Azure.Common.Dependencies": "1.0.0",
"Microsoft.Azure.Management.DataFactories": "4.11.0",
////"Microsoft.Bcl": "1.1.10",
////"Microsoft.Bcl.Async": "1.0.168",
////"Microsoft.Bcl.Build": "1.0.21",
"Microsoft.IdentityModel.Clients.ActiveDirectory": "3.13.8"
////"Microsoft.Net.Http": "2.2.29"
}
}
}
}
Finally, in the csx file, my usings are as follows (again including commented out lines)
#r "System.Runtime"
#r "System.Threading.Tasks"
#r "Microsoft.WindowsAzure.Storage"
using System;
using System.Net;
using System.Threading.Tasks;
using System.Configuration;
//using Newtonsoft.Json;
using Microsoft.Azure;
//using Microsoft.Azure.Common;
using Microsoft.Azure.Management.DataFactories;
using Microsoft.Azure.Management.DataFactories.Models;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
The code to update the pipeline is as follows:
client.Pipelines.CreateOrUpdate(resourceGroupName, dataFactoryName, new PipelineCreateOrUpdateParameters()
{
Pipeline = pl.Pipeline
});
log.Info($"Pipeline rescheduled for {slice}");
If I run this as a console application/web app (which includes several references including Microsoft.Threading.Tasks), the pipeline update works correctly but the same code doesn't work from my Azure function.
Does anyone know what nuget packages/versions or references I might be missing?
It turns out this problem was caused by the project.lock.json file referencing an old version of .Net (i.e. 4.5, rather than 4.6). Updating it to 4.6 resolved the issue.
For completeness, the project.lock.json file now reads as follows:
{
"locked": false,
"version": 2,
"targets": {
".NETFramework,Version=v4.6": {}
},
"libraries": {},
"projectFileDependencyGroups": {
"": [],
".NETFramework,Version=v4.6": []
}
}

How to bind to ICloudBlob or some other (not string) type

I've been trying to create a Azure function being triggered when I add a image to a container on my blob storage account.
The only thing that seems to work, is when I have a string parameter, but the files are images, so I have no use for a string containing the image data.
So I've been trying each and every example I can find online (not that many), and now I've tried the samples from the azure webjobs sdk - this isn't wokring either. So either I'm stupid, which I feel right now, I'm missing something obvious?
There are some of the errors I get:
Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.thumbnailgenerator'. Microsoft.Azure.WebJobs.Host: Can't bind BlobTrigger to type 'Microsoft.WindowsAzure.Storage.Blob.ICloudBlob'.
Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.thumbnailgenerator'. Microsoft.Azure.WebJobs.Host: Can't bind BlobTrigger to type 'Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob'.
Right now the function I'm trying out, is the one given in the sample above, and like so many others I've tried, it's not working with anything but strings.
So how should I create the function (with C#) and the function.json file, to make it work with a blob in and preferable a string in with the name of the blob. Either that or blob in and one out, where the name of the out blob is in a different container and the name is prefixed with a hardcoded string.
This is what I got now, and it's not running:
function.json
{
"bindings": [
{
"type": "blobTrigger",
"name": "blob",
"direction": "in",
"path": "kitimages/{name}.{ext}"
},
{
"type": "blob",
"name": "output",
"direction": "inout",
"path": "thumbnails/{name}_300_200.{ext}"
} ],
"disabled": false
}
run.csx
#r "Microsoft.WindowsAzure.Storage"
using System;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage.Blob;
public static void Run(CloudBlockBlob blob, CloudBlockBlob output, TraceWriter log)
{
log.Info($"C# Blob trigger function processed a blob. Blob={blob.Name}");
}
EDIT: Take a look here for the final solution to my question: Getting work done in the cloud
We need to improve the template here, this is a common pitfall you've run into (sorry about that!). We're fixing, see the GitHub issue: Make it easier for users to get started with binary blob triggers.
There's a built-in template that binds to streams. Go to New Function and select C# for language and Samples for Scenario.
For a more advanced sample that uses CloudBlockBlob bindings (which requires the InOut binding direction that is not yet documented), see the Functions sample in ContosoMoments: DeleteImages Function.
Note that you can browse all the templates in the GitHub repo: https://github.com/Azure/azure-webjobs-sdk-templates.
For anyone else stumbling upon this while seemingly having a correct setup as per above:
I got this message because I had a reference to WindowsAzure.Storage in my project.json file. Perhaps because it was referring to an older version (8.1.1) of the library.. I don't know. Removing it made my function work. Since it's a supported DLL you should just import it using #r..
I found my solution here (the last reply by Baudine).
I had a project that referenced WindowsAzure.Storage nuget directly and a function project that that project but also referenced WindowsAzure.Storage indirectly (through Microsoft.Azure.WebJobs.Extensions.Storage nuget). After reading Baudine's answer, I saw that the versions off (v9.3.3 vs v9.3.1).
So my fix was as Baudine suggested: I removed the WindowsAzure.Storage nuget from the project and added Microsoft.Azure.WebJobs.Extensions.Storage. My trigger looks like this:
public async Task Run([BlobTrigger("/files/{fileName}", Connection = "StorageConnectionString")]ICloudBlob blob, string fileName)

Why can't my Azure Function find Microsoft.Xrm.Sdk assembly dependencies?

I'm using Azure Functions and want to write code that reads/writes to Dynamics CRM Online. I added the CRM 2015 SDK DLLs (all of them) to a bin folder under where the function.json file resides per Microsoft's documentation.
The function compiles fine.
When running the function I get this error:
Exception while executing function: Functions.CrmTest1. mscorlib: Exception has been thrown by the target of an invocation. Could not load file or assembly 'Microsoft.Xrm.Sdk, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
Here's the function body (just a small test sample):
#r "Microsoft.Xrm.Sdk.dll"
#r "Microsoft.Xrm.Client.dll"
using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Services;
public static void Run(string input, TraceWriter log)
{
var connectionString = "AuthType=Office365;Username=me#contoso.com; Password=MyPassword;Url=https://contoso.crm.dynamics.com";
CrmConnection connection = CrmConnection.Parse (connectionString);
using ( OrganizationService orgService = new OrganizationService(connection))
{
var query = new QueryExpression("account");
query.ColumnSet.AddColumns("name");
var ec = orgService.RetrieveMultiple(query);
log.Verbose(ec[0].GetAttributeValue<string>("name"));
}
}
There's no indication in the log files what needed assembly can't be found.
What am I missing with getting this to work? How can I find out what DLL is needed but is not found?
Tim,
The latest deployment that went live today contains the fix to address the issue you ran into. Please try again (you may need to restart your site to pick up the latest version if you had functions running) and let me know if you have any problems.
Thanks again for reporting this! I'm looking forward to seeing what you'll put together with Functions and Dynamics CRM.

Resources