Skip to content

Instantly share code, notes, and snippets.

@miguelhughes
Last active July 17, 2018 14:52
Show Gist options
  • Save miguelhughes/5230ffe7e749c90ec354d92c0b214ee1 to your computer and use it in GitHub Desktop.
Save miguelhughes/5230ffe7e749c90ec354d92c0b214ee1 to your computer and use it in GitHub Desktop.
excerpt of current code to show current setup
Connection id ""0HLF8QG33H9M1"": An unhandled exception was thrown by the application. (8c14976b)
AutoMapper.AutoMapperMappingException: Error mapping types.
Mapping types:
Billing -> BillingModel
Models.Billing -> Models.BillingModel
Type Map configuration:
Billing -> BillingModel
Models.Billing -> Models.BillingModel
Property:
LineItems ---> System.NullReferenceException: Object reference not set to an instance of an object.
at AutoMapper.Configuration.MappingExpression`2.<>c__60`1.<AfterMap>g__AfterFunction|60_0(TSource src, TDestination dest, ResolutionContext ctxt) in C:\projects\automapper\src\AutoMapper\Configuration\MappingExpression.cs:line 450
at lambda_method(Closure , Billing , BillingModel , ResolutionContext )
--- End of inner exception stack trace ---
at lambda_method(Closure , Billing , BillingModel , ResolutionContext )
at lambda_method(Closure , Object , Object , ResolutionContext )
at AutoMapper.Mapper.AutoMapper.IMapper.Map[TDestination](Object source) in C:\projects\automapper\src\AutoMapper\Mapper.cs:line 207
at Controllers.BillingController.Get(Int32 timezone, Int32 billingId) in Y:\someproject\web\Controllers\BillingController.cs:line 392
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextExceptionFilterAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ExceptionContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityModel.AspNetCore.ScopeValidation.ScopeValidationMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.<Invoke>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.<RequestProcessingAsync>d__2.MoveNext()
//automapper configuration helper class
namespace Maps
{
public class MapperConfiguration
{
public static void ConfigureAutoMapperNew(IServiceCollection services)
{
Assembly mapsAssembly = typeof(MapperConfiguration).GetTypeInfo().Assembly;
services.AddAutoMapper(mapsAssembly);
}
public IMapper ConfigureAutoMapper(System.IServiceProvider provider)
{
var config = new AutoMapper.MapperConfiguration(cfg =>
{
AddMappingProfiles(cfg);
cfg.ConstructServicesUsing(type => ActivatorUtilities.GetServiceOrCreateInstance(provider, type)); //set up DI so any services declared here can be injected into the mapper
});
var mapper = config.CreateMapper();
//have automapper test the validation, to early detect any mapping issues. this should remove the need for a lot of testing, although makes the mapping a little more tedious http://automapper.readthedocs.io/en/latest/Configuration-validation.html
config.AssertConfigurationIsValid();
return mapper;
}
private void AddMappingProfiles(IMapperConfigurationExpression cfg)
{
//locate the default mapping profile and add any other profiles in the same project (TracDispatch.Maps)
Assembly[] assemblies = { typeof(DatesMappingProfile).GetTypeInfo().Assembly };
AddMapperProfiles(cfg, assemblies);
}
private void AddMapperProfiles(IMapperConfigurationExpression cfg, IEnumerable<Assembly> assembliesToScan)
{
assembliesToScan = assembliesToScan as Assembly[] ?? assembliesToScan.ToArray();
var allTypes = assembliesToScan.SelectMany(a => a.ExportedTypes).ToArray();
var profiles = allTypes
.Where(t => typeof(Profile).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()))
.Where(t => !t.GetTypeInfo().IsAbstract);
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
}
}
}
namespace Web
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
//Automapper config - old way
//services.AddSingleton(provider => new Maps.MapperConfiguration().ConfigureAutoMapper(provider));
// code removed for brevity
// [...]
services.AddMvc(config =>
{
//make all controllers require authenticated users by default. Can be overridden by AllowAnonymousAttribute
var policy = new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter(policy));
config.Filters.Add(new HttpExceptionFilter());
config.Filters.Add(new PropertyMappingErrorFilter());
config.Filters.Add(new ValidationActionFilter());
config.Filters.Add(new TimezoneParameterActionFilter());
}
).AddJsonOptions(options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.DateFormatString = "M/d/yyyy h:mm:ss tt"; // set format to short datetime format. Affects both serializing and deserializing DateTimes. For automapper to use this format in the responses, the model must have date time properties, not string properties. The easiest way to get this to work is by using RequestTimeZoneTimeConverter and RequestTimeZoneExtensions.
options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //revert serialization options to use Pascal case for properties (not sure what it does for the rest of the serialization, but according to the following comment, it should revert to the "old way" (https://github.com/aspnet/Mvc/issues/4842#issuecomment-256094634)
});
//Automapper config - new way. enables ProjectTo extension, but breaks AfterMap mapping actions
MapperConfiguration.ConfigureAutoMapperNew(services);
//more code removed for brevity
//[...]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment