I’ve discovered something that might be a bug in some way.

In one of our web applications, one of the developers wrote a user control (ASCX). The ASCX file contained a DIV with the “runat=server” attribute named (just of the sake of the sample) “X”. The ASCX.cs file contained another property called “x” (mind the case change!).

Since the compiler is case sensitive, there was no problem with this and the whole thing compiled and run, specifically it run from Visual Studio while debugging, the problem started when we precompiled the application.

In our build process, we precompile the web applications using the ASP.NET Compiler (through MSBuild, of course ;-) ) and since there was no compilation problem, everything went fine and the build succeeded.

We put the new build in a dev machine and started working with it. When we reached a page that used that control we got the “Ambiguous match found” exception. After searching for it in the newsgroups I found that it is a reflection related problem, so I fired up my faithful WinDbg and dived in.

I attached to the ASP.NET worker process and it broke in when the exception was thrown. I looked at the call stack (using !clrstack) and saw a call to “System.RuntimeType.GetField”, a reflection function used to get a field of an object.

OS Thread Id: 0xf38 (14)
ESP EIP
019eecb0 77e55dea [HelperMethodFrame: 019eecb0]
019eed54 79617ef1 System.RuntimeType.GetField(System.String, System.Reflection.BindingFlags
.
.
.

I run “dds 019eed54″ (this address is the address of the stack frame) to see what’s on the stack and get the addresses/values of the two parameters in the function.

019eed54 0263588c
019eed58 00000001

The first two lines (shown above) contains the addresses/values (depending on the type and number of parameters passed to the function, in our case we have only two) of the function. The second column contains the addresses/values. In our case, since the first parameter is a string, the value 0263588c is actually the address of a string, so I used !dumpobject to see its value and saw that it was “x”.

The second parameter is an enumeration, so the value represents the integer value of that enum flag. I looked in Reflector and saw that the value 1 belongs to BindingFlags.IgnoreCase.

At that point I still didn’t figure out the problem, so I went back to reflector and took a look at the precompiled assembly that this code was compiled into and then saw that I had two protected fields, one named “X” and one named “x”.

Bingo! that’s the problem, staring me back from the screen.

To sum things up, while this code is correct compiler-wise (two parameters with the same characters but different casing are two different parameters), the implementation that tries to access some of it uses a case insensitive reflection search, which causes the bug.

Until I get more information from Microsoft, I suggest making sure in any ASP.NET application that is precompiled to avoid having the same names with different casing to variables in the ASPX/ASCX page and its code behind.

Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • co.mments
  • del.icio.us
  • digg
  • Ma.gnolia
  • NewsVine
  • Reddit
  • TailRank
  • YahooMyWeb

36 Responses to ““Ambiguous match found” in a Web Control - a Possible Bug”

  1. Benni B says:

    I searched so long, just to find the right answer here….
    Not as always mentions some defined types in designer.cs-FIle (mine was emopy) and the code-behind file…
    My Example (”HyperLinkAccount” and “HyperlinkAccount”)

    Thanks a lot, Eran. Great job!

  2. Eran Sandler says:

    Hey Benni B,

    I’m always glad to hear that someone benefited from the troubles I had. In this case I even found the exact cause which is even better ;-)

    I happy to hear this actually helped you solve your problem.

    Eran

  3. Anonymous says:

    Thank you for the help. I’d also like to point out that if one of your controls in your .ascx is named the same as a variable in your .ascx.vb (as was my problem) it will fail the same way.

  4. Eran Sandler says:

    Thanks for the input.

  5. Anonymous says:

    HI..

    I have downloaded Win.. debugger and trying to attached asp_net_wp.exe process but am not able to figure out which field is duplicate. Would be glad if u could guide as how to use the tools that u used to figure out.

  6. Eran Sandler says:

    Well.. basically, there is a bit of a faster way of finding this than what I’ve described.

    First, you need to attach WinDbg to the ASP.NET worker process.

    Continue to run your application and when this error occurs, WinDbg should break-in due to the exception.

    When that happens, run !clrstack -p.
    This should show you the managed call stack and the addresses of all the passed parameters to each function.

    Since the exception usually happens in the System.RuntimeType.GetField function, you should take the address of the first parameter (which is the name of the field we are looking for) and run !do 0xXXXXXX where 0xXXXXXX is the address of the string that should contain the name of the field that is probably duplicated.

    If you need further help with WinDbg to set symbols and load the SOS extension, look at previous posts here.

  7. Anonymous says:

    thank you, thank you, thanks a lot!!!!

  8. Eran Sandler says:

    You are welcome!

  9. Rich Armstrong says:

    Thanks! Saved us lots of time. One more thing of note: it doesn’t seem to matter that the two similarly named fields both be protected. I changed one of mine to private — it no longer needed the protected scope anyway — but that didn’t help. Only by giving them different names did the page work.

  10. Kipp says:

    I tried your suggestion on using WinDbg to help find out exactly which variable is a duplicate but after attaching to the w3wp.exe process and then getting the “Ambiguous match found” exception to happen, windbg doesn’t break. Could there be something I’m doing wrong with WinDbg?

    Thanks

  11. David says:

    I couldn’t figure out the windbg, but the comment about using reflector helped a lot! It was easy to see the offending variables. Just download the .NET Reflector from the web. It’s pretty easy to figure out.

  12. Kipp says:

    Thanks for the reminder of using .NET Reflector as that was able to help me see the offending variable easier than just going through the .aspx and .aspx.cs file looking for duplicates. With Reflector the two variable were right next to each other and it was obvious where the problem was.

  13. Anonymous says:

    Thanks a lot, it saved me hours!!!

  14. Eran Sandler says:

    You are welcome. It’s always fun to see that I could actually save time :-)

  15. Paul Robinson says:

    Fabulous - I followed your post and fixed by problem. A bit more useful than the usual group replies of ‘have you applied the latest fixes’ or ‘look for more information at microsoft.com’. Well done!

  16. Eran Sandler says:

    Paul,

    I’m glad it helped you. This is the kind of bug that can cost you lots of time and hours figuring out just because the error is so… well… ambiguous :-)

  17. Anonymous says:

    Thanks guys - my first .net 2005 web application, and the first line of code !
    Been writting 2003 apps for 2 years no problems.

    Downloaded Reflector - pointed it at my app, and hey presto - Job Done.

    Thanks as per the other comments for not sending me off on a wild goose chase.

    Great Blog.

  18. Eran Sandler says:

    I’m glad to hear that my blog really helps people.

    After all, that’s the reason I’ve started it in the first place :-)

  19. Anonymous says:

    Another vote of thanks from me. Your blog, and the hint to use reflector, saved me much frustration.
    Thanks for taking time to post this.

    Simon

  20. Matthew says:

    You are awesome. Saved me a ton of time!

  21. Eran Sandler says:

    You are welcome, Matthew :-)

  22. Mohit says:

    Thanks alot.
    It really worked and helped me in fixing this setup issue.
    Really technical finding.
    Great job!!!!

  23. Eran Sandler says:

    Mohit, you are welcome! :-)

  24. Peter says:

    Thanks Eran, your post helped a lot. I even wrote a short blog post about it and referred to you so that even more people may find this.

  25. Eran Sandler says:

    Peter, you are more than welcome and thanks for linking back here!

  26. Enabling WinDbg to break on CLR Exceptions » Advanced .NET Debugging says:

    [...] A reader named Kipp left some comments on my “Ambiguous match found” post. He had some problems making WinDbg break on CLR exceptions (like the ones generated by the compiler during the ASP.NET compilation of the page that eventually causes the “Ambiguous match found” error). [...]

  27. ASP.NET Compiler assumptions and a possible bug » Advanced .NET Debugging says:

    [...] On my previous post about the dubious “Ambiguous match found” exception, I talked about the fact that the ASP.NET runtime is case sensitive and if you are writing in C# you better be careful about how you name your private, protected and public variables. [...]

  28. Managed Call Stack with Parameters » Advanced .NET Debugging says:

    [...] I know I haven’t been posting much lately, but I’m a bit caught up in a startup I’m involved in called Yedda. It has taken most of my time, but I do find, once in a while, something to post like the “Ambiguous match found” problem, so bear with me [...]

  29. Goran says:

    I had the same nasty error after moving a project from .NET 1.1 to .NET 2.0 I found your blog, and tried to catch the error with the WinDbg, but maybe because I am bot so used to it, I couldn’t.
    But, I found the problem with the VS.NET 2005 debbuger, so if someone else is having dificulties with WinDbg it could try this:
    Before starting your WebApp choose menu Debug->Exceptions and in the window check Common Language runtime exceptions. Open the aspx page that has this exception and start debugging from there (I used the internal ASP.NET WebDevelopment server). After breaking several times for some other exceptions I finally got the fameous “Ambiguous match found” . And it was the very same method (System.RuntimeType.GetField) that has the problem. And just before that one in the call stack was a call to System.Web.UI.Util.GetNonPrivateFieldType that showed me the field that has the problem. It was the same control defined twice in the same file (few lines distance from eachother), but with a different case in one letter.

  30. Eran says:

    Goran, thanks for sharing this information!

    When I get some more time I’ll write a post with these details just so everyone will see it and benefit from it.

    Thanks again!

  31. Sasha Sydoruk » Blog Archive » “Ambiguous match found” in a Web Control - a Possible Bug says:

    [...] More info can be found at Eran Sandler’s blog - “Ambiguous match found” in a Web Control - a Possible Bug. [...]

  32. Tolga Guler says:

    thanks for sharing.

  33. Eran says:

    You are welcome.

  34. vlad says:

    This post is 2 years old, but still very useful.
    Thanks Eran, you saved me a lot of time, I solved the problem in a couple of minutes (tbFillerId tbFillerID).
    Strange thing is that it worked until yesterday and today it crashed without someone changing anything.

    Good job and thanks for sharing!

  35. Eran Sandler says:

    Vlad, you are welcome :-)

  36. Manohar says:

    The easiest way to find the case mismatches is to convert to web applicaton on that particular page, so VS.NET designer will give you the lead! :)

    Thanks!
    Manohar

Leave a Reply

Login Method

OpenID

Anonymous