ASP.Net error: “The type ‘foo’ exists in both ”temp1.dll“ and ”temp2.dll" (pt 2)
Asked Answered
R

12

14

Solution:

I had also moved ashx and asmx files at the same time as this. The Class attribute of the WebService/WebHandler directives were pointed at the wrong namespace. The moral of the story is to make sure you view the markup for all as*x files you change the namespace for by right-clicking on them and choosing "View Markup".


I'm experiencing the same problem as in this question and this link, but none of the answers fixed my problem. (edit: Setting the web.config batch attribute works, but that's a coverup, not a solution)

The problem I'm having is with a User Control that I moved from the root directory to a subdirectory within the same Web Application project. It used to work fine before I moved it. When I moved it it started giving me the error message.

It's saying that the class name exists in two dll files in Temporary ASP.NET Files. Sure enough, when I open Reflector, it's in two dlls.

If I rename the class and ascx file, everything works fine. No usages of the original name exist within any of the files in my entire application. When I rename the file, I opened all of the dll files in Temporary ASP.NET Files with Reflector, and no references to the original class name exists.

So where's this phantom reference coming from how can I fix this?

Update: I literally grepped every file in my working directory for the solution and my temp directory for the old class name and deleted every file that contained it. I then renamed back to the original, broken name and I still get the error.

Server Error in '/' Application. Compilation Error Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error ssage: CS0433: The type 'ASP.dashboard_badusercontrol_ascx' exists in both 'c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_badusercontrol.ascx.a57ad085.iljdmp1p.dll' and 'c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_bhdqaimy.dll'

Source Error:

Line 1098: Line 1099:
[System.Diagnostics.DebuggerNonUserCodeAttribute()] Line 1100: private global::ASP.dashboard_badusercontrol_ascx @__BuildControlMyBadUserControl() { Line 1101:
global::ASP.dashboard_badusercontrol_ascx @__ctrl; Line 1102:

Source File: c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_foo.aspx.a57ad085.1nw6dais.0.cs Line: 1100


Edit: Ok, so I did some more testing on what works and doesn't work. Let's say the original file name was "BadUserControl.ascx" in namespace "MyNamespace".

I moved the file to a directory called "NewDirectory" and changed the namespace to "MyNamespace.NewDirectory". There are no copies of "BadUserControl.ascx" anywhere else on my HDD. I double-checked my TFS history to ensure the ONLY difference is the addition of ".NewDirectory" to the namespace in the markup and code-behind files.

Inside of this namespace are two other user controls named "OtherUserControl" and "AnotherUserControl".

This situation fails: I have 2 Register directives:

<%@ Register src="BadUserControl.ascx" tagname="BadUserControl" tagprefix="uc1" %> 
<%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>

These situations work:

  1. I keep "BadUserControl.ascx" named as is. I have 1 Register directive on a page in the same namespace:

    <%@ Register src="BadUserControl.ascx" tagname="BadUserControl" tagprefix="uc1" %>
    
  2. I change "BadUserControl.ascx" to "GoodUserControl.ascx" I have 2 Register directives:

    <%@ Register src="GoodUserControl.ascx" tagname="GoodUserControl" tagprefix="uc1" %>
    <%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>
    
  3. 2 Register directives without BadUserControl.ascx at all:

    <%@ Register src="AnotherUserControl.ascx" tagname="AnotherUserControl" tagprefix="uc1" %>
    <%@ Register src="OtherUserControl.ascx" tagname="OtherUserControl" tagprefix="uc2" %>
    
Robot answered 7/4, 2010 at 21:36 Comment(3)
Any and all debugging suggestions are welcome in an attempt to earn the bounty.Robot
Could you please include the exact compilation error message that you're getting? It's hard to tell from your description whether the DLLs at stake are generated assemblies or GAC/bin assemblies.Nils
There's the error info for you.Robot
N
15

UPDATE: ok, as you found, the circular reference was the wrong guess, as there are other situation that may cause similar behavior.

The more general way to describe the problem is that batching at runtime works in a very permissive way which can mask problems. Basically, we try to batch everything in one folder, but if we get a compile error when compiling that batch, we fall back to individual file compilation. In many cases that works fine, but sometimes, this can lead to a given page getting compiled twice (similar to what I described below, but for a different reason).

On the other hand, aspnet_compiler works in a strict way, where if batching fails it fails altogether and does not fall back. That's why running this tool is a great way to locate various type of issues (or latent issues) that can be far from obvious at runtime. I guess we didn't do a good job evangelizing this tool for this purpose :)

