-1

After making some changes to a legacy ASP.Net Web Forms app I'm working on, I started receiving the following exception whenever I tried to visit a page of the application.

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\MyApplication\bdb24adf\eb592999\App_Web_mypage.aspx.cdcab7d2.dc1wid-d.0.cs(148): error CS0012: The type 'MyDataModelClass' is defined in an assembly that is not referenced. You must add a reference to assembly 'MyDataModelAssembly, Version=40.0.0.30, Culture=neutral, PublicKeyToken=7ca3fb5049101832'

After hours of troubleshooting, I finally narrowed down the problem to a method I had added to a base page class from which all pages in the application derive. Call it MyBasePageClass.

protected T CreatePlaceholder<T>(T item) where T : MyDataModelClass, new()
{
    return new T { TemporaryIdentifier = item.TemporaryIdentifier };
}

When I comment out that method, the exception goes away and everything works as I would expect. If I add an assembly reference in the web.config file, this exception also goes away. Oddly, when I change the reference to Copy Local = true, this also makes the exception go away.

This is not the first time that MyDataModelClass has been incorporated into the application. It is used in scores of places in almost every code behind file. But for some reason, using it as a type constraint is more than .Net can handle.

I can only imagine that It has something to do with the nature of generics, but I have no idea what that might be. I cannot be the first to have tried this, but I can't find any information about it on SO or anywhere else. Could it have something to do with how IIS is configured?

Update:

MyDataModelAssembly is indeed installed in the GAC. Here is the output of gacutil /l:

The Global Assembly Cache contains the following assemblies: MyDataModelAssembly, Version=40.0.0.30, Culture=neutral, PublicKeyToken=7ca3fb5049101832, processorArchitecture=MSIL

Daniel Arant
  • 483
  • 1
  • 4
  • 16
  • 1
    Why the down vote? – Daniel Arant May 02 '16 at 20:30
  • I would love to know who keeps down voting this question. The whole purpose of up and down votes of questions is so that well-researched, difficult questions can rise to the top and poor quality questions can fall to the bottom. Considering that nobody seems to have a good answer for this question, it needs to rise to the top. – Daniel Arant May 03 '16 at 13:08

2 Answers2

2

Edit 2: This looks like the solution to your problem: Strange Error - CS0012: The type x is defined in an assembly that is not referenced

But no real explanation why.


Edit:

Since your assembly is in the GAC, it should be finding it and not require Copy Local.

Make sure the version in the GAC is the version it's looking for. You can use Gacutil to check what's in the GAC. On my machine, gacutil.exe is in 'C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools', but it might be somewhere else on your machine. Once you find it, run this from the command line:

gacutil /l MyDataModelAssembly

The version and public key token output by gacutil must match what you see in the error message.


Your assembly DLL that defines MyDataModelClass has to be copied to the location that IIS is running the application from.

The Copy Local setting tells Visual Studio to copy the DLL to the compile output path (which is likely where IIS is running the application from). You will need Copy Local set to true for any assembly that is not in the GAC.

Community
  • 1
  • 1
Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • This assembly is in the GAC. – Daniel Arant May 02 '16 at 19:51
  • And why does this only occur when the generic method is added? This isn't the only place in the class that refers to MyDataModelClass. – Daniel Arant May 02 '16 at 19:54
  • You won't get the error until the code that uses the reference actually runs. So it's possible that the other places where you use the class just hasn't run. – Gabriel Luci May 02 '16 at 20:01
  • None of the code has run yet. This exception is happening when IIS tries to compile any of the .aspx files. – Daniel Arant May 02 '16 at 20:03
  • I should have said it loads the assemblies as needed. How it defines "as needed", I'm not precisely sure. But it's safe to say that if you want to use that class anywhere in your project, then IIS needs access to the DLL, which means keeping Copy Local set to true. – Gabriel Luci May 02 '16 at 20:24
  • The class was already being used in the project all over the place, and there were no problems. The problem only began after I used the class as a generic type constraint. – Daniel Arant May 02 '16 at 20:26
  • So does this requirement that the assembly either exist in the bin folder or in the GAC only apply to types used in generic type constraints? If not, then I don't see how your answer is relevant. – Daniel Arant May 02 '16 at 20:56
  • No, it applies to any use of the class. But there may be something in this usage that requires a newer version of the assembly, which is not in the GAC. We can't see the rest of your code, so I'm making guesses. – Gabriel Luci May 02 '16 at 21:00
  • I appreciate your help. I don't think this has anything to do with the GAC or with locating the assembly in general. It is locating the assembly, which is how it knows where the type being referenced is defined. But for some reason, the JIT is unaware of this project reference when it tries to compile the .aspx markup. – Daniel Arant May 02 '16 at 21:17
  • I found a solution from another question. See the link in my answer. – Gabriel Luci May 02 '16 at 21:20
  • Yeah, I saw that question last week. But the solution is not applicable. "It looks like any time you reference a type in the page (not the code-behind), you need the assembly information defined in the web.config file or in a page directive." In this case, I am referencing the type in the code behind, not the page. – Daniel Arant May 02 '16 at 21:31
  • Did you try the solution anyway? – Gabriel Luci May 02 '16 at 21:32
  • Yes, in my question I mentioned that I was able to get rid of the error by adding a reference via the web.config, but no web.config entry should be required in this case. It's just a bandaid. – Daniel Arant May 02 '16 at 21:34
  • Why is it a bandaid? That looks like a solution to me! – Gabriel Luci May 02 '16 at 21:37
  • It's a bandaid because it doesn't address the underlying problem that .Net is failing to compile a .aspx page based on a faulty error message. – Daniel Arant May 03 '16 at 04:21
-1

The type 'MyDataModelClass' is defined in an assembly that is not referenced. You must add a reference to assembly 'MyAssembly, Version=40.0.0.30, Culture=neutral,

Do you actually have a Reference in your project to whatever assembly (DLL) that that class is defined in? The error thinks you don't.

Fix it by adding the DLL here and setting it to Copy Local:

enter image description here

Jeremy Barnes
  • 657
  • 4
  • 15
  • Yes, there is a reference in the project. The application builds just fine in Visual Studio. It's when IIS gets a hold of it while serving up the page that the compile error occurs. – Daniel Arant May 02 '16 at 19:53
  • Make sure you have it set to copy to the IIS directory as well ("Copy Local"). DLLs have to be in the same relative structure to one another - the code isn't smart enough to find a missing DLL that is out of place. – Jeremy Barnes May 02 '16 at 20:03
  • It does it just fine when that generic method isn't included. The assembly is installed in the GAC. – Daniel Arant May 02 '16 at 20:04
  • 1
    If your custom assembly is in the GAC, then that completely changes your question. – Gabriel Luci May 02 '16 at 20:29
  • How so? The exception message has nothing to do with *locating* the assembly. It is complaining that the assembly is not referenced, even though it clearly is. (otherwise the solution would not build.) – Daniel Arant May 02 '16 at 20:34