Getting Method not found error when accessing to Azure KeyVault - azure-keyvault

I am trying to get my connection string from Azure Keyvault in the application_start event of my .Net web application.
protected void Application_Start(Object sender, EventArgs e)
{
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));
RegisterRoutes(RouteTable.Routes);
}
public static async Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
ClientCredential clientCred = new ClientCredential(ConfigurationManager.AppSettings["clientId"],
ConfigurationManager.AppSettings["clientSecret"]);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
if (result == null)
throw new InvalidOperationException("Failed to obtain the JWT token");
return result.AccessToken;
}
But I get this error below.
This is a new MVC web application with .Net 4.6.
The exact same code works fine on a Console app.
I compared the package versions and they are the same.
I also tried to put that code in the constructor of a controller but the same error.
Any ideas?
Method not found: 'Void
Microsoft.Azure.KeyVault.KeyVaultClient..ctor(AuthenticationCallback,
System.Net.Http.DelegatingHandler[])'.
[MissingMethodException: Method not found: 'Void
Microsoft.Azure.KeyVault.KeyVaultClient..ctor(AuthenticationCallback,
System.Net.Http.DelegatingHandler[])'.]
WebApplication1.MvcApplication.Application_Start() in
C:\Users\test\Documents\Visual Studio
2017\Projects\ConsoleApp1\WebApplication1\Global.asax.cs:27
[HttpException (0x80004005): Method not found: 'Void
Microsoft.Azure.KeyVault.KeyVaultClient..ctor(AuthenticationCallback,
System.Net.Http.DelegatingHandler[])'.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext
context, HttpApplication app) +10062145
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr
appContext, HttpContext context, MethodInfo[] handlers) +118
System.Web.HttpApplication.InitSpecial(HttpApplicationState state,
MethodInfo[] handlers, IntPtr appContext, HttpContext context) +173
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr
appContext, HttpContext context) +336
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr
appContext) +296
[HttpException (0x80004005): Method not found: 'Void
Microsoft.Azure.KeyVault.KeyVaultClient..ctor(AuthenticationCallback,
System.Net.Http.DelegatingHandler[])'.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +10043436
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +95
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest
wr, HttpContext context) +254
<packages>
<package id="Antlr" version="3.4.1.9004" targetFramework="net461" />
<package id="bootstrap" version="3.0.0" targetFramework="net461" />
<package id="jQuery" version="1.10.2" targetFramework="net461" />
<package id="jQuery.Validation" version="1.11.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights" version="2.2.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.0.6" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.2.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.2.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.Web" version="2.2.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.WindowsServer" version="2.2.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.2.0" targetFramework="net461" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net461" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net461" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net461" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net461" />
<package id="Microsoft.Azure.KeyVault" version="2.3.2" targetFramework="net461" />
<package id="Microsoft.Azure.KeyVault.WebKey" version="2.0.7" targetFramework="net461" />
<package id="Microsoft.Azure.Services.AppAuthentication" version="1.1.0-preview" targetFramework="net461" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.7" targetFramework="net461" />
<package id="Microsoft.Extensions.Configuration" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.Extensions.Configuration.Abstractions" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.Extensions.Configuration.AzureKeyVault" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.Extensions.Configuration.FileExtensions" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.Extensions.FileProviders.Abstractions" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.Extensions.FileProviders.Physical" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.Extensions.FileSystemGlobbing" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.Extensions.Primitives" version="2.0.0" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.14.2" targetFramework="net461" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.3" targetFramework="net461" />
<package id="Microsoft.Net.Compilers" version="2.1.0" targetFramework="net461" developmentDependency="true" />
<package id="Microsoft.Rest.ClientRuntime" version="2.3.8" targetFramework="net461" />
<package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.7" targetFramework="net461" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net461" />
<package id="Modernizr" version="2.6.2" targetFramework="net461" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net461" />
<package id="Respond" version="1.2.0" targetFramework="net461" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.4.0" targetFramework="net461" />
<package id="WebGrease" version="1.5.2" targetFramework="net461" />
</packages>

I had to remove System.Net.Http from references and re-add it since the application was loading 2 different versions of that library for some unknown reason.

