How do I get ASPNET WebAPI working with Microsoft.Owin.Host.HttpListener on an Azure worker role using an IoC container?

StackOverflow https://stackoverflow.com/questions/21334515

Domanda

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.

È stato utile?

Soluzione

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
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top