As for why renaming the file fixed it, this may be caused by it changing the ordering in which files are processed, which is a bit arbitrary. It may be that if you rename it to something else, you'll see it happen again.

Frankly, looking back I kind of wish we had made this batching behavior strict at runtime, to catch those situations earlier. The reason we chose the current fall back design was to avoid failing whenever possible, but this came with a price: when something is wrong, it's a pain to catch it :)


ORIGINAL ANSWER: In short, the problem is that when batching is turned on (and it is by default), you should avoid having directory level circular dependencies. Let me explain what I mean by that.

Here is an example. Say you have:

  • In folder1: page.aspx and uc2.ascx
  • In forder2: uc1.ascx

And say that page.aspx references uc1.ascx (via a @register directive), and that uc1.ascx references uc2.ascx. At the file level, that’s perfectly fine, but at the directory level, there is a circular dependency: folder1 references something in folder2, which references something in folder1.

Why this is problematic has to do with how batching works: when you request the page, it first tries to compile everything in folder1 together. But since folder1/page.aspx references folder2/uc1.ascx, it needs to compile folder2 before it can do folder1. But then uc1 uses uc2, meaning it must first do folder1! At this point, ASP.NET detects the situation and tries to make the best of it by compiling uc2.asc by itself. While this allows some scenarios to work, it can also cause weird things because some items end up compiled in two assemblies. Here, uc2.ascx would be both compiled by itself and with the folder1 batch.

There is actually a way to easily detect if your site has such folder level circular dependencies. From a VS console window, go to the root of your site and run:

aspnet_compiler -v foo -p .

If you have folder level circular dependencies, you’ll get some errors that look like:

/foo/Sub/UC1.ascx(2): error ASPPARSE: Circular file references are not allowed.

The cheap way to avoid this issue is what you already know: disable batching. Now at least you know why that works :)

But the better thing to do if you can is to avoid the folder level circular dependencies. If you start thinking of each folders as a ‘component’ which produces an assembly, that actually makes sense, and can help make the pieces of your site more modular.

Yes, it’s also fair to call this a ‘bug’ in the compilation system, or at least a limitation. But once you’re aware of it, it’s fairly easy to avoid.

Nils answered 13/4, 2010 at 5:34 Comment(4)
This is a great, informative answer. While I DID NOT have a circular file reference, I got a "error ASPPARSE: Could not create type" error on two complete unrelated files: An asmx and an ashx. Since double-clicking these files opens the code-behind by default, I never thought to view the markup on these files when I did the move. Once I viewed the markup, it was obvious that the "Class" attribute was pointed to the wrong namespace. Fixing these two files caused my User Control to compile properly.Robot
David, I'm still confused as to why simply renaming the user control would cause this error to go away, even with the namespace problems in the other files. I deleted the Temporary ASP.NET Files and bin/obj directories. Could the old compiled state of the site have been stored somewhere else?Robot
I added an update. But to answer your question, the compiled state is not stored anywhere else. More likely, it's an effect of the arbitrary ordering in file processing I described above.Nils
Super answer! Thank you very very much. This as been the bane of my existence for the past few days.Robot
D
5

Clean Temporary ASP.NET Files. It could be that control before moving has an assembly and after - an another one

