'How do I get ASPNET WebAPI working with Microsoft.Owin.Host.HttpListener on an Azure worker role using an IoC container?
When I have the following packages installed in an Azure worker role:
<package id="Microsoft.AspNet.WebApi.Client" version="5.1.0" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.1.0" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.OData" version="5.1.0" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.1.0" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.1.0" targetFramework="net451" />
<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.Data.Services.Client" version="5.6.0" targetFramework="net451" />
<package id="Microsoft.Owin" version="2.0.2" targetFramework="net451" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net451" />
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net451" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.3" targetFramework="net451" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net451" />
<package id="Owin" version="1.0" targetFramework="net451" />
<package id="RavenDB.Client" version="2.5.2750" targetFramework="net451" />
<package id="System.Spatial" version="5.6.0" targetFramework="net451" />
<package id="Unity" version="3.0.1304.1" targetFramework="net451" />
<package id="Unity.WebAPI" version="5.1" targetFramework="net451" />
<package id="WindowsAzure.Storage" version="3.0.2.0" targetFramework="net451" />
I can get the application working as long as I don't try to register an IoC container.
As soon as I put this line in my Startup.cs file:
config.DependencyResolver = new UnityDependencyResolver(new UnityContainer());
I get the following exception:
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in Microsoft.WindowsAzure.ServiceRuntime.dll
If I put the exact same code in a console application, it works without throwing an exception.** Here is the full content of my WorkerRole.cs class:
public class WorkerRole : RoleEntryPoint
{
IDisposable _app;
public override void Run()
{
Trace.TraceInformation("Timbre.Catalogue.ApiRole entry point called");
while (true)
{
Thread.Sleep(10000);
Trace.TraceInformation("Working");
}
}
public override bool OnStart()
{
ServicePointManager.DefaultConnectionLimit = 12;
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["ApiEndpoint"];
var baseUri = string.Format("{0}://{1}", endpoint.Protocol, endpoint.IPEndpoint);
Trace.TraceInformation("Starting OWIN at {0}", baseUri);
_app = WebApp.Start<Startup>(new StartOptions(baseUri));
return base.OnStart();
}
public override void OnStop()
{
if (_app != null)
_app.Dispose();
base.OnStop();
}
}
And hers is the full content of my Startup.cs class:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.MapHttpAttributeRoutes();
config.DependencyResolver = new UnityDependencyResolver(new UnityContainer());
app.UseWebApi(config);
}
}
I have the same problem when trying to use Castle.Windsor with the following package:
<package id="WebApiContrib.IoC.CastleWindsor" version="0.10.0.0" targetFramework="net451" />
and this line of code instead:
config.DependencyResolver = new WindsorResolver(new WindsorContainer().Install(FromAssembly.This()));
Can anyone give me a clue as to what is wrong here? I suspect it is a problem with the Azure compute emulator because it works perfectly in a console application, however I have no idea how to diagnose it any further than that.
Solution 1:[1]
5.1 version of Unity.WebApi
nuget package was built with reference to 5.0
version of Web API. So we need a binding redirect to make Unity work with 5.1
version of Web API.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Related to your later comment about figuring out the exception details:
You can checkout the new Global Error Handling feature in Web API 5.1. Following is a snippet of it.
config.Services.Add(typeof(IExceptionLogger), new CustomExceptionLogger());
public class CustomExceptionLogger : ExceptionLogger
{
public override void Log(ExceptionLoggerContext context)
{
//TODO: Log the exception details
//context.Request
//context.Exception
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |