We are having a problem with our solution when it's hosted in a windows container that I don't encounter on my local. I have a WebAPI project using .Net Framework 4.6.2. It is referencing a custom Nuget package we wrote targeting net461;net462;netstandard2.0;. As I said in my title when I run this on my local machine everything is fine. When we publish it to a docker container image: microsoft/dotnet-framework:4.7-windowsservercore-10.0.14393.1884 we get the following error when we try to hit one of the end points in the Nuget Package. Could anyone suggest a solution or possible next trouble shooting step? We've been throwing some guesses based on Stack Overflow searches, but haven't found anything that works.
The ProjectAPI service is now running, press Control+C to exit.
2019-02-18 08:33:12,522 ERROR lobalExceptionLogger: CustomNugetPackageName Exception
System.IO.FileNotFoundException: Could not load file or assembly 'System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at CustomNugetPackageName.Controllers.ReportsController.GetReport(Int32 reportId, Report& report, IHttpActionResult& unauthorized)
at CustomNugetPackageName.Controllers.ReportsController.GetReport(Int32 reportId)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
I've tried setting binding redirects int he WebAPI project like so:
<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>
When I add that the application silently fails when I try to use Autofac to inject the NetStandard app to the WebAPI project. I've been really stumped on what could possibly be going on that's causing it to break in the container.
Here is my Autofac module and startup if you that matters:
Module:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using API.Claims;
using API.ControllerBase;
using Autofac;
using Autofac.Integration.WebApi;
using ReportingServiceBase.Base;
using Module = Autofac.Module;
namespace ReportingAPIBase.Initializers
{
/// <summary>
///
/// </summary>
public class ReportingStartupModule : Module
{
/// <summary>
///
/// </summary>
public int RestrictAccessValue { get; set; }
/// <inheritdoc />
protected override void Load(ContainerBuilder builder)
{
builder.RegisterModule(new ReportingServiceModule());
var assembly = Assembly.GetExecutingAssembly(); // this
List<Type> controllers = (from t in assembly.GetTypes()
where t.IsClass && typeof(ApiControllerBase).IsAssignableFrom(t)
select t).ToList();
// Add Restrict Attribute
foreach (Type controller in controllers)
{
TypeDescriptor.AddAttributes(controller, new API.Claims.RestrictAttribute(RestrictAccessValue, ClaimValues.FullAccess | ClaimValues.ReadOnly));
}
builder.RegisterApiControllers(assembly);
}
}
}
Startup
using System.Reflection;
using System.Web.Http;
using System.Web.Http.ExceptionHandling;
using API.Base;
using API.Common;
using API.Jwt;
using API.RoleManager;
using Autofac;
using Autofac.Integration.WebApi;
using AutoMapper;
using AutoMapper.Configuration;
using log4net.Config;
using Microsoft.Owin;
using Microsoft.Owin.FileSystems;
using Microsoft.Owin.StaticFiles;
using Model.Reporting;
using Owin;
using ReportingAPIBase.Initializers;
using Service;
using Service.Utilities;
[assembly: XmlConfigurator(ConfigFile = "l4n.config", Watch = true)]
namespace API
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Configure Web API for self-host.
var config = new HttpConfiguration();
// Register modules and types
var builder = new ContainerBuilder();
builder.RegisterModule(new ReportingDataPointsModule());
// FAILS HERE
builder.RegisterModule(new ReportingStartupModule()
{
RestrictAccessValue = Claims.ClaimTypes.Reports
});
builder.RegisterModule(new ServiceModule());
builder.RegisterModule(new EfModule());
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// Register service handles
config.Services.Add(typeof(IExceptionLogger), new GlobalExceptionLogger());
builder.RegisterWebApiFilterProvider(config);
MapperConfigurationExpression mapperConfig = new AutoMapperConfiguration().Configure();
Mapper.Initialize(mapperConfig);
Mapper.AssertConfigurationIsValid();
// Build container
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// The Autofac middleware must go before any Web Api middleware
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
WebApiConfig.Register(config, container);
// Non-Autofac OWIN pipeline
app.UseJsonWebTokens(container.Resolve<IRoleManager>());
app.UseRoleManager(container.Resolve<IRoleManager>());
app.UseWebApi(config);
// Ensures configuration is ready
config.EnsureInitialized();
}
}