In our case, we solved it using the following property in projects depending on KeyVault nuget package:
<ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>
As a result, this forces a reference to System.Net.Http in GAC.

Faced similar issue. Solution for me was:
I had solution in .NET Framework 4.6.2 and when I added the KeyVault SDK from nugget it also took System.Net.Http 4.3.4 with that. But accordingly to the description of the key vault SDK, it is requirement just for .NET standard 1.4 and 2.0 not for .NET Framework. As my whole application used the System.Net.Http 4.0.0 from GAC, I manually removed the System.Net.Http added via nugget (removed it from packages.config) and added reference from GAC to version 4.0.0.
After that, I got rid of the error.

Related

Why "Method not found: 'Void System.Web.Http.HttpResponseException..ctor" after package update?

I have an ASP.NET MVC application which started to misbehave after the last NuGet package updates. The web app uses .NET Framework 4.6.1, and the developer machine is a Windows Server 2012 R2 Essentials. One package I use is Stripe.NET for payment processing. Its earlier versions required only <package id="System.Net.Http" version="4.0.0" targetFramework="net461" />. Visual Studio marked that there's a newer version of that (at that time it was 4.3.0), but when I updated that it pulled in a ton of packages. So I simply reverted back that dependency to 4.0.0, Stripe didn't require newer.
Then lately I introduced Nager.Date to handle work days and holidays. The latest update (v 1.5.0) of that package requires "NETStandard.Library" version="1.6.1". Just like upgrading System.Net.Http to 4.3.0, upgrading to that Nager.Date pulls in the ton of packages I mention. In summary: sooner or later I have to cave in and update.
The pulled-in packages:
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.AppContext" version="4.3.0" targetFramework="net461" />
<package id="System.Collections" version="4.3.0" targetFramework="net461" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
<package id="System.Console" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
<package id="System.Globalization" version="4.3.0" targetFramework="net461" />
<package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net461" />
<package id="System.IO" version="4.3.0" targetFramework="net461" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net461" />
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Linq" version="4.3.0" targetFramework="net461" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net461" />
<package id="System.Net.Http" version="4.3.1" targetFramework="net461" />
<package id="System.Net.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Net.Sockets" version="4.3.0" targetFramework="net461" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net461" />
<package id="System.Reflection" version="4.3.0" targetFramework="net461" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net461" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net461" />
<package id="System.Runtime" version="4.3.0" targetFramework="net461" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net461" />
<package id="System.Runtime.Handles" version="4.3.0" targetFramework="net461" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />
<package id="System.Threading" version="4.3.0" targetFramework="net461" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" />
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net461" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" />
I would still be in peace with all of this if in the end I won't be presented with:
Exception thrown: 'System.MissingMethodException' in ThruThink.dll
Additional information: Method not found: 'Void System.Web.Http.HttpResponseException..ctor(System.Net.Http.HttpResponseMessage)'.
I couldn't figure out why this happened. Nager.Date owner gave me an idea: he generated the latest package with VS 2017, so I installed that hoping that it'll install some assemblies which will magically solve this exception. But that didn't happen so far.
I don't understand the list of these packages. A lot of them are foundational libraries which supposed to be part of the CLR itself (like System.IO, System.Console, ...) and available without a NuGet package. Maybe one clue is that I see Microsoft.NETCore.Platforms, although I'm with .NET 4.6.1, not using .NET Core. I haven't played with .NET Core too much yet, but those packages make sense for .NET Core infrastructure. What's going on?
The newest version of Nager.Date didn't pull in all of those dependencies and I don't face this problem any more.
You're hitting System.Net.Http OOB versioning issue, see Broken System.Net.Http 4.1.1-4.3.0 post-mortem. An assembly redirect should fix the problem:
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
You may need to redirect to 4.1.1.2 or 4.0.0.0 instead, depending on your project and the libraries you reference.

ASP.net MVC 4 and Autofac error - Inheritance security rules violated while overriding member

