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

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.

Related

Problem using Azure Blob Storage to save user conversations

I'm getting an error with the code below when I'm adding the Azure Blob Storage as a singleton. I think I've installed the dependencies correctly as:
<PackageReference Include="Microsoft.Bot.Builder.Azure" Version="4.6.3"/>
<PackageReference Include="Azure.Storage.Blobs" Version="12.2.0"/>
in the .csproj file. However the error I am getting relates t the AzureBlobStorage object in the code below;
<!-- language: c# -->
namespace Microsoft.BotBuilderSamples
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.)
var storageAccount = "connection_string_from_azure";
var storageContainer = "mybotstorage";
services.AddSingleton<IStorage>(new AzureBlobStorage(storageAccount, storageContainer));
// Create the User state. (Used in this bot's Dialog implementation.)
services.AddSingleton<UserState>();
// Create the Conversation state. (Used by the Dialog system itself.)
services.AddSingleton<ConversationState>();
// Other Startup things
}
}
}
The error is:
The type or namespace name 'AzureBlobStorage' could not be found (are you missing a using directive or an assembly reference?) [CoreBot]
Any help greatly appreciated.
Problem solved, I had to open the bot in MS Visual Studio and install the Azure dependency. I was editing in MS Visual Studio Code, so not sure how I could've done a work around from there.

NuGet Packages do not compile Azure CSX

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.

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;
}

Unable to find assembly on Azure Mobile Service

I have an Azure Mobile Service project which has a dependency to another (persistence) project which is referencing FluentNHibernate. Locally everything is running correctly in Release and Debug mode. Publishing the project seems to be successful (blue smiley). The problems starts when I make a request, where FluentNHibernate is used. I get the following error message:
Unable to find assembly 'FluentNHibernate, Version=2.0.3.0, Culture=neutral, PublicKeyToken=null'.
I already tried a lot of things:
Reinstalling packages
A new plain vanilla Mobile Service
Adding dependentAssembly in Web.config in the main project and App.config in the persistence project.
A little confusing for me is following fact: When I change the version of the FluentNHibernate package, I can see in the publish preview window that this dll will not be updated.
I am really not sure if this problem is depended to this specific package (FluentNHibernate). For example, what means: PublicKeyToken=null?
What else can I try to make the service running in the cloud?
The code below worked for my solution. It wires up a handler to the AppDomain's AssemblyResolve event, which is raised if an assembly cannot be found. In this case, I tell it to check the currently loaded assemblies and return one if there is a match, which there should be for FluentNHibernate. Try sticking this as the first line in WebApiConfig.Register
public static void Register()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
return AppDomain.CurrentDomain.GetAssemblies()
.Where(a => a.FullName == args.Name).FirstOrDefault();
};
// the rest of WebApiConfig.Register...
}

Sql-Clr Security Exception

Recently i created an application which could get the password of the user, whose username is provided as the parameter, i checked the code, its working fine, now i created a class library so that i can add this assemnbly in sql server 2008, below is the code of my class library.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
public class DnnUserCredentials
{
public static string GetUserPassword(string username)
{
MembershipUser objUser = Membership.GetUser(username);
return objUser.GetPassword();
}
}
i created the assembly in sql server 2008 like below
CREATE ASSEMBLY DNN_USER_CREDENTIALS FROM 'E:\NBM SITES\SqlProjectDll (DO NOT DELETE)\UserCredentials.dll' WITH PERMISSION_SET = SAFE
i got the command completed successfully message, then i created a function like below:
ALTER FUNCTION [dbo].[fn_UserCredentials](#UserName [nvarchar](max))
RETURNS [nvarchar](max) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [DNN_USER_CREDENTIALS].[DnnUserCredentials].[GetUserPassword]
here too i got the command completed successfully message, now when i tried to call the function using
SELECT [dbo].[fn_UserCredentials]('host')
it throws me below error:
A .NET Framework error occurred during execution of user-defined routine or aggregate "fn_UserCredentials":
System.Security.SecurityException: Request for the permission of type 'System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
System.Security.SecurityException:
at DnnUserCredentials.GetUserPassword(String username)
any solutions.
Not sure what can be the problem. First try to change the PERMISSION_SET to Unrestricted.
When this does not help try to debug the DLL from visual studio.
You need to set PERMISSION_SET = UNSAFE to get access to remote resources.
Also you might want to set TRUSTWORTHY flag to ON.
ALTER [<DBName>] SET TRUSTWORTHY ON
GO
CREATE ASSEMBLY [<assemblyName>]
--user with sysadmin rights for this DB may be required for deploing
AUTHORIZATION [<someSysadmin>]
FROM '[<pathToDll>]'
--compiled with unsafe to access EventLog for example
WITH PERMISSION_SET = UNSAFE
GO

Resources