Domel answered 7/4, 2010 at 22:8 Comment(3)
Thank you for the idea. I deleted everything in that directory and the problem persists. :(Robot
Did you do a Clean from the Build menu?Concentrate
@SLC: Try menu is good idea. But first of all I mean deleting %Temp%\Temporary ASP.NET Files or something like %WINDIR%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET FilesDomel
D
3

This kind of error is due to the name space. Check the name space for all the files to make sure there is no duplicated one or name space usage error error.

Draftee answered 12/4, 2010 at 19:10 Comment(6)
This did occur directly after changing the namespace. I thought about this too, but if all I do is change the filename and classname and leave the namespace intact, the error goes away. I'll doublecheck though.Robot
The simplest way you can do is just remove the newly added namespace and do a search for the namespace in your project and make sure there is no duplicated one. And also check the declarative on your aspx or ascx file make sure they refer to the correct namespace.Draftee
It definitely worked when I obliterated the new namespace. I've discovered some additional information, so I'm editing the question.Robot
@Greg: if you put any path to the namespace in the code behind, you probably need to use exactly the same namespace (MyNamespace.newdirectory) in the register directivesDraftee
This is technically a correct answer. The problem was hidden in in the markup for unrelated asmx and ashx files I had also moved. Since double-clicking these types of files opens the code-behind be default, I never thought to check them.Robot
You, sir, are a gentleman and a scholar. Chased my tail for far too long trying to track this down.Rat
Y
2

I sometimes get this with my web usercontrols. They will complain they exist twice when I edit a different file. I don't know what craziness is causing it but I know that if I press space > save on the complaining control it forces the server to recompile and it works fine after that.

Yearlong answered 7/4, 2010 at 22:11 Comment(3)
Thank you for good idea!I deleted everything in the User Control. All of the markup and code behind. The only thing left was the usings, namespace, classname, and Control directive. It still failed. :(Robot
I wasn't suggesting to wipe out the contents of the user control, just to make any change to the control (such as press space, then delete it again) and then save it. This marks the control as "dirty" in the eyes of the compiler and forces it to recompile the control the next time you visit the page.Yearlong
Sorry for being confusing. I tried just modifying it and that didn't work, so then I wiped everything and it also didn't work.Robot
S
2

Is there more than one project in your solution?

Try cleaning the /bin folder (manually). It's possible that the old build file still persists somewhere, preventing you from building...

Also, take a look at your references - maybe you're duplicating the definition of something you referenced?

This is a wild shot - but maybe you've have that .dll installed in GAC?

Starknaked answered 12/4, 2010 at 12:30 Comment(1)
Yes, there is more than only project in my solution. I grepped the whole solution and I can't find a duplicate reference. Both the user control and the page that uses it are in the same directory. It's not in the GAC.Robot
W
2

I think some of these answers may have been off the mark. I have seen this when your code-behind references a different version of the assembly than your web.config does. e.g.:

(version 1.1.0.0 referenced in aspx and 1.2.0.0 referenced in web.config)

MyFile.aspx

<%@ Register TagPrefix="cc1" Namespace="StrongNamed.Namespace" Assembly="StrongNamed, Version=1.1.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" %>

web.config:

<assemblies>
    <add assembly="StrongNamed, Version=1.2.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"/>
...

I have seen cases where if both versions of the assembly are in the GAC, ASP.NET will give you the error that you describe.

Would answered 12/4, 2010 at 19:7 Comment(1)
Thanks for the new direction. I checked and I'm not using the Assembly attribute on the Register directive anywhere in my code. I'm also not registering the control in question via the web.config.Robot
G
2

I ran into this problem at least twice.
David Ebbo's answer is definitely the one that explains what's happening.

In my project I created a user control that I dynamically inserted into a placeholder.
So the code behind for the control would be something like:

public partial class CustomerAppointmentList : System.Web.UI.UserControl
{
}

Note that this control is not in any namespace whatsoever.

In code behind of 'customer.aspx.cs' I load this usercontrol dynamically:

{
    var contentControl = (CustomerAppointmentList)LoadControl("../controls/customerappointmentlist.ascx");
}

Because the class 'CustomerAppointmentList' does not exist in the aspx page I have to reference it in my custmer.aspx:

<%@ Reference Control="../controls/customerappointmentlist.ascx" %>

When the asp.net compiler has to compile customer.aspx it will come accross the 'CustomerAppointmentList' class and add the type to the library for that folder.
Seconds later the asp.net compiler will add the 'CustomerAppointmentList' class to another library for the folder 'controls'.

After adding an interface 'ICustomerAppointmentList' in an external library (projectname.web.dll) and amending the code, the problem went away. So:

  1. Delete the 'Reference' part in your aspx file.
  2. Create an interface for your user control.
  3. Make sure the 'CustomerAppointmentList' class inherits from the user control.
  4. When using LoadControl, cast to the interface you have just created.

My new code (ascx.cs):

    public partial class CustomerAppointmentList : System.Web.UI.UserControl, ICustomerAppointmentList
{
}

(aspx.cs)

{
var contentControl = (ICustomerAppointmentList)LoadControl("../controls/customerappointmentlist.ascx");  
}
Gyronny answered 5/7, 2011 at 13:55 Comment(0)
L
1
  • Close all visual studio instances running.
  • Stop IIS (if running, otherwise stop that "devserver" thing)
  • Clear ASP.NET Temp file folder (completely)
  • Clear BIN folder
  • Start IIS (if running)
  • Start VS
  • Rebuild solution
Lifelike answered 12/4, 2010 at 12:29 Comment(3)
Thanks for the suggestion. I followed these steps and the problem remains.Robot
Have you used the Clean Solution option? (somewhere between the IIS reset) ?Lifelike
Clean Solution still doesn't fix it.Robot
M
1

With a lot of projects and folders, it's possible to sometimes get the namespaces messed up, especially if you're trying to force things by using namespace declarations.

To see if this really is a problem, I'd go through all my code files - .cs and .designer.cs - and remove ALL the namespace declarations, then rebuild all to see if that fixes the problem.

You don't mention what version of Visual Studio and .net you're using, that might help too - I remember dealing with a similar problem in VS2005.

Multipartite answered 12/4, 2010 at 19:7 Comment(3)
Visual Studio 2008 SP1 targeting .NET 3.5 with the WebDev server.Robot
This is technically a correct answer. The problem was hidden in in the markup for unrelated asmx and ashx files I had also moved. Since double-clicking these types of files opens the code-behind be default, I never thought to check them.Robot
The generated, designer.cs files can sometimes get out of sync, and I never did find a good way to force them to regenerate correctly.Multipartite
E
1

Try to remove all the files and folders within the folder "Temporary ASP.Net Files",it's in this path:

c:\windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

this worked for me

Epigoni answered 15/7, 2012 at 15:28 Comment(0)
S
0

For me this happened when I had my PrecompiledWeb/Publish location set to the current directory which was where the site's root folder was too.

My Web Site was then seeing the publish folder as part of the project when compiling/building and then finding duplicates in that manner.

i.e. Don't put the published version of your site in your site's code folders.

Succession answered 17/9, 2013 at 3:38 Comment(0)
B
0
  1. First of all you should use the vs 2013 for for this problem.
  2. Secondly this error because file that extension is .dll and show on browser like that

Compiler Error ssage: CS0433: The type 'ASP.dashboard_badusercontrol_ascx' exists in both 'c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_badusercontrol.ascx.a57ad085.iljdmp1p.dll' and 'c:\Docunts and Settings\me\Local Settings\Temp\Temporary ASP.NET Files\root\3c2b7e1f\2e8a7620\App_Web_bhdqaimy.dll'

So you should remove that file which show with this error.(App_Web_bhdqaimy.dll)

Binominal answered 3/10, 2019 at 11:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.