Auto Mapper fails to load in an MVC project.

1,762 views
Skip to first unread message

Peter Shaw

unread,
Jul 7, 2014, 1:01:50 PM7/7/14
to automapp...@googlegroups.com
Hi Jimmy & Co,

this one's driving me nuts, so if anyone has any insight and be very thankful, I've never encountered this issue before, and doing a bit of Googling only turns up one SO post on it from quite some time back:


The referenced SO post is the exact issue I'm seeing, except for the following:

The App is MVC 5
The Automapper version is : 3.2.1
The Project is configured for .NET 4.5 (Any CPU)
IIS app-pool Is configured for .NET 4 full framework with integrated pipeline.

Iv'e used Automapper in dozens of Projects over the years and never had an issue like this.

I don't think it's a mapping failure, because I see the failure on the first attempt to call into my business rules layer where the mapping is done.

 Project is set up as follows:

WebUI (MVC App)
Business Rules (Standard Class Library)
ViewModels (Standard Class Library)
Data (Standard Class Library)

Within 'Data' there is a sub namespace called 'Entities', this name space holds the database versions of my pocos, and is controlled using EF code first

In the 'ViewModels' assembly can be found the application level Pocos, all of which are Suffixed with 'Vm' so 

(App)TicketVm --->  (DataBase)Ticket

At the moment during development there is an Exact 1 to 1 field mapping between objects.

WebUI controllers call ---->   Business Rules wich in turn calls into ---->  Data which uses EF to talk to SQL Server.

Automapper is added to the business rules project as this is where all the mapping is performed.

The webui knows nothing of the 'Ticket' poco and the data layer knows nothing about the 'TicketVm' poco.

Before I even get anywhere near the code in 'Business Rules' I get the following exception thrown at me as the assembly attempts to start-up:


The code inside the business rules dll looks like the following:

using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using *********.*******.Data;
using *********.*******.Data.Entites;
using *********.*******.web.ViewModels;

namespace *********.*******.Business
{
  public class TaskTickets
  {
    public static void SetUpMaps()
    {
      Mapper.CreateMap<TaskTicketItemVm, TaskTicketItem>();
      Mapper.CreateMap<TaskTicketVm, TaskTicket>();
    }

    public static void AddNew(TaskTicketVm ticketToAdd)
    {
      SetUpMaps();

      using (var db = new EncDataContext())
      {
        var newTicket = Mapper.Map<TaskTicket>(ticketToAdd);
        db.Tickets.Add(newTicket);
        db.SaveChanges();
      }
    }

    public static List<TaskTicketVm> GetAllTickets()
    {
      List<TaskTicketVm> results = new List<TaskTicketVm>();

      results.AddRange(GetAllTicketsWithStatus(StatusType.beingWorkedOn));
      results.AddRange(GetAllTicketsWithStatus(StatusType.closed));
      results.AddRange(GetAllTicketsWithStatus(StatusType.newTicket));
      results.AddRange(GetAllTicketsWithStatus(StatusType.open));
      results.AddRange(GetAllTicketsWithStatus(StatusType.resolved));
      results.AddRange(GetAllTicketsWithStatus(StatusType.testing));
      results.AddRange(GetAllTicketsWithStatus(StatusType.unknown));

      return results;
    }

    public static List<TaskTicketVm> GetAllTicketsWithStatus(StatusType statusType)
    {
      SetUpMaps();

      List<TaskTicketVm> results = new List<TaskTicketVm>();

      using (var db = new EncDataContext())
      {
        var records = db.Tickets.Where(x => x.TicketStatus == statusType);
        if(records.Any())
        {
          results = Mapper.Map<List<TaskTicketVm>>(records);
        }
      }

      return results;
    }

    public static List<TaskTicketVm> GetAllNewTickets()
    {
      return GetAllTicketsWithStatus(StatusType.newTicket);
    }

    public static List<TaskTicketVm> GetAllResolvedTickets()
    {
      return GetAllTicketsWithStatus(StatusType.resolved);
    }

    public static List<TaskTicketVm> GetAllTicketsBeingWorkedOn()
    {
      return GetAllTicketsWithStatus(StatusType.beingWorkedOn);
    }

    public static List<TaskTicketVm> GetAllTicketsBeingInTesting()
    {
      return GetAllTicketsWithStatus(StatusType.testing);
    }

    public static List<TaskTicketVm> GetAllOpenTickets()
    {
      List<TaskTicketVm> results = new List<TaskTicketVm>();

      results.AddRange(GetAllTicketsWithStatus(StatusType.beingWorkedOn));
      results.AddRange(GetAllTicketsWithStatus(StatusType.open));
      results.AddRange(GetAllTicketsWithStatus(StatusType.resolved));
      results.AddRange(GetAllTicketsWithStatus(StatusType.testing));

      return results;
    }

  }
}

However since this is failing in the controller:

    public ActionResult TestGetTickets()
    {
      var tickets = TaskTickets.GetAllTickets();

      return View(tickets);
    }

