June, 2007

  • Never doubt thy debugger

    Compiler Error Message: CS0433 in ASP.NET 2.0

    • 40 Comments

    A few days ago a friend of mine had the Compiler Error Message: CS0433 error in his precompiled site, and proposed me a deal: a dinner for my help smile_regular, and since also Support Engineers sometimes need to eat, I accepted smile_wink.

    The exact error message was the following: The type <typename> esists in both <path 1> and <path 2>. Sometimes the error message is quite self explanatory, especially if one of the two assemblies is in BIN and the other is in the GAC (remove the one in the BIN, you don't need two copies of the same file!), but my friend was getting the following one:

    Exception information:
        Exception type: HttpCompileException
        Exception message: c:\WINNT\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\customers\30216428\89bd3cad\App_Web_default.aspx.27046288.rpug8fan.0.cs(112): error CS0433: The type 'App_Items_63_pgs_default' exists in both 'c:\WINNT\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\customers\30216428\89bd3cad\assembly\dl3\d1307a39\42cbc228_01a6c701\App_Web_tzn10d4k.DLL' and 'c:\WINNT\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\customers\30216428\89bd3cad\assembly\dl3\5493a6b9\8880bf21_01a6c701\App_Web_7jlq-fy_.DLL'

    Thread information:
        Thread ID: 1
        Thread account name: <server>\ASPNET
        Is impersonating: False
        Stack trace:    at System.Web.Compilation.AssemblyBuilder.Compile()
       at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()
       at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
       at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)
       at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)
       at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
       at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
       at System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
       at System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
       at System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig)
       at System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

    As you can see, the two involved assemblies comes both from the Temporary ASP.NET Files folder and have randomly created names, so we needed some little more troubleshooting... I asked for the source code of the application and after flipping through a little bit, I notice he had a default.master page which he was using as the master for his default.aspx; interestingly both pages were implementing a class with the same name: public partial class App_Items_63_pgs_default.

    That rang a bell... because what happens when you precompile the site is that you'll end up with two default.App_Item_63_pgs_default classes... I built a sample to confirm my theory:

       1: <%@ Master Language="C#" AutoEventWireup="true" CodeFile="default.master.cs" Inherits="_Default" %>
       2: <html xmlns="http://www.w3.org/1999/xhtml">
       3: <head runat="server">
       4:     <title>Untitled Page</title>
       5: </head>
       6: <body>
       7:     <form id="form1" runat="server">
       8:         <asp:Label ID="Label1" runat="server" Text="Master"></asp:Label>
       9:         <div>
      10:             <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
      11:             </asp:ContentPlaceHolder>
      12:         </div>
      13:         <asp:Label ID="Label2" runat="server" Text="Master"></asp:Label>
      14:     </form>
      15: </body>
      16: </html>
       1: <%@ Page Language="C#" MasterPageFile="~/default.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" 
       2:     Inherits="_Default" Title="Untitled Page" %>
       3:  
       4: <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
       5:     <asp:Label ID="Label3" runat="server" Text="Content"></asp:Label>
       6: </asp:Content>

    Publish the site and browse it, you should get the following error:

    Server Error in '/TestPrecompiled' 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 Message: CS0433: The type '_Default' exists in both 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\TestPrecompiled\b3047f60\f7364c3\assembly\dl3\6d1b8849\12db42f6_e9abc701\App_Web_yvefexa5.DLL' and 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\TestPrecompiled\b3047f60\f7364c3\assembly\dl3\a4f9584b\913c83f6_e9abc701\App_Web_qmnuz7n3.DLL'

    Source Error:
     
    Line 110:    
    Line 111:    [System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
    Line 112:    public class default_aspx : global::_Default, System.Web.SessionState.IRequiresSessionState, System.Web.IHttpHandler {
    Line 113:        
    Line 114:        private static bool @__initialized;

    Source File: c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\TestPrecompiled\b3047f60\f7364c3\App_Web_default.aspx.cdcab7d2.emhdmgwo.0.cs    Line: 112

    Bingo! We have a repro! smile_regular  So I asked my friend to rename one of the two App_Item_63_pgs_default classes (or wrap them in two different namespaces) and the application magically started working fine.

    I'm not completely clear why this happens only with the precompiled site while it works fine with the "normal" JITted site, but I'll try to find out.

    It worth mentioning that you could get this compiler error if you upgrade your project to the Web Application Project you have with Visual Studio 2005 SP1 (or as a separate add-in); in that case pay attention to the @Page directive and change the CodeFile attribute to CodeBehind (further details in this post).

    Again, when attempting to use the same CodeFile (.aspx.cs or .aspx.vb file) in Visual Studio 2005 for multiple ASPX or ASCX pages, compile errors resulted. Using a similar approach in Visual Studio .NET 2003 worked as desired. Visual Studio 2005 uses a “Partial Class” concept where declarations for “Controls” that are drag/dropped onto an ASPX page are put in a “.designer” file (which is typically stored in memory and not persisted to disk). The “designer” declarations are stored in the designer file and the actual C# or VB code is stored in the CodeFile. Because of the way that the ASPX/CodeFile/Designer go together, it isn’t straight forward to use multiple ASPX/Designer files with a single CodeFile since potentially unrelated controls from multiple ASPX pages will want to be declared in a single designer file. The recommended solution is to use the CodeFileBaseClass attribute of the ASPX page directive. When using this technique, each ASPX page has its own CodeFile/Designer files but then looks beyond these files for the base class that is specified.


    Carlo

    Quote of the Day:
    Your heart often knows things before your mind does.
    --Polly (Pearl) Adler
  • Never doubt thy debugger

    Avoid UAC prompt in IE component

    • 18 Comments

    Wow, this has been a tough one I closed this afternoon. The customer has developed a custom IE toolbar to interact with their portal, and found that when running this on Vista, IE displayed a warning dialog asking the user's consent to run an external program; in particular that was happening when the toolbar was calling a Web Service to retrieve some content from the web server. If for test we denied the permission to run the external problem, we got this error message: "System.Runtime.InteropServices.ExternalException: Cannot execute a program. The command being executed was "C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe" /noconfig /fullpaths @"C:\Users\Vista\AppData\Local\Temp\Low\ev4a0rzg.cmdline"." The exception occurred when the SOAP client proxy tries to spawn the compiler to generate the type serialization assemblies the first time the web service is called.

    After the usual log analysis we setup a repro in a virtual machine, and we found that this was not an UAC issue but rather an IE Protected Mode problem (by the way, Protected Mode in IE is currently available only on Vista, so maybe this is why the customer thought to this as an UAC issue); this was confirmed by turning off Protected Mode for a test, and the prompt to the user disappeared. IE was prompting the user because when the toolbar calls the remote Web Service, the CLR needs to generate and compile on the fly the needed serialization assembly, and here is where we were failing. To resolve this we used sgen.exe from the .NET framework SDK: this allows to pre-generate the serialization assemblies, so at runtime the CLR has no need to create them on the fly (and therefore IE does not prompt the user anymore).

    After that everything was running file on the virtual machine we used for your tests, but on the real customer's machine we again got an error, this time it was "Could not find a part of the path 'C:\Users\account\AppData\Local\Microsoft\Windows\Temporary Internet Files\Virtualized\C\Users\account\AppData\Local\Temp\Low\6br1dtzk.tmp'"; another dig into the logs, and then we found that the customer was missing a part of the path where IE stores it’s temporary files (%userprofile%\AppData\Local\Temp\Low); for some reason he was missing the “Low” folder and IE was prompting the user to ask permission to create it.

    Here are a couple of links to use as a reference:

     

    Carlo


    Quote of the Day:
    Perhaps the best thing about the future is that it comes one day at a time.
    --Dean Acheson
  • Never doubt thy debugger

    Security bug in Vista recovery console? Well... not quite...

    • 4 Comments

    My colleague Feliciano Intini (Chief Security Advisor here at Microsoft Italy) just pointed me to his post were he comments about a news which is (re)spreading across the web about a security hole in the recovery console in Windows Vista: if you can read Italian here is the post, otherwise go on an ready my translation.

    Third episode of my anti-FUD column. True story (unfortunately): a few days ago someone has stolen the motorbike of a colleague of mine whom was working at a customer's site.How was the bike protected? With that special padlock which locks the front wheel, without any sort of chain to fasten to a physical stand. How did they stole the bike? They arrived with a truck, a few guys got off it and they loaded the bike by sheer force in less than 5 minutes! What do I want to say?

    Here is a fundamental concept in security field: physical security is the basis for all security.

    False fact: I'm reading in various posts which quote an article by Finnish Kimmo Rousku, which Windows Vista apparently has a security hole which "allows to gain unlimited access to anyone who has physical access to the pc, even if he does not know the password to log.in".

    Security experts will be already smiling reading the sentence in quotation marks above and I don't think they need further explanations, but they'll forgive me if I'll now spend some more words for the benefit of everyone, aiming to improve the so called "informatics (IT) security culture".

    This is NOT a security bug, if you have physical access to the machine you already won the game as already stated in the 10 immutable Laws of security: if a bad guy has unrestricted physical access to your computer, it's not your computer anymore. The protection of your data on the hard disk must necessarily rely on information encryption: this is the reason why BitLocker and EFS have been added to Windows Vista. And I also remind that they robustness of the ciphering is due to the robustness of the algorithm used and not to the availability of the keys; this is why in Vista:

    1. EFS has been improved to allow keeping private keys on smart cards
    2. more strong ciphering algorithms have been implemented
    3. With BitLocker the most secure combination requires to use the TPM chip and a USB pen (not to store together with the pc!)

    To complete what just said you can read the article 818200, which further explains those considerations about data protection on hard disks.

    Just a legitimate doubt remains, which also I thought about: if on Windows XP there was a password to protect access to the recovery mode, why that has been removed from Vista, thus generating the (wrong) perception of decreased security or even a bug?? Here is why: Repair Mode/Recovery Console are used exactly when we have troubles starting our pc. Since it has been verified that the majority of the problems starting Windows XP were due to file system and registry corruptions, it made no sense to force authentication to allow access to the disk, since that authentication precisely requires to read the registry or the file system to verify that the password entered was correct.Since that password was not adding a security layer in respect of an average technical competency (seen the physical security consideration I discussed above, and the general availability on the Internet of tools to run offline security attacks), on the contrary it was making harder the recovery activities, it has been chosen to remove it.

    So, I understand that a password gives a certain sense of security, but if that is just a false perception and just hurts the recovery functionality, then I agree the design choice to remove it: so, I clinch, this is NOT a security bug and Microsoft does not have anything to fix here...

    Of course feel free to comment both here and on Feliciano's blog, if you wish smile_regular

     

    Carlo

  • Never doubt thy debugger

    ActiveX component can't create object... a tough one!

    • 3 Comments

    This week I've been working on a case from a customer who was migrating his web application to Windows 2003, and while on the old servers (Windows 2000) and on his development machine everything was working fine (as usual smile_regular), after deployment on the production server he got a nasty "ActiveX component can't create object" error  message, and was not able to fix it.

    The troubleshooting started from the usual and maybe most obvious possible causes (component registration, permissions etc...), but we soon realized the problem was not that obvious as we expected. The application was made by a custom ActiveX VB6 object which internally referenced other custom dlls and msrdo20.dll; this was then embedded into a .aspx page to show some use interface in IE to the end user. The customer sent me his application to try to reproduce the problem on my machine, and at the first run I got exactly the same error message he reported! Ah Ah! I got you! smile_regular On my machine I got rid of it registering all the involved components, something we already tried on the phone, but worth another check. I came back to the customer and set up an EasyAssist session to carefully check his server's configuration to spot  (and fix) the problem... but things went a bit differently. Everything was looking fine, so we decided to build a smaller sample to check if at least we were able to instantiate other ActiveX: we tried to work with msrdo20.dll directly, and that also failed with the same error.

    We then decided to capture a crash dump with adplus to have a full dump on the exception (we used the command "adplus -crash -iis -FullOnFirst" to obtains a full dump on first chance exceptions), and to make a long story short, after analyzing the dump (and digging into the VB6 runtime with the help of my colleague Carlo Colombo, Escalation Engineer in the COM+ team) we came to the conclusion that the runtime was trying to read the CLSID for msrdo20.dll in the wrong registry hive, HKEY_USER instead that HKEY_LOCAL_MACHINE as expected. By the way, that also could explain the reason why running the same code and loading the same msrdo20.dll in a WinForm application worked fine: the desktop app was able to find the CLSID for the component and to load it, while the web app does not have access to some registry hives... the customer already sent us a copy of its system registry to check the various CLSID involved, and a quick search confirmed our assumption: we found the CLSID 9A8831F0-A263-11D1-8DCF-00A0C90FFFC2 (msrdo20.dll) under HKEY_USER and not under HKEY_LOCAL_MACHINE. I forgot to mention that we were in a absolute hurry, because the application was supposed to to go live exactly that evening...

    Anyway, at that point we needed to confirm our theory: I called the customer to explain our findings and ask him to manually register (with regsvr32) msrdo20.dll, but a quick search in the registry showed that nothing was changed, we were in the same situation. Then I asked him to login as the Domain Administrator (which he was logger as the Local Administrator on the server) and check again: this did the trick! The CLSID was finally created under the right registry hive, and another quick test from a client confirmed the application was then able to instantiate the ActiveX... Eureka! smile_regular

    In trying to understand the reason for the HKEY_USERS registration, one theory might be the following: msrdo20.dll is installed through an MSI package. The MSI technology has the possibility to do a per-user or per-machine installation, or a "per machine, but fallback to per-user if per-machine fails" (ALLUSERS property set to 2): see http://msdn2.microsoft.com/en-us/library/Aa371865.aspx. If the user running the MSI package is not an admin, he won't have write permissions to HKCR\CLSID so per-machine registration will fail and we'll fail back to per-user installation. In per-user installation the registration is made in the HKEY_USERS registry hive: see http://msdn2.microsoft.com/en-us/library/aa370813.aspx.

    Thanks a lot to Carlo Colombo for his assistance on this one!

     

    Carlo

  • Never doubt thy debugger

    Spell checker missing in Windows Live Writer beta 2

    • 2 Comments

    A few days ago I installed the newly released beta 2 of Windows Live Writer, and immediately noted (with a bit of disappointment) that the spell checker was missing... smile_thinking After various tests (reinstalling on other machines I have, checking that all assembly versions were the right ones etc...) I decided to open a call through http://support.live.com (yes, this time I've been the customer and not the Support Engineer smile_regular).

    They've been very quick, and after a few emails I've been pointed to this post: the trick is use this custom launcher instead of running WindowsLiveWriter.exe directly, and I got my spell checker back and working like a charm smile_nerd.

    Following up this with the WLW support and we found that, even if I'm running only English operating systems (WinXP, Win2003 and Vista x64), all with Italian keyboard layout, and at least on the XP machine I also have the Italian .NET Framework package, the difference is made by my Regional and Language options which, as you may guess, I set to Italian; as a test I switched it to English US and the spell checker showed up in the Tools menu even without the custom launcher. It worth mentioning that the spell checker is currently only available for English language, but the Writer Product Team is working to add more language in the future. And of course the PD is aware of this problem, and hopefully they'll fix it in the next release.

     

    Carlo

  • Never doubt thy debugger

    How Fast Can You Type?

    • 0 Comments

    Here is some OT fun to start the day smile_regular

    Fingerjig is a fun little typing game that tests your accuracy and speed for randomly selected words (each level tests a different typing skill).

    From How Fast Can You Type? Direct link to the test: http://www.jonmiles.co.uk/fingerjig.php

     

    Carlo

  • Never doubt thy debugger

    Quick hint: "Server Unavailable" error

    • 0 Comments

    I stumbled into this error this afternoon, while working on a repro for a customer: if you need to have your application pool running under an account other than the default NETWORK SERVICE, and when you try to browse your application you get a nasty Service Unavailable error, check if you remembered to add that account to the IIS_WPG group... smile_thinking

     

    Carlo

  • Never doubt thy debugger

    How to: contact Carlo

    • 0 Comments

    Lately I've been receiving emails and comments to my posts asking for help on specific issues, to request hotfixes etc.... Unfortunately I can't guarantee the attention needed in those cases since I blog in my spare time (what's left smile_wink) and can't always be there monitor the blog; if you need assistance the best choice is go through official support channels such as http://support.microsoft.com, and you'll have in depth assistance from either me or one of my colleagues depending on the technologies involved and where you are based around the  globe.

    In any case, if you want to communicate with me directly and you open a Service Request you could specify to have the case to my attention (but this does not guarantee I'll be really the person that will work on it, because of the technologies and different skillset we have in the team!), or you can use the "email" module you find in my blog; this will send a mail to me directly and I'll hopefully be able to reply to you directly, without having to rely on post comments to communicate.

     

    Carlo

  • Never doubt thy debugger

    Debugger not debugging, and Response.Redirect() not redirecting...

    • 0 Comments

    The customer was working on a WinXP machine joined to a domain, but had logged in using a local account (I've not tested if this may have contributed to the problem so this may be a useless information). Anyway to make things easy I connected to the faulting machine using EasyAssist to have a better look at the configuration: everything looked fine both in IIS and Visual Studio. Interestingly browsing the application from IE directly we found that even if he was using "http://localhost/app" the page was shown in the "Internet" zone (hence the debugger error).

    This usually happens when the application is created using either the IP address or the FQDN (Fully Qualified Domain Name) of the web server; to verify, we created a new test project as "http://localhost/test" but got the same debugging problem, and again the page belongs to the Internet zone. As a test we enabled "Automatic logon with current username and password" for the Internet zone and then the debugging started working fine.

    internet security zone settings

    Talking about this with my team colleagues they suggested uncheck "Automatically detect intranet network" in the "Local Intranet" settings and enable the three remaining checkboxes; this because under some circumstances IE may fail to correctly detect the local network and assign it to the right zone (here is where I'm not sure if logging in with a local account may have an impact).

    local intranet settings

    Then, while testing the application we noticed that Response.Redirect() calls where not redirecting the page as expected (we just got a blank page, but this may vary a bit); the customer was using SmartNavigation, and this in conjunction with the redirect problem usually means a problem with the client side .js file which may be corrupted... run aspnet_regiis -c and you should get rid of it.

    Problem solved smile_regular

     

    Carlo


    Quote of the Day:
    Civilization begins with order, grows with liberty, and dies with chaos.
    --Will Durant
  • Never doubt thy debugger

    Your login attempt was not successful. Please try again

    • 0 Comments

    This time the customer was using the "Web Site Administrator Tool" wizard to create the authentication mechanism (based on SqlExpress membership) for his site. As usual everything was working fine on his development machine, but after deploying the application on the live web server users were no longer able to authenticate, and they got the message "You login attempt was not successful. Please try again.", and in the event log we found a few messages like the following:

    Event code: 4006
    Event message: Membership credential verification failed.
    Event time: 13/04/2006 13:23:30
    Event time (UTC): 13/04/2006 12:23:30
    Event ID: 89ff87b6e2d8490c9b873730e50af976
    Event sequence: 3
    Event occurrence: 1
    Event detail code: 0

    Application information:
        Application domain: /LM/W3SVC/1/Root/myapp-1-127894037524081250
        Trust level: Full
        Application Virtual Path: /myapp
        Application Path: d:\inetpub\wwwroot\myapp\
        Machine name: WEBSERVER

    Process information:
        Process ID: 5540
        Process name: w3wp.exe
        Account name: NT AUTHORITY\NETWORK SERVICE

    Request information:
        Request URL:
    http://<web server ip>/myapp/login.aspx?ReturnUrl=/myapp/search.aspx 
        Request path: /myapp/login.aspx
        User host address: <web server ip>
        User: 
        Is authenticated: False
        Authentication Type: 
        Thread account name: NT AUTHORITY\NETWORK SERVICE

    Name to authenticate: administrator

    The problem is that this error message is misleading; we found out that the problem was actually due to the Internet user missing permissions on the .mdf and .ldf files. SQLEXPRESS.EXE runs in the context of the ASP.NET user account and it of course need to access the .mdf file; the access type must the read/write because of course we must be able to update the database content.

     

    Carlo

Page 1 of 1 (10 items)