July, 2007

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 13

    • 7 Comments

    Hi Everyone,

    Welcome back!!!

    As mentioned earlier, today we will be wrapping up with the discussion about the ASP.Net 2.0 reserved folders. Let's take a look and understand the other ASP.Net special folders that we didn't consider yesterday.

    The App_Data Folder:

    The App_Data folder is expected to contain data stores local to the application. It typically contains data stores in the form of files such as Microsoft Access or Microsoft SQL Server Express databases, XML files, text files, and whatever else your application can support. The contents of the folder are not processed by ASP.NET. The folder is the default location where ASP.NET providers store their data.

    Note: The default ASP.NET account is granted full permissions on the folder. If you happen to change the ASP.NET account, make sure that the new account is granted read/write permissions on the folder.

    The App_GlobalResources Folder:

    Let's quickly understand what are resources? Just like other applications, an ASP.NET application can, and often should, use resources. Resources are an effective way to isolate localizable portions of the application's user interface. In general, a resource is non-executable text associated with the program. Typical resources are images, icons, text, and auxiliary files, but any serializable object can be considered a resource. Application resources are stored outside of the application so that they can be recompiled and replaced without affecting and recompiling the application itself.

    In ASP.NET 1.x, compiling resources inside an assembly (or satellite assemblies), although done by Visual Studio but was still a rather transparent task and more often developers need to be aware of several minute details to manage these resources. Basically, an ASP.NET application needs to have a primary assembly to contain the default or neutral resources for the application. In addition, we deploy a number of satellite assemblies, each containing localized resources for a particular culture we want to support. We have to manually compile XML-based resource files (those with a .resx extension) into a .resources binary file. These files can be either embedded in a .NET executable or compiled into satellite assemblies. We use the Resource File Generator (resgen.exe) utility to convert text and XML-based resource files into .resources files. The resource file names follow the naming convention baseName.cultureName.resources. Usually, the base name is the name of the application. A typical command line could be as follows:

    resgen.exe MyAppName.resx MyAppName.it.resources

    Once created, the .resources file should be embedded into an assembly, or it can even be used as is as a resource container. To embed the resource file into a satellite assembly, we use the Assembly Linker tool (al.exe). On the command line, we indicate the culture (it in our example, which represents Italian) and the name of the assembly.

    al /out:MyAppName.resources.dll /c:it /embed:MyAppName.it.resources

    After we compile our satellite assemblies, they will all have the same name. We deploy them in distinct subdirectories, each named after the culture. Fortunately, with ASP.NET 2.0, gone are the days of satellite assemblies. More precisely, satellite assemblies are still there, but they are a thing of the past for developers thanks to the App_GlobalResources reserved folder. Any .resx files located within the folder are automatically compiled to satellite assemblies. The name of the .resx file contains culture information to help the ASP.NET runtime environment with the assembly generation. The following files—resources.resx, resources.it.resx, resources.fr.resx—generate the neutral assembly and satellite assemblies for the Italian and French cultures respectively. The neutral assembly is the default culture resource used by the application if no specific culture is called for. Resource files located in the App_GlobalResources folder are global to the application and can be referenced from within any page. Resource reading results are greatly simplified as compared to ASP.NET 1.x:

    <asp:Label ID="Label1" Runat="server" Text="<%$ Resources:ResxFile, MyResName %>" />

    We can now bind global resources declaratively using the newest $-expression named Resources. (As already mentioned in one of the session, we'll cover $-expressions in more detail during one of the oncoming sessions) For now, the expression takes two parameters—the name of the .resx source file (no extension), and the name of the resource to retrieve. To access resources programmatically, you resort to the following code:

    HttpContext.GetGlobalResourceObject(resxFile, MyResName);

    Both parameters are strings and have the same role as the parameters in the $-expression. Moreover, the implementation of the $- expression Resources uses GetGlobalResourceObject internally.

    The App_LocalResources Folder:

    App_LocalResources is a subdirectory located below the folder that contains some ASP.NET pages. The folder can be filled with .resx files named after the pages located one level upper in the hierarchy. Assuming that the parent folder contains test.aspx, here are few feasible resource files you can find in the App_LocalResources folder: test.aspx.resx, test.aspx.it.resx, test.aspx.fr.resx. Obviously, resources stored in the aforementioned files have an effect only on test.aspx and are visible (and can be used) only from within the linked page.

    How do you access a page-specific resource? For programmatic access, you use the following code:

    HttpContext.GetLocalResourceObject("/ProAspNet20/ResPage.aspx", "PageResource1.Title");

    The first parameter indicates the virtual path of the page; the second parameter is the resource name. For declarative access, you use the meta:ResourceKey attribute. Here's an example:

    <asp:Button ID="Button1" Runat="server" meta:resourcekey="ButtonResource1" />

    The declaration associates a unique resource key with the specified button instance. The local .resx file will contain entries of the form prefix.name, where prefix is a resource key and name is a property name on the bound control. To give the button a localizable caption (the Text property), you simply create a ButtonResource1.Text entry in the resource file.

    Resource files found in both the local and global resource folders are compiled to create classes for satellite assemblies. The net effect is that developers create .resx files and test the page. The ASP.NET compilation machinery does the rest.

    The App_Themes Folder:

    The App_Themes folder defines themes for ASP.NET controls. Each theme takes a folder under App_Themes. Defined, a theme is a collection of files with style information. Compiled, the contents of the files in a theme folder generate a class that, invoked by the page, programmatically sets styles on themed controls.

    The App_Themes folder lists themes local to the application. An application can also inherit global themes defined in the following folder:

    %WINDOWS%\Microsoft.NET\Framework\[version]\ASP.NETClientFiles\Themes

    From the compilation perspective, there's no difference between global and local themes. If a theme with a given name exists both locally to the application and globally to the server machine, the local theme takes precedence.

    The App_WebReferences Folder:

    In Visual Studio .NET 2003, an ASP.NET application that requires access to a Web service will obtain the corresponding .wsdl file through the Add Web Reference dialog box. The Web Service Description Language (WSDL) document for the Web service is not sufficient to make the Web service usable from the page. An ASP.NET page is ultimately a managed class and needs another managed class to talk to. So the Web service is wrapped by a proxy class. The proxy class is created by Visual Studio using the services of a command-line tool—wsdl.exe. The proxy class contains as many methods as there are Web methods on the Web service, and it incorporates any custom data type defined by the public interface of the Web service.

    There are no significant costs for developers in this operation. However, developers are clearly dependent on Visual Studio to generate the proxy class. Wouldn't it be easier and simpler if you could just drop the .wsdl file somewhere in the application's tree and have ASP.NET deal with the rest? This is just what the App_WebReferences folder is for.

    It recognizes .wsdl files describing bound Web services, and it generates runtime proxy classes so that ASP.NET pages can place calls to the Web service in a type-safe manner. The App_WebReferences folder can contain subfolders. The name of the subfolder drives the namespace of the resulting proxy class, whereas the WSDL file defines the classname. For example, the samples.wsdl file in MyApp subfolder will originate a proxy class named MyApp.Samples. The dynamically created assembly is named App_WebReferences.xxx.dll, where xxx is a random sequence of characters.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will start discussing about Asp.Net 2.0 build providers.

    Thanks,

    Sukesh Khare
    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Bücher zu verschenken (bis Ende August)

    • 4 Comments

    So… ich brauche Platz in meiner Bücherei und verschenke hiermit die folgenden Bücher und Zeitschriften (teils neu, teils gebraucht):

    ·         Windows Server 2003. Taschenratgeber für Administratoren (Sondereinband), ISBN-10: 3860636464

    ·         Microsoft Office 2003. Die technische Referenz (Gebundene Ausgabe), ISBN-10: 3860639587

    ·         Building Tablet PC Applications (Paperback), ISBN-10: 0735617236

    ·         Programming Microsoft SQL Server 2000 with Microsoft Visual Basic .NET (Paperback), ISBN-10: 0735615357

    ·         Introducing Microsoft .Net (Paperback)

    ·         Developing International Software, Second Edition (Paperback), ISBN-10: 0735615837

    ·         Software-Produkt-Management. (Xpert.press) (Gebundene Ausgabe), ISBN-10: 3540140379

    ·         Microsoft Visual C++ .NET Step by Step (Paperback), ISBN-10: 0735615675

    ·         Visual Basic .NET verstehen und anwenden. (Sondereinband), ISBN-10: 3860636391

    ·         Grundkurs Programmieren mit Visual Basic (Broschiert), ISBN-10: 3528058552

    ·         Microsoft .NET Framework 1.1 Class Library Reference 5. System.Web: Class Library Reference: 5 (Pro-Developer) (Taschenbuch), ISBN-10: 073561816X

    ·         iX SPECIAL, Programmieren mit .NET

    ·         CoDe FOCUS, Mobile PC Development

    Bei Interesse einfach eine E-Mail über meinen Blog an mich schicken. Wenn sich mehr als eine Person für ein Buch interessiert verlose ich das Buch. Ein Buch/Zeitschrift pro Person. Einsendeschluss ist der 31.08.2007 31.07.2007, 23:59 (GMT+01:00).

    Da ich ab Fr. in Seattle bin kann ich die Bücher leider erst Mitte August verschicken.

    Viel Erfolg!

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 15

    • 4 Comments

    Hi Everyone,

    Welcome back!!!

    As mentioned yesterday, today we will be wrapping up with the discussion about the ASP.Net 2.0 compilation machinery with the discussion about virtual path providers.

    Virtual Path Providers:

    Before the advent of ASP.NET 2.0, a source ASP.NET page could be only an .aspx file deployed on the server and located in a particular folder. A one-to-one correspondence is required between .aspx resources and files on disk. In ASP.NET 2.0, the virtual path provider mechanism allows you to virtualize a bunch of files and even a structure of directories. You can abstract web content away from the physical structure of the file system. Created to serve the needs of SharePoint (the next version of SharePoint when ASP.Net 2.0 was being designed was to be built on top of ASP.NET 2.0) virtual path providers prove extremely useful to ASP.NET developers too. For example, you can register a path provider and serve ASP.NET the source code of your pages reading from a database. (Yes, this is just what SharePoint does with its earlier version and will do, based on ASP.NET 2.0.)

    Structure of a Virtual Path Provider:

    A virtual path provider (VPP) is a class that inherits from the VirtualPathProvider class and implements a virtual file system for a Web application. In such a virtual file system, you're essentially using files and directories that a custom data store other than the file system will provide. Most files involved with the processing of an ASP.NET request can be stored in a virtual file system. The list includes ASP.NET pages, themes, master pages, user controls, custom resources mapped to a build provider, and static Web resources such as HTML pages and images.

    A VPP can't serve global resources—such global.asax and web.config—and the contents of reserved folders—such as Bin, App_Code, App_Data, App_GlobalResources, and any App_LocalResources. Below table details the members to override in a sample VPP component.

    Member

    Description

    CombineVirtualPaths

    Combines a base path with a relative path to return a complete path to a virtual resource

    DirectoryExists

    Indicates whether a directory exists in the virtual file system

    FileExists

    Indicates whether a file exists in the virtual file system

    GetCacheDependency

    Creates a cache dependency based on the specified virtual paths

    GetCacheKey

    Returns a cache key to use for the specified virtual path

    GetDirectory

    Gets a reference to a VirtualDirectory-derived class that represents the virtual directory the requested resource is mapped to

    GetFile

    Gets a reference to a VirtualFile derived class that represents the virtual file the requested resource is mapped to

    GetFileHash

    Returns a hash of the specified virtual paths

    Previous

    Protected property, gets a reference to a previously registered VPP object to ensure that the resource can be resolved either by a registered VPP or the default one

    When writing a custom VPP, it is important that you override GetFile and GetDirectory and use the Previous property carefully. Here's an example:

    public override VirtualFile GetFile(string virtualPath)

    {

        if (IsPathVirtual(virtualPath))

            return new YourVirtualFile(virtualPath, this);

        else

            return Previous.GetFile(virtualPath);

    }

    In the preceding code, IsPathVirtual is a private function that simply establishes whether your VPP is able to process the virtual path. If not, you pass the request down to the next VPP in the ASP.NET chain. If you omit the call to Previous, the request won't be processed.

    private bool IsPathVirtual(string virtualPath)

    {

        // For example

        // Check the virtual path against your data store

    }

    Structure of a Virtual File:

    A virtual path provider works by taking URLs and checking whether a VPP is registered to handle that URL. If so, the VPP is given a chance to return the ASP.NET source for that path. A VPP returns the source of a virtual path through an object that inherits from the class VirtualFile. Following table details the members to override in a virtual file class.

    Member

    Description

    IsDirectory

    Indicates whether this is a virtual resource that should be treated as a file

    Name

    Gets the display name of the virtual file

    VirtualPath

    Gets the path of the virtual file

    Open

    Returns a read-only stream that refers to the contents of the requested resource

    The key thing to do when writing a custom virtual file class is to override the Open method and make it return a read-only stream to the contents of the virtual resource. In the Open method, you use the virtual path as the key to access the data store and retrieve the source code.

    Registering a Virtual Path Provider:

    Unlike most providers, a virtual path provider is not registered through the web.config file. You can register your VPP either in the Application_Start global event or by adding a static AppInitialize method to some class deployed in App_Code. Here's a sample class you can drop in App_Code to register a VPP:

    public static class AppStart

    {

        public static void AppInitialize()

        {

            // Add a new VPP to the chain

            MyPathProvider vpp = new MyPathProvider();

            HostingEnvironment.RegisterVirtualPathProvider(vpp);

        }

    }

    The name of the surrounding class is arbitrary; the name and signature of AppInitialize are not :-). If multiple static methods with this name exist in the different classes stored in App_Code, you get a compile error.

    Important Note: It is essential that a virtual path provider be registered prior to any page parsing or compilation. If a path provider is registered in other points in the application (for example, web.config) or page life cycle, some unexpected results may show up. There's no syntax requirement that prevents you from registering a VPP, say, in Page_Load. However, if the VPP is registered after the page assembly has been generated, there's no way to invalidate the link between that page and that assembly. As a result, when requesting that page, the VPP will be bypassed. It still makes sense to register a VPP from within a page event, but only if you do that from a page that is not designed to be served by the VPP and that is invoked prior to any page served by the VPP. As you can see, it might not be a common situation and so the above method is usually used.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will start discussing about HTTP Handlers and Modules.

    Thanks,

    Sukesh Khare
    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 12

    • 3 Comments

    Hi Everyone,

    Welcome back!!!

    As mentioned earlier, today we will discuss about the ASP.Net 2.0 reserved folders. There a number of reserved folders that you will see applicable to an ASP.Net 2.0 application. We will now try to understand what each of these is and what their respective purposes are. As there are many such folders, and each has its own associated concept, we will see a few today and the remaining tomorrow:

    Folder name

    File Types

    Notes

    Bin

    .dll

    Contains any prebuilt assemblies required by the application.

    App_Browsers

    .browser

    Contains application-specific browser definition files that ASP.NET uses to identify individual browsers and determine their capabilities.

    App_Code

    .cs, .vb, .xsd, custom file types

    Contains source class files to compile as part of the application. ASP.NET compiles the code in this folder when pages are requested. Code in the folder is referenced automatically in applications.

    App_Data

    .mdb, .mdf, .xml

    Contains Microsoft Office Access and SQL Express files as well as XML files or other data stores.

    App_GlobalResources

    .resx

    Contains resource files to be used programmatically in the localization of an application.

    App_LocalResources

    .resx

    Contains page-scoped resource files.

    App_Themes

    .skin, .css, .xsl, auxiliary files

    Contains a collection of files that define the appearance of ASP.NET pages and controls.

    App_WebReferences

    .wsdl

    Contains WSDL files to generate proxy classes and other files associated with using Web services in your application.

    The Bin Folder:

    The Bin folder contains all deployable assemblies required by the application for controls, components, or other code that you want to reference. Any .dll files found in the directory will be automatically linked to the application. If unused or outdated files are left around, the risk is that you'll get "ambiguous reference" exceptions. In other words, if two distinct assemblies define the same class (same namespace and class name), the ASP.NET runtime can't resolve which one to use and raises an exception. This is a common error when, at development time, you rename a project or an assembly name. To avoid that, make sure that no unnecessary assembly is found or at least remove the following line from the <assemblies> section in the configuration file:

    <add assembly="*" />

    Of all the folders listed in above table, only Bin is recognized by ASP.NET 1.x applications also.

    The App_Browsers Folder:

    This folder contains .browser files. A .browser file describes characteristics and capabilities of a browser—be it a mobile device or a desktop browser. ASP.NET installs a bunch of .browser files in the Config\Browsers folder under the installation path. These files are shared by all applications. You place under the App_Browsers folder only the browser files specific to the current application. The content of the .browser file is compiled on the fly to provide up-to-date browser information to the ASP.NET runtime. Let's briefly address a scenario in which having a custom .browser file might be helpful. Imagine that your application uses a control that doesn't render effectively under a certain browser. You can write a .browser file to force ASP.NET to use a different adapter to render that control when the host page is served by the specified browser.

    <browsers>

         <browser id="browserID">

              <controlAdapters>

                    <adapter controlType="Samples.CustomControl" adapterType="Samples.Adapters.CustomControlAdapter" />

              </controlAdapters>

         </browser>

    </browsers>

    Assuming that browserID matches one of the standard browsers recognized by ASP.NET, the .browser file just shown dictates that CustomControlAdapter be used to render CustomControl under the specified browser.

    The App_Code Folder:

    The App_Code subdirectory lives immediately underneath the Web application's root and stores all class files that should be dynamically compiled as part of the application. These class files get automatically linked to the application and don't require you to add any explicit directive or declaration in the page to create the dependency. Class files placed in the App_Code folder can contain any recognized ASP.NET component—custom controls, helper classes, build providers, business classes, custom providers, HTTP handlers, and so on.

    Note: At development time, changes to the App_Code folder cause the whole application to be recompiled. For large projects, this can be undesirable and time-consuming. For this reason, I encourage you to modularize your code into distinct class libraries in which you group logically related sets of classes. Mostly helper classes specific to the application should make their way into the App_Code folder.

    All class files dropped into the App_Code folder should use the same language. If you have class files written in two or more languages, you must create language-specific subdirectories to contain classes for each language you support. Once files have been grouped by language, you add an entry to the web.config file for each subdirectory:

    <compilation>

         <codeSubDirectories>

              <add directoryName="VBFolder" />

         </codeSubDirectories>

    </compilation>

    It is important that the language-specific subdirectory is registered in the web.config file; otherwise, all files underneath App_Code will be compiled to a single assembly regardless of the folder they belong to. The preceding configuration script delineates a situation in which all, say, C# files are in the root App_Code, and a few Visual Basic .NET class files are moved into the VBFolder directory. If a directory mentioned in the <codeSubDirectories> section doesn't exist, you'll receive a compilation error. Files in the root App_Code folder are compiled to App_Code_xxx.dll assembly, where xxx is a randomly generated sequence of characters. Files in a given subdirectory will be compiled to a dynamically created assembly named App_SubCode_xxx_yyy.dll, where xxx indicates the name of the subdirectory and yyy is a random sequence of characters. The <codeSubDirectories> section is valid only if it is set in the web.config file in the application root.

    A strongly named assembly can be created by dropping an assemblyinfo.cs file in the App_Code directory or any other subdirectory you might have. Obviously, you'll use an assemblyinfo.vb file if the folder contains Visual Basic .NET files. The assembly configuration file may refer to a .snk file to contain the key for the strong name.

    Note 1: To sign an assembly with a strong name, you must first obtain a public/private key pair. You can get such a key pair by using the Strong Name tool (sn.exe), one of the SDK binaries you'll find in the installation path of the .NET Framework. Key pair files usually have a .snk extension. You save this file to an application folder and reference it in the assemblyinfo.cs file, as shown here:

    [assembly: AssemblyKeyFileAttribute(@"yourKeyPair.snk")]

    Note 2: Visual Basic .NET looks for the key file in the directory containing the Visual Studio Solution, whereas the C# compiler looks for the key file in the directory containing the binary. In light of this, adjust the path you use with the attribute, or place the key file in the proper folder.

    On any subsequent rebuild, the names for assemblies change, and as soon as the old AppDomain requests cycle out, the old assemblies are removed. The App_Code folder can contain more than just class files. In particular, it can contain and automatically process XSD files representing a schema of data. When an XSD file is added to the folder, the compiler will parse it to a typed DataSet class, which will be added to the application scope. In ASP.NET 1.x, this work is accomplished by a Visual Studio .NET wizard and uses a command-line utility under the hood—xsd.exe.

    Note: When you register a component (for example, a custom server control or a custom HTTP handler) with the web.config file, you are typically requested to specify the name of the assembly that contains the code. If the component is defined in the App_Code folder, which name should you indicate for the assembly? In this case, you just omit the assembly information and specify only the full class name. When no assembly is specified, the ASP.NET runtime attempts to load the class from any loaded assemblies, including the dynamically created assembly for the App_Code folder.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will continue this discussion and will deal with the remaining ASP.Net 2.0 reserved folders – namely App_Data, App_GlobalResources, App_LocalResources, App_Themes, App_WebReferences. In the following days we will look at what are build providers and a sample custom build provider.

    Thanks,

    Sukesh Khare
    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 5

    • 3 Comments

    Hi Everyone,

    Welcome back!!!

    As mentioned, we are continuing to discuss the automatic dynamic page compilation further.

    Now, if you notice the way the final page class gets prepared is a bit different in ASP.Net 2.0 compared to how it happened in ASP.Net 1.x, this is typically because of the introduction of partial classes. Partial classes are a new feature introduced in C# 2.0 and ASP.Net 2.0 leverages it. We will not discuss much about partial classes here. For those interested please refer here. In ASP.Net 1.x, the page class inherits from the code-behind class you created with Visual Studio. In ASP.Net 2.0, the page class still inherits from the class that represents the code. But the class that represents the code is a completed version of the partial class representing the Visual Studio.Net code file. In particular, the partial class in the project is completed with a second partial class dynamically arranged by the ASP.Net HTTP runtime.

    Let's understand this based on the following diagram (please take enough time to grasp this and please ask questions if not understood :-)):

    Creation of a dynamic page 

    The following diagram gives another workflow based understanding of the creation of the dynamic page class:

    Creation of a dynamic page

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow also we will continue with the discussion of dynamic compilation of pages.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 6

    • 2 Comments

    Hi Everyone,

    Welcome back!!!

    Again, continuing to discuss the automatic dynamic page compilation further.

    Let's understand how is the page assembly generated with respect to what files are involved. Generating an assembly for a particular .aspx resource is a 2 step process. First, a class file is created that fully represents the markup of the .aspx file. Second, the dynamically generated class is compiled into an assembly and cached in the "Temporary ASP.Net Files" folder. There will be a distinct folder for this for each installed version of ASP.Net. Let's understand this "Temporary ASP.Net Files" folder a bit more:

    The Temporary ASP.Net Files folder has one child directory for each application ever executed. The name of the subfolder matches the name of the virtual directory of the application. Pages that run from the Web server's root folder are grouped under the "root" subfolder. Page specific assemblies are actually cached in a subdirectory placed a couple of levels down the virtual directory folder. The names of these two child directories one below the other are the result of a hash algorithm based on some randomized factor along with the application name. A typical path is shown below. The last two directories (numbered names) have fake but realistic names:

    \Framework
        \[version]
            \Temporary ASP.Net Files
                \MyWebApp
                    \6789b205
                        \e40605c7

    Regardless of the actual algorithm implemented to determine the folder names, from within an ASP.Net application, the full folder path is retrieved using the following, pretty simple code:

    String tempAspNetDir = HttpRuntime.CodegenDir;

    So much for the location of the dynamic assembly. How does the ASP.Net runtime determine the assembly name for a particular .aspx page? For each processed page, the application's temporary folder contains a file with the following name:

    [page].aspx.xxxxx.compiled

    Obviously, [page] represents the name of the .aspx resource. The xxxxx placeholder is a hash value based on the directory, so all .aspx files from the same folder have the same hash. All page files are compiled in the same folder, regardless of the fact that they might originate from different source folders. The hash value disambiguates files that have the same name but originally belonged to different originating source folders. An internally stored cache of hash values allows the ASP.Net runtime system to quickly identify hash values for any given resource name. The following listing shows the contents of a .compiled file.

    <preserve virtualPath="/Compilation/Test.aspx"

        hash="3521556vf"

        filehash="5d556b72e8843345"

        flags="10000"

        assembly="App_Web_h5y1dfjq"

        type="ASP.Test_aspx">

        <filedeps>

            <filedep name="/Compilation/Test.aspx" />

            <filedep name="/Compilation/Test.aspx.cs" />

        </filedeps>

    Note: The syntax of .compiled files is not documented and might change in future versions of ASP.Net. It is shown here for purely educational purposes and to help to form an idea of how things work under the hood. Be careful to rely on this information for any application.

    The <preserve> node contains a reference to the original source file (test.aspx), the name of the class created upon it (ASP.test_aspx), and more importantly, the name of the assembly that contains a compiled version of the class.

    The <filedeps> node lists the source files that concur with the definition of the dynamic assembly for the page.

    Once the HTTP handler has identified the name of the class that represents the requested page, the .compiled file helps to figure out the assembly name, if any, that contains it. If no .compiled file exists, or if the linked assembly is missing or outdated, the .aspx source is parsed again to create a temporary C# or VB.Net class file. This class file is then compiled to a new assembly whose name is randomly generated.

    Note: In ASP.Net 2.0, the name of dynamically created assemblies that represent pages always begin with App_Web_. Other dynamically created assemblies that represent themes, application class files, resources, and global.asax have different names.

    Detecting Page Changes:

    The dynamically compiled page assembly is cached and used to serve any future request for the page. However, changes made to an .aspx file will automatically invalidate the assembly, which will be recompiled to serve the next request. The link between the assembly and the source .aspx files is kept in the aforementioned .compiled file. Any changes to any of the files listed in the <filedeps> section will also invalidate the assembly. To detect changes, the ASP.Net runtime installs a file monitor infrastructure based on the Win32 file notification system.

    When a page is changed, it's recompiled as a single assembly and reloaded. ASP.Net ensures that the next request will be served the new page outfit by the new assembly. Current requests, on the other hand, will continue viewing the old page served by the old assembly. The two assemblies are given different (because they are randomly generated) names and therefore can happily live side by side in the same folder as well as be loaded in the same AppDomain.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow see how ASP.Net replaces page assemblies at runtime.

    Thanks,

    Sukesh Khare

  • <dw:daniel_walzenbach runat="server" />

    Genealogy made easy - Announcing Family.Show 2.0

    • 2 Comments

    Family.Show is a genealogy program that demonstrates the usage of WPF for a complex, realistic scenario. If you're a fledgling WPF developer who wants to pore over some code that demonstrates best practices for application construction, there's nothing better out there today.

    If you've not yet tried out Family.Show, you can run it from here: http://www.vertigo.com/downloads/familyshow/familyshow.application

    Sources are availible from here: http://www.codeplex.com/familyshow

    Have fun!

       Daniel

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 4

    • 2 Comments

    Hi Everyone,

    Welcome back!!!

    Today and in next few days we will discuss the automatic dynamic page compilation. Each web application has its own copy of the Http runtime and runs in a separate AppDomain. The runtime object creates the Http context for the request, and it initializes the cache and the file system monitor used to detect changes in the application files. The worker process (either aspnet_wp or aspnet_isapi inside w3wp) activates the HTTP pipeline by creating a new instance of the HttpRuntime class and then calling its ProcessRequest method.

    As mentioned earlier the ultimate goal of the HTTP pipeline is finding in the current AppDomain a managed class that fully represents the requested ASP.Net resource. For pages, this class derives either directly or indirectly from Page class and follows a particular naming convention. For a page named xxx.aspx, the default class name is ASP.xxx_aspx (if the page features the ClassName attribute in the @Page directive, the actual class name will be ASP.ClassName). If such a class is available in the current AppDomain, it is instantiated and invoked through the methods of the IHttpHandler interface. Otherwise, such a class is dynamically created by the page handler factory object. As we will see tomorrow ASP.Net knows exactly from the contents of temporary files if the page class exists and where it is located.

    Note: The dynamic creation of a page class occurs at least the first time the page is requested, right after deployment. The class is shared by all sessions, and only the very first user to hit it after the application is started experiences the compilation delay. After that, the page is recompiled only in case of changes to its source code or any of its dependencies, such as a master page. This first-hit delay can be avoided if the site is deployed in a precompiled form. If the page is precompiled, no dynamic creation occurs. We'll have more to say on precompilation later.

    The Page Handler Factory:

    The HttpApplication object retrieves from machine.config the name of the handler object to serve requests of a particular type. The following code snippet shows the standard setting that associates the PageHandlerFactory class with .aspx resources. Similar mappings are shown for .asmx (Web Services) and .ashx (custom HTTP handler) resources.

    <httpHandlers>

    <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />

    <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />

    <add path="*.asmx" verb="*" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bo3f5f7f11d50a3a" validate="True" />

    ...

    </httpHandlers>

    The PageHandlerFactory class implements the IHttpHandlerFactory interface, detailed below:

    The IHttpHandlerFactory Interface:

    Method

    Description

    GetHandler

    Returns an instance of a class that implements the IHttpHandler interface and can serve the requested resource. For pages, this class would derive from Page class. Arguments to this method include the HTTP verb, the raw URL and the context of the request.

    ReleaseHandler

    Does whatever is needed to enable the factory to reuse the specified handler instance. The default page HTTP handler's implementation of this method simply returns void.

    The page handler factory is responsible for either finding the assembly that contains the page class or dynamically creating an ad hoc assembly. The source code for the class is created by parsing the souce code of the requested .aspx resource, and its temporarily saved in the following ASO.Net temporary folder:

    %systemroot%\Microsoft.Net\Framewor\[version]\Temporary ASP.Net Files

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will continue with the discussion of dynamic compilation of pages.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    CSS in Visual Studio 2008 rockt!!!

    • 2 Comments

    An CSS geht kein Weg vorbei und mit Visual Studio 2008 gibt es es nun endlich den passenden Support.

    Ein kleines, einfaches Beispiel:

    <body>

        <form id="form1" runat="server">

        <div>

            <asp:Label ID="Label1" runat="server" CssClass="xxx" Text="Test"></asp:Label>

        </div>

        </form>

    </body>

    Die Seite referenziert folgendes CSS-Stylesheet

    Body {

          font-family: Verdana;

    }

    .xxx{

          font-family: Calibri;

    }

    Frage: Welche Schriftart wird auf Label1 angewendet?

    Was in diesem Beispiel noch einfach ist wird komplizeirter, wenn mehrere, kaskadierte Stylesheets zum Einsatz kommen.

    Glücklich, wer in diesen Situationen auf Visual Studio 2008 zurückgreifen kann...

    Schöne Grüße aus Seattle!

        Daniel

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 11

    • 1 Comments

    Hi Everyone,

    Welcome back!!!

    Let's continue the discussions around the ASP.Net compilation mechanisms. We discussed the overall dynamic compilation concepts (what happens when resources get updated) and pre-compilation (techniques to avoid first hit delay and preserving intellectual property by hiding source code), however whenever any kind of compilation happens for any resource of an ASP.Net site, there is a machinery that gets triggered behind the scenes which does the job of actually compiling the resources from their source files. That's what we will look into today.

    Building Blocks of ASP.NET Compilation:

    The ASP.NET compilation machinery involves two main manager classes and a family of components named "build providers". The two classes are the ones we mentioned on Friday last week - ClientBuildManager and BuildManager. ClientBuildManager acts a proxy between client applications such as Visual Studio and the ASP.NET back-end system that actually compiles pages and resources. BuildManager governs the physical compilation process from within the ASP.NET environment. It creates and uses build-provider components to process specific resources. Finally, build providers supply an object model to parse file types and generate code. Behind each C# or Visual Basic .NET class dynamically compiled to an assembly from whatever application folder, there's a build provider. For example, a build provider governs the compilation of ASP.NET pages, themes, and profile information. You can define and register custom build providers to extend and enhance the set of file types that ASP.NET can handle. We'll see a sample custom build provider later this week. Let's start the tour of the ASP.NET compilation machinery with a look at the available configuration options. The ASP.NET compilation environment is subject to a number of attributes defined in the web.config file. The section to check out is <compilation>. It is composed of four child sections, as listed in following table:

    Child Sections of <compilation>:

    Section

    Description

    <assemblies>

    Lists the assemblies that are used during the compilation of an ASP.NET resource.

    <codeSubDirectories>

    Lists subdirectories containing code files to be compiled at run time. Typically, they are children of the App_Code folder. We'll return to this subject later.

    <buildProviders>

    Lists all registered build providers. We'll return to this subject later.

    <expressionBuilders>

    Lists all registered expression builders. (We'll cover expression builders in one of the sessions quite later in one of the coming weeks.)

    Before going any further with child sections of the <compilation> block, let's explore the attributes available to <compilation>. The Debug attribute indicates whether to compile retail or debug binaries. The default is false. The DefaultLanguage attribute indicates the language to default to if the page lacks this information. The default is Visual Basic .NET. Strict and Explicit turn on and off the corresponding flags on the Visual Basic compiler. Finally, TempDirectory specifies the directory to use for temporary file storage during compilation.

    Linked Assemblies:

    The <assemblies> section lists the assemblies automatically linked to each page class being compiled. The default contents of the section are shown here:

    <assemblies>

         <add assembly="mscorlib" />

         <add assembly="System, ..." />

         <add assembly="System.Configuration, ..." />

         <add assembly="System.Web, ..." />

         <add assembly="System.Data, ..." />

         <add assembly="System.Web.Services, ..." />

         <add assembly="System.Xml, ..." />

         <add assembly="System.Drawing, ..." />

         <add assembly="System.EnterpriseServices, ..." />

         <add assembly="System.Web.Mobile, ..." />

         <add assembly="*" />
    </assemblies>

    The final <add> line dictates that all assemblies found in the /Bin folder are to be loaded for the application. In application-specific web.config files, you can modify this list at will by using the <clear />, <remove/>, and <add/> nodes. They let you respectively empty the previous list, remove a particular assembly, and add a particular assembly.

    Batch Compilation:

    ASP.NET attempts to batch into a single compiled assembly as many pages as possible without exceeding the configured maximum batch size. Batch compilation is a form of optimization that attempts to minimize the number of assemblies loaded into an application. Batch compilation attempts to group in the same assembly pages resident in the same directory that are using the same language. Batch compilation is attempted only in Web directories containing page content such as .aspx and .ascx files. Reserved directories such as App_Code are always compiled atomically into a single assembly. Pages with parsing errors are excluded from compilation. When a page has a compile error, the result of the failed compilation is not included in the final assembly. Following table lists the configuration options with respect to batch compilation. The batch system is governed by configuration directives in the <compilation> section of the configuration file. Fine-tuning parameters in the <compilation> section of the configuration file is important and should save you from both having (and loading) 1000 different assemblies for as many pages and from having a single huge assembly with 1000 classes inside. Notice, though, that the problem here is not only with the size and the number of the assemblies but also with the time needed to recompile the assemblies in case of updates.

    Batch Compilation Options:

    Attribute

    Description

    batch

    Enables batch compilation. Set to true by default.

    batchTimeout

    Indicates, in seconds, the timeout period for batch compilation. If compilation cannot be completed within the timeout period, the compiler reverts to single compilation mode for the current page. Note that in ASP.NET 2.0, this is no longer supported, and it is ignored.

    maxBatchSize

    Indicates the maximum number of pages to be grouped together per batch compilation.

    maxBatchGeneratedFileSize

    Maximum combined size (in KB) of the generated source file per batch compilation.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will continue this discussion and will deal with the ASP.Net 2.0 reserved folders. In the following days we will look at what are build providers and a sample custom build provider.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 1

    • 1 Comments

    Es ist unglaublich! Ich bin immer wieder fasziniert wie viele interessante Informationen innerhalb von Microsoft ausgetauscht werden! Zusätzlich zu internen Seiten der Produktgruppen, Mailinglisten, Blogs, Wikis, etc. hat mein Kollege Sukesh Khare angefangen täglich Informationen rund um das Thema ASP.NET 2.0 zu veröffentlichen. Innerhalb der nächsten 2-3 Monate plant Sukesh die Themen

    • Compilation Model
    • Configuration
    • Provider Model
    • Out of band technologies
    • Web Parts
    • Mobility
    • Site Navigation
    • Iterative Controls
    • User Controls
    • Custom Controls

    zu behandeln und er hat mir erlaubt, diese Infos auf meinem Blog zu veröffentlichen :-))

    In diesem Sinne viel Spaß mit den "Daily .Net Feeds"!

    Daniel


    Hi Everyone,

    Welcome again to a new edition of Daily .Net Feeds. As intimated earlier this edition will focus on ASP.Net 2.0 intrinsics so we can better grasp and take our understanding to the next level about the internal functioning of ASP.Net 2.0 features. Considering that we will be dealing with some complex topics here, note that these emails will be short enough to address those who don't have expertise around ASP.Net 2.0. This might not be noticeable during initial stages but will be visible in oncoming topics. This way everyone can assimilate the information appropriately by appending some background reading to this content if needed.

    Please feel free to ask questions and also to answer if you know for sure, let's make this forum both informative and interactive so it benefits everyone.

    We will begin today by talking about the ASP.Net compilation model.

    ASP.Net 2.0 Compilation Model

    Before we take a deep dive, let's run through a summary of some basic facts that we might or might not know already related to ASP.Net compilation model:

    1. The basic methodology of ASP.Net compilation model is that mostly all types of files served by ASP.Net (very few exceptions) are automatically compiled on demand when first requested by a web application.
    2. In ASP.Net 1.x dynamic compilation was supported for ASPX, ASMX, ASHX, Global.asax and class files. In ASP.Net 2.0 this model is extended to other file types – XSD, WSDL, resource files, themes and master pages. Specifically, pages are compiled on first request and global.asax is dynamically compiled the first time any page is requested from the application, even before the page is compiled.
    3. ASP.Net pages are made up of markup and code files. To take advantage of the benefits that the compiled code has, markup is also compiled. Generally speaking, markup is converted to a C# or VB.Net temporary class which fits into the hierarchy with the code class. Then these are compiled into an assembly that gets loaded into the application Domain that hosts the application.
    4. The originally requested resource (ex an ASPX page) is automatically tracked and invalidated and recompiled in case of changes.
    5. This model gives 2 key benefits – testing/development ease of interpreted model and performance/robustness of compiled code.

    Next, we will take a closer look at the ASP.net runtime environment:

    1. Any incoming requests that IIS gets is mapped to an external module for actual processing with 2 notable exceptions: static resources (images, HTML etc) and kernel cached pages.
    2. These modules are DLL files, not just plain Win32 dlls but IIS ISAPI DLL. An ISAPI module is a Win32 DLL that necessarily exports a couple of functions with a given name and prototype (GetExtensionVersion and HttpExtensionProc). HttpExtensionProc is the function that IIS calls into and this is the one that processes the request and generates the response. This external module in case of ASP.Net is the ISAPI DLL called aspnet_isapi.dll
    3. The binding for which resources IIS calls aspnet_isapi is set in IIS metabase and can be changed through properties of an IIS application.
    4. The detailed tasks that aspnet_isapi performs vary quite a bit with the process model in use. ASP.Net supports 2 process models based on the version of IIS it runs on.
    5. IIS 5 process model is the only option available when ASP.Net runs under IIS 5.x. On IIS 6, it can be enabled but is not the default option – the default there is the IIS 6 process model, also called worker process isolation mode which is centered on the concept of application pools. IIS 7 does not support the IIS 5 isolation model.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will take a quick look at the two process models.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 2

    • 1 Comments

    We skimmed through some basics of ASP.Net compilation model and the ASP.Net runtime environment yesterday. We mentioned the 2 process models that ASP.Net supports; we will see more inside these 2 models today.

    ASP.Net Process Models

    IIS 5.0 Process Model

    On IIS 5.x all ASP.Net applications run inside a separate process called aspnet_wp.exe. So in this model aspnet_isapi doesn't actually process the requests, it is hosted within the inetinfo process of IIS but it acts as a dispatcher, collects all the information available about the invoked URL and routes the request towards this distinct process aspnet_wp also called the ASP.Net worker process. The communication between the ISAPI extension and the worker process takes place through named pipes. By default this worker process runs under the identity of the account called ASPNET, created when ASP.Net is installed

    Only a single copy of aspnet_wp runs all the time and hosts all the active web applications each in a distinct AppDomain. In a web garden scenario though, multiple worker processes run simultaneously, one for each affinitized CPU. If a client requests a page from an already running web application, ASP.Net runtime simply forwards the request to the existing AppDomain associated with the corresponding virtual directory. If the assembly needed to process the page is not available in the AppDomain, it will be created on the fly, otherwise, if it is already created upon the first call, it will simply be re-used.

    Below is a diagrammatic explanation of this process model:

    IIS 5 Process Model

    IIS 6.0 Process Model

    IIS 6 employs a different pipeline of internal modules to process an inbound request, although it mimics the behavior of IIS 5 when run in the IIS 5 isolation mode, also called emulation mode. This model by default is centered on the concept of Application Pools; an application pool is a group of web applications that share the same copy of the worker process. We can configure each pool (and so the process) with a different set of properties.

    So on IIS 6, in the default worker process process model, ASP.Net applications use a generic – ASP.Net agnostic process because it's the similar process that serves any other web applications. The other key component of this model is the kernel level driver called http.sys which is the HTTP listener that captures and eventually services all requests. When a request arrives http.sys routes it to a queue managed by the application pool that the invoked application belongs to. There is just one queue per pool. In IIS 5 isolation mode however, http.sys places requests in a unique, shared request queue.

    In this model, w3wp.exe – the worker process loads aspnet_isapi.dll – the ISAPI extension which in turn loads the CLR (Common Language Runtime) and also starts the ASP.Net runtime pipeline. When this default model is in use on IIS 6, the built in ASP.Net worker process (aspnet_wp) id disabled.

    So, the worker process w3wp uses http.sys to get requests and send responses to the client. This process by default runs under the Network Service account. This is a specific account with the least set of privileges compatible with the functionality it is expected to allow.

    Below is a diagrammatic explanation of this process model:

    IIS 6 Process Model

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will talk about the ASP.Net pipeline that is demonstrated in the above diagrams and in the coming days we will delve into the dynamic compilation of pages.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 14

    • 1 Comments

    Hi Everyone,

    Welcome back!!!

    Yeah, we skipped a few days again, just got a bit busy with my cases. As mentioned earlier, today we will be taking up the discussion about ASP.Net 2.0 Build Providers.

    Build Providers:

    In ASP.NET 1.x, only a few file types are dynamically compiled into assemblies—ASP.NET pages, user controls, ASP.NET Web services, and custom HTTP handlers. In ASP.NET 2.0, compilation model is extended to virtually any file type that you use in your application. In ASP.NET 2.0, commonly used file types are bound to a special breed of component—the build provider—which communicates with the ASP.NET infrastructure and provides the code representation of the contents of the specified file. Hence the build provider registered to process .aspx files will parse the .aspx markup and build a class according to the rules we identified in the session for "Day 5". This class will then be transformed into an assembly with a given scope.

    ASP.NET developers are familiar with this model. The great news is that ASP.NET 2.0 applies this same model to a wide range of file types, such as class files (.cs, .vb), resource files (.resx), Web service references (.wsdl), typed DataSet (.xsd), themes, and so on. Certain file types undergo a runtime transformation process when dropped in some reserved folders. This transformation is driven by native build providers with the same internal architecture and mechanics of providers that build ASP.NET pages.

    Essentially, a build provider is a component that can plug into the ASP.NET compilation system and provide custom compilation support for some file types. Build providers can automatically generate an appropriate proxy class by interpreting at compile time the contents of the source file. A build provider generates compilable code and keeps it in sync with the source file; as the source file changes, the build provider kicks in again and updates everything. To solidify this abstract discussion :-) of build providers let's take a look at the following excerpt from the default configuration file. It illustrates the built-in bindings between file types and native build providers:

    <compilation>

        <buildProviders>

            <add extension=".aspx"

                type="System.Web.Compilation.PageBuildProvider" />

            <add extension=".ascx"

                type="System.Web.Compilation.UserControlBuildProvider" />

            <add extension=".master"

                type="System.Web.Compilation.MasterPageBuildProvider" />

            <add extension=".asmx"

                type="System.Web.Compilation.WebServiceBuildProvider" />

            <add extension=".ashx"

                type="System.Web.Compilation.WebHandlerBuildProvider" />

            <add extension=".resx"

                type="System.Web.Compilation.ResXBuildProvider" />

            <add extension=".resources"

                type="System.Web.Compilation.ResourcesBuildProvider" />

            <add extension=".wsdl"

                type="System.Web.Compilation.WsdlBuildProvider" />

            <add extension=".xsd"

                type="System.Web.Compilation.XsdBuildProvider" />

            <add extension=".js"

                type="System.Web.Compilation.ForceCopyBuildProvider" />

        </buildProviders>

    </compilation>

    Note: All these build providers are nonpublic, internal classes defined in the System.Web.Compilation namespace inside the system.web assembly. All these classes derive from one common root—the BuildProvider class.

    We'll get into the details of BuildProviders in a moment. For now, the following figure shows the conceptual layout of the ASP.NET compilation model.

    Conceptual Layout of ASP.Net Compilation System

    The host environment receives input from external components—a client (for example, Visual Studio 2005 or precompilation utilities) using the ClientBuildManager API or the ASP.NET pipeline—and activates the build manager. The build manager, in turn, invokes the build provider in charge of the resource. When the proxy class has been generated, the assembly builder kicks in to compile the source.

    Note: Build providers are an important building block in the overall ASP.NET infrastructure, but they are certainly not the kind of component you'll have to tinker with every day. You should know that they exist and how they work. In the end, however, you'll rarely run into them unless you need to adjust the way certain files are processed by ASP.NET.

    Build providers kick in during compilation, but compilation can occur for two different reasons—to service a user request at run time and to precompile an application. A file for which a build provider is registered is passed to the provider and processed. What happens next depends on the build provider logic. Application files mapped to a .NET language (for example, .cs or .vb files) are passed to the respective compilers and processed, but they are not deployed. Files that are bound neither to compilers nor build providers are ignored during the compilation step. The precompilation for the deployment mechanism, though, copies them to the final layout.

    There are two points left open tough – a couple exceptions: What happens with .js files? And what if you want to exclude some files from deployment? ForceCopyBuildProvider addresses the former, while IgnoreFileBuildProvider is used for the latter.

    The ForceCopyBuildProvider Provider:

    Specifically designed for .js files, this provider ensures that .js files are always copied during the precompilation for deployment. The issue is that .js is the extension of a standard .NET language—JScript. According to the rules we just outlined, Javascript files wouldn't be deployed. However, a .js file is often a client-side file, the lack of which can compromise an application. To avoid that, the .js extension is bound to ForceCopyBuildProvider, and .js files are then always copied when you deploy your Web site through the Copy Web Site operation in Visual Studio 2005.

    The IgnoreFileBuildProvider Provider:

    Whereas ForceCopyBuildProvider always copies files, the IgnoreFileBuild provider always excludes files of a certain type from participating in any compiling or publishing operation. The ignore-file provider is particularly useful for development-only files you maintain for internal purposes but that have no reasons for being deployed—for example, a Microsoft Office Word document, Microsoft Office Visio diagrams, and so on. Enter the following script in your web.config file to let the compilation system ignore .doc files.

    <compilation>

        <buildProviders>

            <add extension=".doc"

                type="System.Web.Compilation.IgnoreFileBuildProvider" />

        </buildProviders>

    </compilation>

    Architecting a Custom Build Provider:

    Build providers are a constituent part of the compilation machinery and participate in build operations regardless of the starter—be it Visual Studio 2005 or the ASP.NET runtime. As a developer, you can implement your own provider to add custom semantics to ASP.NET compilation.

    An interesting example consists of adding logic to process files with a given extension whose contents represent a mapping with one or more database tables. The provider could then dynamically generate strongly typed classes to render columns in the table. Classes will be generated any time one of these files is added to the project. Nicely enough, build providers also get you full IntelliSense support within Visual Studio 2005.

    Note:

    Have you ever wondered what the magic is that allows Visual Studio 2005 to recognize control properties through IntelliSense on the code-behind class of an .aspx page? In ASP.NET 1.x, Visual Studio .NET 2003 created ad hoc members to represent controls in protected regions so that the class was complete for a .NET reflection analysis. In ASP.NET 2.0, members that represent server controls are created at compile time thanks to the mechanism of partial classes. So how can IntelliSense work correctly on code files?

    The answer is that Visual Studio 2005 has the .aspx build provider generate the dynamic source code of the class with all missing declarations. The resulting assembly is loaded in the Visual Studio 2005 process; the resulting type of the page is scanned through reflection to populate the IntelliSense drop-down lists. So the process we studied on "Day 5" about aspx markup being parsed to generate corresponding partial class definition is continuously happening as we type code. :-)

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will discuss an extremely interesting new feature of ASP.Net 2.0 – Virtual Path Provider. Post that in the oncoming sessions we will be delving into HTTP Handlers and Modules.

    Thanks,

    Sukesh Khare
    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Wie parse ich einen beliebigen String in ein DateTime-Objekt?

    • 1 Comments

    Eigentlich ganz einfach, wie alles, wenn man weiß wie es geht aber dennoch immer wieder gerne nachgefragt. Und so einfach geht's:

    Dim culture As Globalization.CultureInfo = New Globalization.CultureInfo("de-DE", True)

    Dim dateAsString As String = "2007-0712 050430"

    Dim d As DateTime

    d = DateTime.ParseExact(dateAsString, "yyyy-MMdd HHmmss", culture)

    Console.WriteLine(d.ToString)

    Wichtig ist einzig, dass das Format des "Formatstrings" mit dem zu parsenden String übereinstimmt. Sehr cool!

    Weiter Infos finden sich auf

    Happy coding!

    Daniel

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 7

    • 1 Comments

    Hi Everyone,

    Welcome back!!!

    Again, continuing to discuss the automatic dynamic page compilation further. Now we have been saying all the while that ASP.Net will detect automatically at runtime when ASP.Net resources change and will dynamically create new assemblies. Let's see how this replacement of assemblies happens.

    How ASP.NET Replaces Page Assemblies:

    We already mentioned that ASP.Net puts in place a file change notification mechanism and that is what tells ASP.net that a resource got updated and a new assembly is built for that. When a new assembly is created for a page as the result of an update, ASP.NET verifies whether the old assembly can be deleted. If the assembly containing the old page class contains only that page class, ASP.NET attempts to delete the assembly. Often, though, it finds the file loaded and locked, and the deletion fails. In this case, the old assembly is renamed by adding a .delete extension. (All executables loaded in Microsoft Windows can be renamed at any time, but they cannot be deleted until they are released.) Renaming an assembly in use is no big deal in this case because the image of the executable is already loaded in memory and there will be no need to reload it later. The file, in fact, is destined for deletion. Notice that .delete files will actually be cleaned up when the application is restarted next and that can happen due to various reasons, some of which are as follows:

    1. An application file (global.asax or web.config) change
    2. When the number of such recompilations as above exceeds the limit specified by <compilation numRecompilesBeforeAppRestart=... />
    3. Modification of the physical path of a virtual directory
    4. Modification of the code-access security policy

    numRecompilesBeforeAppRestart:

    Other reasons of application restart are quite understandable, let's understand this numRecompilesBeforeAppRestart a bit. When a page is recompiled, the assembly representing its old version stays in memory until the AppDomain is unloaded. There's no way this assembly can be freed up because this is one of the pillars of the whole CLR machinery. To avoid having too many recompiles flood the memory with too many assemblies (all of which are useless), the ASP.NET runtime periodically restarts the application and imposes an upper limit to the number of allowed recompiles. Each ASP.NET application is allowed a maximum number of recompiles (with 15 as the default) before the whole application is restarted. The threshold value is set in the configuration file. If the latest compilation exceeds the threshold, the AppDomain is unloaded, and an application shutdown is scheduled to occur as soon as possible. Bear in mind that the atomic unit of code you can unload in the common language runtime (CLR) is the AppDomain, not the assembly. Put another way, you can't unload a single assembly without unloading the whole AppDomain.

    In order to understand this further let us take a hypothetic example. Let's say we have an ASP.Net application and inside an ASPX page we write some code to access the AppDomain ID and the total number of assemblies present currently in the AppDomain of that ASP.Net application. This can easily be done using code as follows:

    String appDomainID = HttpRuntime.AppDomainId.ToString();

    System.Reflection.Assembly[] listOfAssem = AppDomain.CurrentDomain.GetAssemblies();

    Response.Write(string.Format("AppDomainId: {0}<br />listOfAssem: {1}",appDomainID, listOfAssem.Length));

    Now again, let us say as an example the sample page needs 10 system assemblies, including those specific to the application—global.asax and the page class. This number increases each time you save the .aspx file because after a page update, a new assembly is loaded, but the old one is not unloaded until the whole AppDomain is unloaded. If you save the .aspx file several times (by just opening the file and pressing Ctrl+S), we can easily see that the output of above code will keep increasing each time by to 11, 12, etc. But after 15 recompiles (with the default setting), the AppDomain ID will change – that is as soon as the number of loaded assemblies become 25, and immediately the number of loaded assemblies will revert back to 17 or whatever it was originally. This number, in fact, depends upon the number of referenced assemblies you included with your page.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will take another example, a bit more realistic one and will try to apply all the dynamic compilation concepts we learnt so far and that should be it for dynamic compilation. The upcoming next dive would be inside application pre-compilation.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 8

    • 1 Comments

    Hi Everyone,

    Welcome back!!!

    The feed is delayed a lot today but today will be our last session on dynamic page compilation. To revisit all concepts we learnt and understand how the dynamic compilation process works end to end, we will consider an example. Since all that we discuss today is in the context of this example the feed for today will be a long one but unfortunately I can't imagine splitting :-).

    So, let say, we have a page called Test.aspx in a folder named Compilation. The page contains a text box to grab some user-typed text and a button to trigger a server-side operation that reverses the text. The results are shown in a label control, while another label control displays the current time through a data-bound expression. These features represent two of the most common operations we find on web form pages - postbacks and declarative data binding. The markup and the code for the page follow:

    <%@ Page Language="C#" CodeFile="Test.aspx.cs" Inherits="Test" %>

    <html>

    <head id="Head1" runat="server">

        <title>Sample page</title>

    </head>

    <body>

        <form id="form1" runat="server">

        <div>

            <h1>Enter some text and click.</h1>

            <h2><asp:Label ID="Today" runat="server"

                     Text='<%# DateTime.Now %>' /></h2>

            <asp:TextBox ID="TextBox1" runat="server" Text="Type here" />

            <asp:Button ID="Button1" runat="server" Text="Reverse"

                 OnClick="ReverseText" />

            <hr />

            <asp:Label ID="Label1" runat="server" />

        </div>

        </form>

    </body>

    </html>

     

    using System;

    using System.Web.UI;

    using System.Web.UI.WebControls;

    using System.Text;

     

    public partial class Test : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            DataBind();

        }

        protected void ReverseText(object sender, EventArgs e)

        {

            string reverseText = Reverse(TextBox1.Text);

            Label1.Text = reverseText;

        }

        private string Reverse(string text)

        {

            if (text.Length == 1)

                return text;

            else

            {

                char[] rg = text.ToCharArray();

                Array.Reverse(rg);

                return new string(rg);

            }

        }

    }

    Let's examine in more detail how the test.aspx page is converted into a class and compiled into an assembly. The source code of the page class to render test.aspx is created in the temporary folder and deleted immediately after compiling. It will persist if we have debug=true attribute in the @Page directive or in web.config file. Execute the page, and once the page shows up in the browser, open the "Compilation" folder in the browser under the ASP.NET temporary folder. Below, the first figure shows the path to the folder where temporary files for the page are created and the second figure lists the temporary files created to serve test.aspx. Note that some of these files are deleted after use on a production machine that serves non debug pages.

    Following table provides more details about each of these files. Note that xgpc4gcp is a randomly generated prefix. You will get a different name each time you recompile the page.

    File name

    Description

    hash.web

    Contains the hash value for the folder, which will be used to calculate hash values for individual resources.

    App_Web_xxx.dll

    The dynamic assembly created for the pages in the folder named test.aspx. The xxx placeholder indicates the hash value that makes the test.aspx page unique even if multiple pages with the same name exist in different subdirectories.

    Test.aspx.xxx.compiled

    XML file that contains information about the dependencies that test.aspx has with external files. It also links test.aspx to the randomly generated assembly name.

    xgpc4cgb.x.cs

    Source code for the C# class code created after parsing test.aspx and all its dependencies. These files will be Visual Basic .NET class files if Visual Basic .NET is the language of the page. The x placeholder indicates a 0-based index used to distinguish relevant constituent files. This file is deleted unless the debug attribute is turned on in the page.

    xgpc4cgb.cmdline

    Text file that contains the command line used to compile the preceding class file. This file is deleted unless the debug attribute is turned on in the page.

    xgpc4cgp.err

    Text file that contains any output the compiler sends to the standard error stream. This file is deleted unless the debug attribute is turned on in the page.

    xgpc4cgb.out

    Text file that contains any output text generated by the compiler. This file is deleted unless the debug attribute is turned on in the page.

    Let's take a look at the source code of the xgpc4cgb.x.cs files. For test.aspx, we have three distinct constituent source files. The x placeholder, therefore, varies from 0 through 2, in this case, as discussed in following table:

    File

    Class

    Contents

    xgpc4cgb.0.cs

    (partial) Test, ASP.test_aspx

    It contains two classes. The first is the partial class Test that completes the code file written by the author to back up test.aspx. The second is the page handler class used to serve the test.aspx resource.

    xgpc4cgb.1.cs

    (partial) Test

    The code file class created by the page author as test.aspx.cs.

    xgpc4cgb.2.cs

    ASP.FastObjectFactory

    Internal-use factory class created to avoid reflection and maximize speed when instantiating the page handler class.

    The contents in the partial class defined as xxx.1.cs is the code of the code file class associated with the ASP.NET page. This partial class—named Test as in the Inherits attribute of the @Page directive—is completed with a dynamically generated partial class that adds members for each server control. Here's what the second partial class looks like:

    public partial class Test : IRequiresSessionState

    {

        protected Label Today;

        protected TextBox TextBox1;

        protected Button Button1;

        protected Label Label1;

        protected HtmlForm form1;

     

        protected DefaultProfile Profile

        {

            get { return (DefaultProfile)Context.Profile; }

        }

        protected HttpApplication ApplicationInstance

        {

            get { return (HttpApplication)Context.ApplicationInstance; }

        }

    }

    The FastObjectFactory class is also worth a quick mention. It merely contains a static method that instantiates the page handler class in a strong-typed, early-bound manner. Because the compiled page type is known at run time, .NET reflection would be the only option left to instantiate a class. This trick allows you to gain a little bit of performance on a very frequently executed operation. Here's the typical source code:

    namespace ASP

    {

        internal class FastObjectFactory

        {

            private FastObjectFactory() { }

            static object Create_ASP_Test_aspx()

            {

                return new ASP.Test_aspx();

            }

        }

    }

    Warning: All above code is shown for educational purposes only and in a slightly edited format that makes it read well. If you plan to use this information for building real-world applications, make sure that you verify and cross-check any line of code to ensure that it works in your context, too. Note also that this is ASP.NET internal code; as such, it might change in future builds without being noted.

    Structure of the Page:

    The page class created to service requests for test.aspx inherits from the class specified through the Inherits attribute in the markup file - Test in this case. As mentioned, the Test class is a partial class defined in test.aspx.cs and derives, directly or indirectly, from Page. A second, ASP.NET-generated partial class will complete the definition of Test. The page handler for test.aspx has a fixed name – ASP.Test_aspx. Let's explore its internals as well:

    namespace ASP

    {

        public class Test_aspx : Test

        {

            private static bool __initialized;

            private static object __fileDependencies;

     

            public Test_aspx()

            {

                string[] dependencies;

                AppRelativeVirtualPath = "~/Test.aspx";

                if (__initialized == false)

                {

                    dependencies = new string[2];

                    dependencies[0] = "~/Test.aspx";

                    dependencies[1] = "~/Test.aspx.cs";

                    __fileDependencies = GetWrappedFileDependencies(dependencies);

                    __initialized = true;

                }

                Server.ScriptTimeout = 30000000;

            }

     

            protected override void FrameworkInitialize()

            {

                base.FrameworkInitialize();

                __BuildControlTree(this);

                AddWrappedFileDependencies(__fileDependencies);

                Request.ValidateInput();

            }

     

            public override int GetTypeHashCode()

            {

                // This static number is generated dynamically when the source

                // code of this page is generated dynamically

                return 850224717;

            }

            // ...

        }

    }

    The class has two static members to indicate the initialization state of the class and the list of its file dependencies. These two members are initialized in the class constructor. Next, the ASP.Test_aspx overrides two methods on the base Page class, as detailed in following table:

    Method

    Description

    FrameworkInitialize

    Governs the creation of the page's control tree.

    GetTypeHashCode

    Returns the hash code for the page that uniquely identifies the page's control hierarchy. The method should not be confused with GetHashCode that all .NET Framework classes inherit from System.Object, although both methods pursue similar goals—returning values to identify the contents of objects. GetTypeHashCode is more specific than GetHashCode and bases its value on the page's control tree. The number is generated on the fly when the source code of the page is generated.

    There are two key things going on in the override of FrameworkInitialize. First, the __BuildControlTree method is invoked to fill the Controls collection of the page class, thus determining the control tree of the page. The __BuildControlTree method is autogenerated by ASP.NET. We'll take a look at it in a moment. Second, ValidateInput is invoked on the Request object to ensure that no potentially dangerous input is being processed by the page. ValidateInput is controlled by the ValidateRequest attribute in the @Page directive and simply applies some standard regular expressions to all inbound data. You should never rely on ValidateInput alone to secure your application.

    The Control Tree:

    The __BuildControlTree is the entry point in the code that physically builds a class from the ASPX markup. It uses an IParserAccessor reference to the current page object to find all sub objects in the specified graph and add them to the Controls collection of the page being processed.

    private void __BuildControlTree(Test_aspx __ctrl)

    {

        // Get the parser interface from the page

        IParserAccessor __parser = (IParserAccessor) __ctrl);

     

        // Build the <head> node and add it to the tree

        HtmlHead __ctrl1 = __BuildControl__control2();

        __parser.AddParsedSubObject(__ctrl1);

     

        // Build a subtree for a literal expression

        __parser.AddParsedSubObject(new LiteralControl("<body>"));

     

        // Build the <form> node and add it to tree

        HtmlForm __ctrl2 = __BuildControlform1();

        __parser.AddParsedSubObject(__ctrl2);

     

        // Build a subtree for a literal expression

        __parser.AddParsedSubObject(new LiteralControl("</body></html>"));

    }

    The contents of the <head> tag are processed to obtain a subtree of controls, and the same process occurs with the <form> tag and all of its contents. Any literal expression, such as <body>, is processed as a control as well. Any consecutive text found between two server controls is converted into a literal control and added to the tree.

    Note: In light of this behavior, you should avoid using carriage return/linefeed pairs between server controls. In fact, the sequence /r/n is added to the generated tree as a literal control. The sequence has no impact on the HTML rendering—it simply makes the source more easily readable—but it charges a slight performance penalty at run time.

    Each server control originates a procedure like the following one, which builds the TextBox1 text box control:

    private TextBox __BuildControlTextBox1()

    {

        TextBox __ctrl = new TextBox();

        this.TextBox1 = __ctrl;

        __ctrl.ApplyStyleSheetSkin(this);

        __ctrl.ID = "TextBox1";

        __ctrl.Text = "Type here";

        return __ctrl;

    }

    The preceding code is the result of the following markup:

    <asp:TextBox ID="TextBox2" runat="server" Text="Type here" />

    The build method for the <form> tag calls build methods for all contained controls. Build methods have fixed names: __BuildControlname, where name stands for the ID of the control. It will be controlN for unnamed controls.

    Event Handlers and Data-Binding Expressions:

    What if the control has an event handler or a data-binding expression? Let's first consider the case of a button with the Click event handler. The code is nearly identical to the preceding code snippet, except of course that a Button class is used instead of a TextBox. In addition, you'll find the following:

    __ctrl.Click += new EventHandler(this.ReverseText);

    For data-binding expressions <%# ... %>, the code generated is similar except that the DataBinding event is used.

    __ctrl.DataBinding += new EventHandler(__DataBindingToday);

    The code associated with the handler depends on the nature of the bound control and the code being bound. In this relatively simple case, it looks like the following fragment:

    public void __DataBindingToday(object sender, EventArgs e)

    {

        Label target = (Label)sender;

        target.Text = Convert.ToString(DateTime.Now, CultureInfo.CurrentCulture);

    }

    Note: The $-expressions introduced in ASP.NET 2.0 are processed in a different way, as they are not bound to the data-binding process. We'll delve deep into $-expressions in some oncoming session.

    That's it for today. Thanks for joining!!! So we wrapped up with dynamic page compilation today and we will look at pre-compilation tomorrow. See you tomorrow.

    Thanks,

    Sukesh Khare

    Coordinator Daily

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 9

    • 1 Comments

    Hi Everyone,

    Welcome back!!!

    We again missed a couple of days and most of you know what most of us were busy with in the last 2 days :-) :-). So, as mentioned earlier, today we talk about ASP.Net site pre-compilation.

    Application Pre-compilation:

    By default, each public resource of an ASP.NET site is compiled on the fly only upon its first request. This introduces a first-hit delay as a result of the compilation process. Since the advent of ASP.NET 1.0, developers have raised the issue of site pre-compilation. Site pre-compilation brings a double benefit: no delay for requests because of compilation and no need of deploying source code to the Web server. Further, as do classic Windows executables, precompiled sites offer a high degree of protection against violations of the intellectual property behind the work. Pre-compilation comes in two forms, each targeting a specific scenario/goal: in-place pre-compilation and deploy pre-compilation. The former prepares all the resources in a site to be served without delay by actually accessing and thereby generating all needed dynamic assemblies for all pages and resources that need be compiled. In-place pre-compilation occurs on an already deployed application.

    In-Place pre-compilation:

    In-place pre-compilation is merely a form of performance improvement. You deploy the application as usual using whatever technique you like or can afford—FTP, Xcopy, or setup packages. Once the site is up and running on the production server, you pre-compile it before it goes public. Pre-compilation ensures that each page is accessed and each required dynamic assembly is created. In this way, even the first user hitting the page will be served quickly because the required assembly is already available. In-place pre-compilation essentially primes a site, meaning that no end user will ever wait for pages and their references to be compiled before being served a response.

    Conditions for In-Place Pre-compilation:

    In-place pre-compilation assumes that the site is running under IIS, and it requires that .NET compilers are available on the target machine for the languages used by the pages. Pre-compilation will fail on the application if compilation for any single file fails. The in-place pre-compilation model preserves the full site structure and still allows sites to be extended with new pages or newer versions of existing pages. Needless to say, if new or modified pages are uploaded without stopping and recompiling (pre-compiling) the site, the first user hitting modified pages will experience the first-hit delay again. When pre-compiling a site, though, only new or modified files are actually processed. Up-to-date files are skipped, thus minimizing the impact of the operation on the running sites.

    The aspnet_compiler utility:

    In-place pre-compilation consists essentially of running a batch compiler. It's analogous to manually requesting all the pages on the site to make sure all the code is compiled. The executable in charge of all forms of pre-compilation is aspnet_compiler.exe. You find it in the ASP.NET installation path:

    %WINDOWS%\Microsoft.NET\Framework\[version]

    To pre-compile a site in-place, you use the following command, where /MyTestPreCompiledSite indicates the virtual folder of the application:

    aspnet_compiler –v /MyTestPreCompiledSite

    Following table lists the command-line switches supported by the utility that are relevant to in-place compilation:

    Switch

    Description

    -m

    Indicates the full IIS metabase path of the application. This switch cannot be combined with the -v or -p switches.

    -v

    Indicates the virtual path of the application to be compiled. If -p is also specified, the physical path is used to locate the application. If no virtual path is specified, the application is assumed to be in the default site: W3SVC/1/Root.

    -p

    Indicates the physical path of the application to be compiled. If missing, the IIS metabase is used to locate the application. This switch must be combined with -v.

    -d

    If specified, the debug information is emitted during compilation.

    -c

    If specified, the precompiled application is fully rebuilt. Any previously compiled components will be recompiled.

    -keyfile

    Indicates the physical path to the key file for strong names.

    -keycontainer

    Indicates the name of the key container for strong names.

    -aptca

    If specified, compiled assemblies will allow partially trusted callers.

    -delaysign

    If specified, compiled assemblies are not fully signed when created.

    -fixednames

    If specified, the compiled assemblies will be given fixed names.

    Effects of In-Place Precompilation:

    After running the aforementioned command line, the utility runs and recursively scans all the pages and related dependencies in the virtual folder and child applications. Assemblies are generated in the "codegen" directory and remain there to serve requests. To see it live, I suggest that you delete any temporary folder for your application and then run the utility from the command prompt. The folder fills up before your eyes, and when the tool completes, all required dynamic assemblies have been generated. Note that aspnet_compiler requires localhost access and administrative rights on the machine to operate.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will continue with pre-compilation and will look into deploy pre-compilation, updatable pre-compilation and programmatic pre-compilation.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 10

    • 0 Comments

    Hi Everyone,

    Welcome back!!!

    Let's continue the discussion about ASP.Net site pre-compilation. We talked about in-place pre-compilation yesterday; another flavor of pre-compilation is deployment pre-compilation.

    Pre-compilation for deployment:

    Pre-compilation for deployment pursues different goals than in-place pre-compilation. Conceptually, it tends to transform the ASP.NET application into a closed executable that preserves intellectual property by hiding source code (possibly both markup and classes). Pre-compilation generates a file representation of the site made of assemblies, static files, and configuration files that can be later packaged into a CAB, ZIP, or MSI file for actual deployment. As a pleasant side effect, it also saves your users from first-hit compilation delay. Note that the overall purpose of in-place compilation was getting rid of the first hit delay for the site pages but that is not the case with deployment pre-compilation which in turn works towards getting rid of having to put code at the deployment location. Pre-compilation for deployment has two variants that allow for non-updatable or updatable sites.

    You use the same utility—aspnet_compiler—to build manifests of a Web site. Following table lists additional command-line switches that are useful here.

    Switch

    Description

    -u

    If specified, indicates that the precompiled application is updatable.

    -f

    Indicates that the target directory will be overwritten if it already exists and existing contents are lost.

    targetDir

    Indicates the physical path to which the application is compiled. If not specified, the application is precompiled in-place.

    Non-updatable Pre-compilation:

    The big difference between in-place and deploy pre-compilation is that the latter can work on the development machine and creates a deployable image of the site in the specified target directory. Try the following command:

    aspnet_compiler -v /MyPrecompiledSite c:\Deliverable

    You get the output shown in the following figure:

     

    The first thing that you notice is the presence of an additional small file named precompiledapp.config whose contents are shown here:

    <precompiledApp version="2" updatable="false"/>

    The file is a marker to inform the ASP.NET runtime that the application is precompiled. In the figure, you also see that web.config and web.sitemap have a different date. This is because static files such as images, web.config, web.sitemap, and HTML pages are not compiled. They are just copied to the target destination.

    On the surface, the structure of the site is intact. However, if you delve a bit deeper, you see a lot of differences. First, all .aspx files are empty. To be more precise, they contain a string of text that warns you not to remove .aspx files even though they don't appear to contain any significant text.

    In a precompiled solution, ASP.NET pages are marker files and should not be deleted. In other words, they represent a necessary endpoint and must be deployed. However, their contents won't be parsed or processed. You can also replace the text to display a custom message before you package the layout into a deliverable file.

    The Bin folder of the application also contains a different set of assemblies, as in the original project. In addition to the referenced assemblies, the folder now contains one App_Web_xxx assembly for each page in the application. Sites packaged for deployment only are not sensitive to file changes. When a change is required, you modify the original files, recompile the whole site, and redeploy the new layout. The only exception is the site configuration; you can update web.config or web.sitemap on the production server without having to recompile the site.

    Updatable Precompilation:

    By adding a –u switch to the batch compiler utility, you can pre-compile a site to be updatable. In this case, .aspx files are slightly touched to remove the CodeFile attribute and change the Inherits attribute. Other files, on the other hand, are compiled as usual. In this way, you are allowed to make limited changes to the ASP.NET pages after compiling them. For example, you can change the position of controls or settings regarding colors, fonts, and other visual parameters. You can also add new controls to existing pages as long as they do not require event handlers or other code. Code files are not deployed as source code, so you can't update the logic of the page without recompiling and redeploying the layout. Updatable sites won't save users from first-hit compilation delay when each page is accessed for the first time after a change is made.

    Note: Updatable pre-compilation in ASP.NET 2.0 is nearly identical to the compilation and deployment model of ASP.NET 1.1, in which.aspx files are deployed in source and all classes (including code-behind classes) are compiled to assemblies.

    Programmatic Precompilation:

    Site pre-compilation is also possible programmatically. The ClientBuildManager class exposes an API to invoke pre-compilation on an ASP.NET application. The aspnet_compiler utility itself simply creates an instance of this same class and works through its public interface. The method to start the pre-compilation is PrecompileApplication. The class constructors allow you to specify virtual and physical directories for the source and the target directory for the output. In addition, one of the constructors can accept additional parameters, such as pre-compilation flags and strong name attributes. All classes are located in the System.Web.Compilation namespace. An example follows:

    ClientBuildManagerParameter params = new ClientBuildManagerParameter();

    params.PrecompilationFlags = PrecompilationFlags.Updatable | PrecompilationFlags.OverwriteTarget;

    ClientBuildManager cbm;

    cbm = new ClientBuildManager(vdir, sourceDir, targetDir, params);

    cbm.PrecompileApplication();

    The PrecompilationFlags enum type is defined as follows:

    public enum PrecompilationFlags

    {

        AllowPartiallyTrustedCallers = 0x20,

        Clean = 8,

        CodeAnalysis = 0x10,

        Default = 0,

        DelaySign = 0x40,

        FixedNames = 0x80,

        ForceDebug = 4,

        OverwriteTarget = 2,

        Updatable = 1

    }

    That's it for today. Thanks for joining!!! See you tomorrow. We are done with the discussion of pre-compilation today and tomorrow we will start delving deeper into the overall ASP.Net compilation machinery :-).

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

  • <dw:daniel_walzenbach runat="server" />

    Wie optimiere ich Zugriff auf JavaScript (White Spaces, Kommentare, …)?

    • 0 Comments

    In einem ersten Schritt solle der JavaScript Code aus der Webseite in eine eigene Datei ausgelagert werden. Ist dies geschehen kann diese Datei vom Browser gecacht werden und braucht nicht bei jedem Zugriff erneut geladen werden. Überprüft werden kann das mit Tools wie Fiddler welche den HTTP-Traffic anzeigen und so aufdecken welche Dateien beim Zugriff auf eine Webseite wirklich abgerufen werden.

    Fiddler im Einsatz

    Fiddler Icon Referenz

    Danach gilt es die gerade erzeugte JavaScript Datei zu optimieren. Mögliche Optionen sind

    • Kommentare entfernen
    • White Spaces (Leerzeichen, Zeilenumbrüche, …)
    • Variablen kürzen

    Glücklicherweise gibt es Tools die diese Arbeit (zumindest das Entfernen von White Spaces und Kommentaren) übernehmen :-)

    Als Beispiel ein kleiner Codeschnipsel aus www.woistdaniel.de

    // JScript File

    // holds the Virtual Earth Map

    var map = null;

    function LoadMap() {

    if (map == null)

    {

    map = new VEMap('myMap');

    map.LoadMap();

    map.SetMapStyle('r');

    }

    }

    vs.

    var map=null;function LoadMap(){if(map==null){map=new VEMap('myMap');map.LoadMap();map.SetMapStyle('r')}}

    Vor der Optimierung: 223 Bytes,
    Nach der Optimierung: 107 Bytes

    Ersparnis: 52,02% :-))

    Schöne Grüße

    Daniel

  • <dw:daniel_walzenbach runat="server" />

    Tools für Webentwickler

    • 0 Comments

    Auf http://blogs.msdn.com/ie/archive/2007/06/22/from-microsoft-teched-2007-web-development-tools-for-internet-explorer.aspx findet sich eine gute Übersicht an Tools für Webentwickler. Besonders gelungen und unverzichtbar sind meiner Meinung nach die IE Developer Toolbar, Nikhil's Web Development Helper und Fiddler. Solange der IE8 noch nicht voröffentlich ist ;-) empfehle ich außerdem Firebug (echt ein geiles Ding!) wobei man sich dieser Lücke bewusst sein sollte…

    Daniel

  • <dw:daniel_walzenbach runat="server" />

    Die Einsamkeit im Web 2.0

    • 0 Comments

    http://www.alleinr.de/ :-)

    fast so gut wie http://www.kommandozeile.de/ ;-) (danke Frank)

  • <dw:daniel_walzenbach runat="server" />

    Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 3

    • 0 Comments

    Hi Everyone,

    After having seen the overall process models that ASP.Net can possibly run under, we will now discuss the components of the ASP.Net pipeline – steps that ASP.Net performs on each request before it serves its response, these don't differ based on process model. The process model just determines how the original request flows from the IIS gate into the CLR instance. Now, inside the CLR a pipeline of components act upon the request and actually processes it at each step.

    In general the ASP.Net request goes through several managed components and finally lands at a class that actually handles the request. The managed components that participate in the ASP.Net pipeline can do several things to the request – read and edit the request, access and add cookies, order browser redirects, check against cached content, perform validations etc. At the end of the pipeline, the request morphs into an instance of a class that represents the requested ASP.Net resource.

    Specifically in ASP.Net 2.0, this process has been significantly re-factored to involve several new components, most of which are customizable to various extents by developers.

    These components of the ASP.Net pipeline, we will now understand what they are. It's a bit easier to understand this concept saying that - the ultimate goal of the pipeline is to find a class that fully represents the requested ASP.Net resource. Note that if not found, such a class is created on the fly, compiled, and loaded in the AppDomain where the ASP.Net application runs. The components of the pipeline are as follows:

    Components of the HTTP pipeline:

    HttpApplicationFactory

    An instance of this class is responsible for returning a valid HttpApplication object that can handle the request. HttpApplicationFactory object maintains a pool of HttpApplication objects, and when invoked, it verifies that an AppDomain exists for the virtual folder targeted by the request. If the application is already running, the factory picks an HttpApplication out of the pool and passes it the request. A new HttpApplication object is created if an existing object is not available.

    HttpApplication

    A running ASP.Net application is represented by a dynamically created class that inherits from HttpApplication. The source code of this dynamically generated class is created by parsing the global.asax file and its code file. The HttpApplication object determines the class that represents the resource being requested – typically, an ASP.net page, a Web Service, or perhaps a user control – and uses the proper handler factory to get an object that represents the requested resource.

    Http Modules

    The HttpApplication maintains a list of module objects that can filter and even modify the content of the request. Registered modules are called at several stages of the request processing as the request passes through the pipeline. Built in Http Modules are responsible for steps such as authentication, output caching, session state management, user profiling etc.

    PageHandlerFactory

    The page handler factory creates an instance of an object that represents the particular page requested. Analogous factory objects will do the same for web service, user control, custom handlers.

    IHttpHandler

    The page object created by the page factory inherits from the System.Web.UI.Page class (or a class derived from this), which in turn implements the IHttpHandler interface. The final step accomplished by the ASP.Net runtime is calling the HttpHandler's ProcessRequest method on the page object. This call causes the page to execute the user defined code and generate the markup for the client.

    That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will talk about the page handler factory in detail and in coming days we will deal with the dynamic compilation of pages.

    Thanks,

    Sukesh Khare

    Coordinator Daily .Net Feed Program

Page 1 of 1 (22 items)