Before I even get into the method (Iv'e verified this in the debugger, the exception gets thrown the second I press F11 to step into 'GetAllTickets'

Going off the notes in the attached stack-overflow post, the first time I saw it (When writing the save new ticket method) I went into my Local IIS instance and fiddled with the app pool (More specifically, I opened the advanced settings in IIS, and saved the settings even though I'd not changed them) and that made it work.

However, I then added the retrieval code, cleaned and re-build my app and it failed again, I went in changed around the AppPool settings, different versions etc, but I've not been able to make it work again the second time.

Anyone got any thoughts?

For ref, the build machine is , Windows 7, X64, .NET 4.5 installed, running Visual Studio 2013 Ultimate.  IIS 7.5 is installed locally and the project is being developed in a local hard drive folder (So not a UNC path or anything funny like that, which might cause security burps)

Cheers
Shawty

Jimmy Bogard

unread,
Jul 7, 2014, 1:32:18 PM7/7/14
to automapper-users
Wow, this looks fun. Have you checked what Fusion Log Viewer says? Sometimes it has more details.


--
You received this message because you are subscribed to the Google Groups "AutoMapper-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to automapper-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Asher Newcomer

unread,
Jul 7, 2014, 2:32:23 PM7/7/14
to automapp...@googlegroups.com

Simple suggestion, but have you checked your platform target for all relevant projects? It sounds like it’s failing to load the assembly at all, which might indicate a 32bit/64bit/any mismatch between assemblies.

--

Message has been deleted

Peter Shaw

unread,
Jul 7, 2014, 5:17:42 PM7/7/14
to automapp...@googlegroups.com
@Jimmy no not yet, I'll do that now... good call btw, I forgot all about the fusion log...

@Asher, yup.. that was my initial suspicion, so I verified that every part of my solution where all targeting .NET 4.5 Any CPU.


Peter Shaw

unread,
Jul 7, 2014, 6:28:46 PM7/7/14
to automapp...@googlegroups.com
Hi all, 

So as per your suggestion Jimmy,  I took a look in the fusion log (I forgot just how usefull that darn thing was) and here is what I see:

*** Assembly Binder Log Entry  (07/07/2014 @ 22:46:38) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  c:\windows\system32\inetsrv\w3wp.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = AutoMapper, Version=3.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005
 (Fully-specified)
LOG: Appbase = file:///G:/***/********/***************site/webui/
LOG: Initial PrivatePath = G:\***\********\***************site\webui\bin
LOG: Dynamic Base = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\***********\3e21f29b
LOG: Cache Base = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\***********\3e21f29b
LOG: AppName = b1739544
Calling assembly : *********.*******.Business, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: G:\***\*********\***************site\webui\web.config
LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: AutoMapper, Version=3.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/enablecomds/3e21f29b/b1739544/AutoMapper.DLL.
LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/enablecomds/3e21f29b/b1739544/AutoMapper/AutoMapper.DLL.
LOG: Attempting download of new URL file:///G:/***/********/***************site/webui/bin/AutoMapper.DLL.
LOG: Attempting download of new URL file:///G:/***/********/***************site/webui/bin/AutoMapper/AutoMapper.DLL.
LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/enablecomds/3e21f29b/b1739544/AutoMapper.EXE.
LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/enablecomds/3e21f29b/b1739544/AutoMapper/AutoMapper.EXE.
LOG: Attempting download of new URL file:///G:/***/********/***************site/webui/bin/AutoMapper.EXE.
LOG: Attempting download of new URL file:///G:/***/********/***************site/webui/bin/AutoMapper/AutoMapper.EXE.
LOG: All probing URLs attempted and failed.

This message is repeated twice (And sorry about the stars, but it's a needed precaution as my clients name is shown in the paths and assembly names), and followed finally by:

*** Assembly Binder Log Entry  (07/07/2014 @ 22:46:38) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  c:\windows\system32\inetsrv\w3wp.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = AutoMapper, Version=3.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005
 (Fully-specified)
LOG: Appbase = file:///G:/***/********/***************site/webui/
LOG: Initial PrivatePath = G:\***\********\***************site\webui\bin
LOG: Dynamic Base = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\***********\3e21f29b
LOG: Cache Base = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\***********\3e21f29b
LOG: AppName = b1739544
Calling assembly : *********.*******.Business, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: G:\***\*********\***************site\webui\web.config
LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: AutoMapper, Version=3.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

Now, here's the thing.  Earlier today, I'd checked my build output (Given that the last message just above, was actually part of the output in the page), and seeing the following:

I didn't think anything of it.  I saw the "Automapper.Net4.Dll" and thought, oh ok, every things there.

However, the fusion log tells me that it was also looking for "Automapper.dll" which as you can see from the screen dump, is not there.

Iv'e just checked in the package folder created by NuGet and "Automapper.dll" is in there, so Iv'e copied it by hand to the website's bin directory, hit refresh and it's worked (Well sort of anyway...  I now have a different exception, but that's in my code and I know what's causing it :-)     )

So basically, it looks like the NuGet package for the current version isn't putting the "Automapper.dll" file in the correct place, or something like that.

I installed this from the NuGet package manager like I usually do.

Status : Resolved....

Thanks for taking time to look though gents.

Jimmy : Shoot me an EMail (peter.shaw AT lidnug.org) if you'd like to come and do a 90 minute live on-line presentation on Automapper :-)   We'd love to have you.

Shawty

Henning Christiansen

unread,
Sep 4, 2014, 4:20:21 AM9/4/14
to automapp...@googlegroups.com
We're having the exact same issue, AutoMapper.Net4.dll is included, but AutoMapper.dll is not. Copying by hand is no resolution, this needs to just work.

Is there a *real* solution to this?

Jimmy Bogard

unread,
Sep 4, 2014, 6:42:41 AM9/4/14
to automapper-users
What does your project structure look like?


Reply all
Reply to author
Forward
0 new messages