I am getting some strange error while configuring Autofac on ASP.MVC 4. I have worked with Autofac on MVC 4 on many other projects successfully. This MVC project is in .Net 4.5.2 and I am referencing the following Autofac libraries from nuget:
Autofac version=3.5.2
Autofac.Mvc4 version=3.1.0
The error that I am getting is:
"Inheritance security rules violated while overriding member: 'Autofac.Integration.Mvc.AutofacDependencyResolver.GetService(System.Type)'. Security accessibility of the overriding method must match the security accessibility of the method being overriden."
The weird thing is that my code is even not called that this error is fired!! My code is as below:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
try
{
AutofacDependencyResolverHelper.RegisterAutofac();
}
catch (Exception ex)
{
Trace.Write(ex.Message);
throw;
}
}
public class AutofacDependencyResolverHelper
{
public static void RegisterAutofac()
{
var container = GetContainer();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
public static IContainer GetContainer()
{
var assemblies = new List<Assembly>();
assemblies.Add(Assembly.Load("Core.Infrastructure"));
assemblies.Add(Assembly.Load("Core.GenericRepository"));
assemblies.Add(Assembly.Load("Core.Common"));
assemblies.Add(Assembly.Load("CRM.Interfaces"));
assemblies.Add(Assembly.Load("CRM.Data"));
assemblies.Add(Assembly.Load("CRM.Dtos"));
assemblies.Add(Assembly.Load("CRM.Entities"));
assemblies.Add(Assembly.Load("CRM.Business"));
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(assemblies.ToArray()).AsImplementedInterfaces();
builder.RegisterControllers(Assembly.Load("CRM.Web.Mvc4"));
var container = builder.Build();
return container;
}
}
Not sure what this error is? Any comments will be appreciated. I have found some other questions but they are related to MVC5:
Solving Autofac issue Inheritance security rules violated while overriding member GetService
Updated with full config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="angularjs.TypeScript.DefinitelyTyped" version="4.2.7" targetFramework="net46" />
<package id="Antlr" version="3.4.1.9004" targetFramework="net46" />
<package id="Autofac" version="3.5.2" targetFramework="net46" />
<package id="Autofac.Mvc4" version="3.1.0" targetFramework="net46" />
<package id="bootstrap" version="3.0.0" targetFramework="net46" />
<package id="jQuery" version="1.10.2" targetFramework="net46" />
<package id="jquery.TypeScript.DefinitelyTyped" version="0.0.1" targetFramework="net46" />
<package id="jQuery.Validation" version="1.11.1" targetFramework="net46" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net46" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.3" targetFramework="net46" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net46" />
<package id="Modernizr" version="2.6.2" targetFramework="net46" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net46" />
<package id="Respond" version="1.2.0" targetFramework="net46" />
<package id="WebGrease" version="1.5.2" targetFramework="net46" />
</packages>
Ok, found the issue. Even though it was an MVC4 application I added reference to Autofac MVC5 using nuget and that sorted out the issue. Ie:
package id="Autofac.Mvc5" version="3.3.4" targetFramework="net452"
Instead of:
package id="Autofac.Mvc4" version="3.1.0" targetFramework="net46"
Strange.but it worked!

Why does Azure CloudConfigurationManager.GetSetting return null

I have a cloud service web role project that runs locally in the emulator, but does not run when deployed. The error given is as follows:
[ArgumentNullException: Value cannot be null.
Parameter name: connectionString]
Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(String connectionString) in e:\projects\azure-sdk-for-net\microsoft-azure-api\Services\Storage\Lib\Common\CloudStorageAccount.cs:344
Candor.WindowsAzure.Storage.Table.CloudTableProxy`1.GetTable() in c:\Users\micha_000\Documents\GitHub\candor-common\Candor.WindowsAzure\Storage\Table\CloudTableProxy.cs:66
Candor.WindowsAzure.Storage.Table.CloudTableProxy`1.Get(String partitionKey, String rowKey) in c:\Users\micha_000\Documents\GitHub\candor-common\Candor.WindowsAzure\Storage\Table\CloudTableProxy.cs:117
Candor.WindowsAzure.Logging.Common.Table.CloudTableLogger.get_Configuration() +218
Candor.WindowsAzure.Logging.Common.Table.CloudTableLogger.get_IsInfoEnabled() +9
Common.Logging.Factory.AbstractLogger.Info(Object message) in c:\_oss\common-logging\src\Common.Logging.Core\Logging\Factory\AbstractLogger.cs:503
Candor.Configuration.Provider.ProviderCollection`1.SetActiveProvider(T provider) in c:\Users\micha_000\Documents\GitHub\candor-common\Candor\Configuration\Provider\ProviderCollection.cs:169
Candor.Configuration.Provider.ProviderResolver`1.AppendActive(T provider) in c:\Users\micha_000\Documents\GitHub\candor-common\Candor\Configuration\Provider\ProviderResolver.cs:77
SHM.PublicMvcWeb.App_Start.ProviderBootstrapper.InitProviders() in c:\Users\micha_000\Documents\Git-Repos\shm-main\SHM.PublicMvcWeb\App_Start\ProviderBootstrapper.cs:23
SHM.PublicMvcWeb.App_Start.ProviderBootstrapper.PostStartup() in c:\Users\micha_000\Documents\Git-Repos\shm-main\SHM.PublicMvcWeb\App_Start\ProviderBootstrapper.cs:18
You can see the code for the relevant lines shown in the stack trace on github.
https://github.com/michael-lang/candor-common/
The lines leading to the error in CloudTableProxy are:
if (String.IsNullOrWhiteSpace(_connectionName))
throw new InvalidOperationException("The Cloud ConnectionName has not been configured.");
if (_account == null)
_account = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(_connectionName));
Since it does not throw the custom error "The cloud connectionName has not been configured.", that tells me that _connectionName passed into CloudConfigurationManager.GetSetting is not null. So CloudConfigurationManager is the call returning null for the supplied name. Given that this name does return a value when running locally, I am not sure why it isn't found when deployed to my cloud web role. If the connection name was entered as a typo, then it wouldn't work locally either. To be sure, here is my common logging configuration naming the connection to be used:
<common>
<logging>
<factoryAdapter type="Candor.WindowsAzure.Logging.Common.Table.CloudTableLoggerFactoryAdapter, Candor.WindowsAzure.Logging.Common">
<arg key="connectionName" value="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
</factoryAdapter>
</logging>
</common>
I also have an entirely different solution with a cloud service web role using the same Candor.Common components, so I don't believe they are the problem.
I am using the same laptop to develop both solutions, and so both are using the Azure 2.2 Tools version. Inspecting the properties of the Cloud Service project in each solution verifies this.
I inspected every component and NuGet package reference to be sure there are no version mismatches through the solution. The same components are set to copy-local=true between the working solution and this non-working solution. They also have the same binding redirects. Although this was my biggest issue, now resolved, before running into this connection issue.
The non-working service deployment configuration:
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="SHM.AzureService.PublicMvcWeb" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="4" osVersion="*" schemaVersion="2013-10.2.2">
<Role name="SHM.PublicMvcWeb">
<Instances count="1" />
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)" />
<Setting name="DefaultTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)" />
<Setting name="UserTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)" />
<Setting name="UserSaltTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)" />
<Setting name="UserAuditTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)" />
</ConfigurationSettings>
</Role>
</ServiceConfiguration>
I also recently tried putting these same connection names in the web application's appsettings. This was in response to a comment 3 years ago that their code was executing before RoleEnvironment.OnStart. But this attempt still results in the same error.
Here is what the attempt looked like:
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)"/>
<add key="DefaultTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)"/>
<add key="UserTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)"/>
<add key="UserSaltTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)"/>
<add key="UserAuditTableConnection" value="DefaultEndpointsProtocol=https;AccountName=(redacted);AccountKey=(redacted)"/>
</appSettings>
This code in error does run on start of the application using WebActivator 2.0.6, wheras my working solution uses WebActivator 2.0.4. But the release notes of WebActivator only shows compilation change from Debug to "Retail" and a license change between the two versions, and those changes were a year ago.
In case timing was the issue, I also tried adding a Thread.Sleep(1000) just before the call in error, and it didn't work either, so I am going to remove it.
using System.Threading;
using Candor.Configuration.Provider;
using Candor.Security;
using Candor.Security.Cryptography;
using Candor.Security.Web;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(StopHarassingMe.PublicMvcWeb.App_Start.ProviderBootstrapper), "PreStartup")]
[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(StopHarassingMe.PublicMvcWeb.App_Start.ProviderBootstrapper), "PostStartup")]
namespace SHM.PublicMvcWeb.App_Start
{
public class ProviderBootstrapper
{
public static void PreStartup()
{
}
public static void PostStartup()
{
Thread.Sleep(1000); //let RoleEnvironment finish startup first or connectionstrings are not available.
InitProviders();
}
private static void InitProviders()
{
ProviderResolver<HashProvider>.Configure()
.AppendActive(new SHA2HashProvider("sha2") { IsObsolete = false, SaltModifier = "" });
}
}
}
This is the first provider configured in both the working and non-working solutions.
Here is a list of the packages used by the web application in error:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net45" />
<package id="Candor.Core" version="1.4.1.0" targetFramework="net45" />
<package id="Candor.jQuery.AutoAsync" version="4.0.0.50129" targetFramework="net45" />
<package id="Candor.Security" version="2.4.0.0" targetFramework="net451" />
<package id="Candor.Security.AzureStorageProvider" version="2.3.2.0" targetFramework="net451" />
<package id="Candor.Web.Mvc" version="1.0.3.0" targetFramework="net451" />
<package id="Candor.Web.Mvc.ErrorHandler" version="1.0.0.0" targetFramework="net45" />
<package id="Candor.Web.Mvc.Security" version="2.1.0.0" targetFramework="net45" />
<package id="Candor.WindowsAzure" version="1.3.0.0" targetFramework="net451" />
<package id="Candor.WindowsAzure.Logging.Common" version="1.1.1.0" targetFramework="net451" />
<package id="Common.Logging" version="2.2.0" targetFramework="net45" />
<package id="Common.Logging.Core" version="2.2.0" targetFramework="net45" />
<package id="form2js" version="1.0.0.30224" targetFramework="net45" />
<package id="jQuery" version="2.1.4" targetFramework="net451" />
<package id="jQuery.UI.Combined" version="1.8.20.1" targetFramework="net45" />
<package id="jQuery.Validation" version="1.13.1" targetFramework="net45" />
<package id="MarkdownSharp" version="1.13.0.0" targetFramework="net451" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.3" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Data.Edm" version="5.6.0" targetFramework="net451" />
<package id="Microsoft.Data.OData" version="5.6.0" targetFramework="net451" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.1.0" targetFramework="net45" />
<package id="Modernizr" version="2.8.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="Respond" version="1.4.2" targetFramework="net45" />
<package id="RestSharp" version="105.0.1" targetFramework="net451" />
<package id="System.Spatial" version="5.6.0" targetFramework="net451" />
<package id="T4MVC" version="3.7.4" targetFramework="net45" />
<package id="T4MVCExtensions" version="3.7.4" targetFramework="net45" />
<package id="Twilio" version="4.0.3" targetFramework="net451" />
<package id="Twilio.Mvc" version="3.1.15" targetFramework="net451" />
<package id="Twilio.TwiML" version="3.3.6" targetFramework="net451" />
<package id="WebActivatorEx" version="2.0.6" targetFramework="net451" />
<package id="WebGrease" version="1.6.0" targetFramework="net45" />
<package id="WindowsAzure.Storage" version="2.1.0.3" targetFramework="net45" />
</packages>
There are a couple package differences between my working and non-working solution, but I didn't think these were applicable to the error. I went from MVC 5.0 to 5.2.3, upgraded javascript related packages, and Candor.WindowsAzure from 1.2.10 to 1.3. That may seem relevant, but the only code change was to replace the implementation of a batch update method.
WORKING SOLUTION PROJECT PACKAGES:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net45" />
<package id="Candor.Core" version="1.4.1.0" targetFramework="net451" />
<package id="Candor.jQuery.AutoAsync" version="3.5.0.40210" targetFramework="net451" />
<package id="Candor.Security" version="2.4.0.0" targetFramework="net451" />
<package id="Candor.Security.AzureStorageProvider" version="2.3.2.0" targetFramework="net451" />
<package id="Candor.Web.Mvc" version="1.0.3.0" targetFramework="net451" />
<package id="Candor.Web.Mvc.ErrorHandler" version="1.0.0.0" targetFramework="net45" />
<package id="Candor.Web.Mvc.Security" version="2.1.0.0" targetFramework="net45" />
<package id="Candor.WindowsAzure" version="1.2.10.0" targetFramework="net451" />
<package id="Candor.WindowsAzure.Logging.Common" version="1.1.1.0" targetFramework="net451" />
<package id="Common.Logging" version="2.2.0" targetFramework="net451" />
<package id="Common.Logging.Core" version="2.2.0" targetFramework="net451" />
<package id="form2js" version="1.0.0.30224" targetFramework="net45" />
<package id="jQuery" version="2.0.3" targetFramework="net45" />
<package id="jQuery.UI.Combined" version="1.10.3" targetFramework="net45" />
<package id="jQuery.Validation" version="1.11.1" targetFramework="net45" />
<package id="MarkdownSharp" version="1.13.0.0" targetFramework="net451" />
<package id="Microsoft.AspNet.Mvc" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.2" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OData" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.Data" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.WebData" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.Data.Edm" version="5.6.0" targetFramework="net45" />
<package id="Microsoft.Data.OData" version="5.6.0" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.1.0" targetFramework="net45" />
<package id="Modernizr" version="2.7.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" />
<package id="SlidesJS" version="3.0.4" targetFramework="net451" />
<package id="System.Spatial" version="5.6.0" targetFramework="net45" />
<package id="T4MVC" version="3.7.4" targetFramework="net45" />
<package id="T4MVCExtensions" version="3.7.4" targetFramework="net45" />
<package id="WebActivatorEx" version="2.0.4" targetFramework="net45" />
<package id="WebGrease" version="1.6.0" targetFramework="net451" />
<package id="WindowsAzure.Storage" version="2.1.0.3" targetFramework="net45" />
</packages>
I tried to deploy as a website just to see what the difference would be. The table connection strings were in appSettings from the earlier attempts to get past the timing issue, so it made sense to try the websites deployment option (not a cloud web role).
The error from this attempt was
[FileNotFoundException: Could not load file or assembly 'Microsoft.WindowsAzure.ServiceRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.]
[FileNotFoundException: Could not load file or assembly 'Microsoft.WindowsAzure.ServiceRuntime, Version=2.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.]
Candor.WindowsAzure.Logging.Common.Table.CloudTableLogger.WriteInternal(LogLevel level, Object message, Exception exception) +0
Common.Logging.Factory.AbstractLogger.Info(Object message) in c:\_oss\common-logging\src\Common.Logging.Core\Logging\Factory\AbstractLogger.cs:504
Candor.Configuration.Provider.ProviderCollection`1.SetActiveProvider(T provider) in c:\Users\micha_000\Documents\GitHub\candor-common\Candor\Configuration\Provider\ProviderCollection.cs:166
Candor.Configuration.Provider.ProviderResolver`1.AppendActive(T provider) in c:\Users\micha_000\Documents\GitHub\candor-common\Candor\Configuration\Provider\ProviderResolver.cs:75
This was odd, since the other working solution web role deployed to the cloud now, has that reference set as CopyLocal=false. But when I set it to true in this non-working solution, it started to work in the website deployment.
Next I redeployed the cloud web role with this component set as CopyLocal=True and it now works. I don't know why this is required in one project deployment and not the other, While both projects required the other azure components to be CopyLocal=true.
There is still one lingering problem with startup speed, but I'll leave that for another question, if I don't figure it out. For some reason this smaller project goes in a busy/recycle loop after it starts, but the page loads now and then. It is quite odd since it has fewer dependencies initialized on startup, that is providers instantiated that write a single log entry each.
Straight point to the question is - CloudConfigurationManager.GetSetting will read the given config key from Cloud Project settings if defined or else will fall back to actual project App Or Web config. So if you make sure that it exists at one of the places, it should work fine. As you confirmed that it is working locally, it should work exactly the same way even after deployment.
Other case that can happen is when you are having multiple config files for local and cloud deployment environments and that config could be missing from your cloud configuration file that you used to deploy into cloud.
In my case, I used SlowCheetah (NuGet package) to transform App.config files. In Debug it did not use the Transformation. Using the Debug settings in the "root"-config file solved my problem.

Autofac global exception filter throwing null reference exception

I'm trying to add a global exception handling filter that will log errors in an MVC 5 app. I need to use Autofac to inject an error logging service into the filter to log the errors. I have been using Autofac in this app for some time to inject my services and repositories without issue.
When I follow the procedures outlined here and here I am met with a null reference exception:
[NullReferenceException: Object reference not set to an instance of an
object.]
Autofac.Integration.Mvc.AutofacFilterProvider.GetFilters(ControllerContext
controllerContext, ActionDescriptor actionDescriptor) +206
System.Web.Mvc.FilterProviderCollection.GetFilters(ControllerContext
controllerContext, ActionDescriptor actionDescriptor) +182
System.Web.Mvc.ControllerActionInvoker.GetFilters(ControllerContext
controllerContext, ActionDescriptor actionDescriptor) +37
...
I have removed the global filter registration for this attribute in the global.asax:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AuthorizeAttribute());
//filters.Add(new HandleExceptionAttribute());
}
And setup my Autofac dependency registration:
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyTypes(typeof(BaseService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.PropertiesAutowired();
builder.RegisterFilterProvider();
builder.RegisterType<HandleExceptionAttribute>()
.AsExceptionFilterFor<BaseController>()
.InstancePerHttpRequest()
.PropertiesAutowired();
And my Handle Exception Attribute with constructor injection:
public class HandleExceptionAttribute : HandleErrorAttribute
{
private IErrorLoggingService Service { get; set; }
public HandleExceptionAttribute(IErrorLoggingService service)
{
this.Service = service;
}
public override void OnException(ExceptionContext filterContext)
{
this.Service.LogError(new Error());
}
}
I've done a lot of Googling on this subject but was not able to find an exact example of what I'm looking for. A few results indicated an issue with also having Glimpse installed, which I had, but since removed. Calling builder.RegisterFilterProvider(); inside of the Autofac setup is the line that causes the exception.
Am I missing something or is this just not possible? Does anyone have a working example? Thanks!
Edit:
I have another global filter applied (AuthorizeAttribute) and I tried removing it but I still get the null ref exception. Another thought was that I'm using other nuget packages that could cause conflicts, like Glimpse has in the past.
Here are other nuget packages I am using:
<packages>
<package id="AmplifyJS" version="1.1.0" targetFramework="net45" />
<package id="angularjs" version="1.2.16" targetFramework="net45" />
<package id="Antlr" version="3.5.0.2" targetFramework="net45" />
<package id="Autofac" version="3.3.1" targetFramework="net45" />
<package id="Autofac.Mvc5" version="3.2.1" targetFramework="net45" />
<package id="CsQuery" version="1.3.4" targetFramework="net45" />
<package id="EntityFramework" version="6.1.0" targetFramework="net45" />
<package id="jQuery" version="2.1.0" targetFramework="net45" />
<package id="jQuery.Migrate" version="1.2.1" targetFramework="net45" />
<package id="jQuery.Validation" version="1.12.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.1.2" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.1.2" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.1.2" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.1.2" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.1.2" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="MicrosoftWebMvc" version="2.0" targetFramework="net45" />
<package id="MoxieManager" version="1.0" targetFramework="net45" />
<package id="Mvc2Futures" version="2.0.50217.0" targetFramework="net45" />
<package id="MvcContrib" version="2.0.95.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.2" targetFramework="net45" />
<package id="PreMailer.Net" version="1.2.4" targetFramework="net45" />
<package id="WebGrease" version="1.6.0" targetFramework="net45" />
</packages>
I will try an MVC project from scratch as you suggested to see what happens.
Couldn't reproduce your issue on empty MVC5 project. Make sure you are using correct packages and your code doesn't have any extra wired staff. Here is my solution that works fine.
packages.config:
<packages>
<package id="Autofac" version="3.3.1" targetFramework="net451" />
<package id="Autofac.Mvc5" version="3.2.1" targetFramework="net451" />
<package id="Microsoft.AspNet.Mvc" version="5.1.0" targetFramework="net451" />
<package id="Microsoft.AspNet.Razor" version="3.1.0" targetFramework="net451" />
<package id="Microsoft.AspNet.WebPages" version="3.1.0" targetFramework="net451" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
</packages>
HandleExceptionAttribute:
public class HandleExceptionAttribute : HandleErrorAttribute
{
private IErrorLoggingService Service { get; set; }
public HandleExceptionAttribute(IErrorLoggingService service)
{
this.Service = service;
}
public override void OnException(ExceptionContext filterContext)
{
this.Service.LogError(filterContext.Exception);
}
}
IErrorLoggingService:
public interface IErrorLoggingService
{
void LogError(Exception error);
}
ErrorLoggingService:
public class ErrorLoggingService : IErrorLoggingService
{
public void LogError(Exception error)
{
Debug.WriteLine(error);
}
}
dependencyResolver replacement:
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.PropertiesAutowired();
builder.RegisterFilterProvider();
builder.RegisterType<HandleExceptionAttribute>()
.AsExceptionFilterFor<BaseController>()
.InstancePerHttpRequest()
.PropertiesAutowired();
DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
if your solution still doesn't work, try to create an empty project and check if it works fine.

ELMAH requires System.Data.SqlServerCe.dll

Installed the ELMAH NuGet package. Now, when I publish my ASP.NET MVC 4 project to Azure, it warns me that it wants my project to have a direct reference to System.Data.SqlServerCe.dll (so that the DLL, which is apparently referenced by ELMAH, is included in the bits uploaded to Azure).
I'm not using SQL Compact Edition for logging, so I assume that I don't really need that DLL (and, in fact, the Azure package works just fine without it).
So, how do I resolve this "missing DLL" issue? I could try to find and remove the part of ELMAH that references this DLL, but it would just come back the next time a new version of ELMAH is released. Since the DLL is apparently not in the GAC, I could add a reference to the copy of System.Data.SqlServerCe.dll that's stashed away under my C:\Program Files (X86) folder, but that smells ugly to me. Or I could just ignore the warning, but as a matter of principle (and published policy) I don't tolerate warnings lightly.
Any suggestions?
EDIT:
Daniel Powell asked me to post my NuGet packages.config, which looks like this (I hope - this is deeper magic than I've dug into)
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DotNetOpenAuth.AspNet" version="4.2.2.13055" targetFramework="net45" />
<package id="DotNetOpenAuth.Core" version="4.2.2.13055" targetFramework="net45" />
<package id="DotNetOpenAuth.OAuth.Consumer" version="4.2.2.13055" targetFramework="net45" />
<package id="DotNetOpenAuth.OAuth.Core" version="4.2.2.13055" targetFramework="net45" />
<package id="DotNetOpenAuth.OpenId.Core" version="4.2.2.13055" targetFramework="net45" />
<package id="DotNetOpenAuth.OpenId.RelyingParty" version="4.2.2.13055" targetFramework="net45" />
<package id="elmah" version="1.2.2" targetFramework="net45" />
<package id="elmah.corelibrary" version="1.2.2" targetFramework="net45" />
<package id="EntityFramework" version="5.0.0" targetFramework="net45" />
<package id="Glimpse" version="1.1.0" targetFramework="net45" />
<package id="Glimpse.AspNet" version="1.1.0" targetFramework="net45" />
<package id="Glimpse.Mvc3" version="1.1.0" targetFramework="net45" />
<package id="jQuery" version="1.9.1" targetFramework="net45" />
<package id="jQuery.UI.Combined" version="1.10.1" targetFramework="net45" />
<package id="jQuery.Validation" version="1.11.0" targetFramework="net45" />
<package id="knockoutjs" version="2.2.1" targetFramework="net45" />
<package id="log4net" version="2.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.20715.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.Data" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.OAuth" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.WebData" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.Data.Edm" version="5.3.0" targetFramework="net45" />
<package id="Microsoft.Data.OData" version="5.3.0" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="2.0.30116.0" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="2.0.30116.0" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="1.8.0.0" targetFramework="net45" />
<package id="Modernizr" version="2.6.2" targetFramework="net45" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
<package id="System.Spatial" version="5.3.0" targetFramework="net45" />
<package id="WebGrease" version="1.3.0" targetFramework="net45" />
<package id="WindowsAzure.Storage" version="2.0.5.0" targetFramework="net45" />
</packages>
I've been running a service on Azure for many months with this same warning. If you're sure you're not using SQL Server CE it's fine.
It is an annoying warning but as far as I can tell does no harm.

Resources