Building Re-Usable ASP.NET User Control and Page Libraries with VS 2005

One of the questions I’ve been asked a few times recently is whether it is still possible to build web projects that encapsulate common libraries of .ascx web user controls or .aspx pages with VS 2005 that can then be easily re-used across multiple other web projects (note: the quick answer is “yes").

 

This blog post walks-through how to easily accomplish this with VS 2005, as well as some of the new features you can take advantage of to make this scenario even better than before.

 

Quick Scenario Overview

 

The scenario I’m going to use to illustrate building re-usable page/control libraries in the below post is one where a development team wants to build a re-usable “ecommerce” web UI library that they can then re-use across multiple web projects and applications (note: if they are an ISV they will also want to be able to package it up and sell it).

 

The developers building this ecommerce web UI library want to provide two things:

 

1) Pre-built store-front UI pages (.aspx files) that provide catalog listings, shopping cart management, customer billing, and more.  They want developers using the library to be able to add a \storefront directory into their web project, copy this library of pages into them, and have ecommerce functionality incorporated within their application.

 

2) Pre-built strong-front UI user controls (.ascx files) that enable scenarios like current sales, current shopping cart items, and best selling product lists to be easily added to pages outside of the \storefront directory.  By encapsulating this functionality as user-controls, they want developers using this user control library to be able to easily add this functionality to any page on their site.

 

One condition the developers have for this ecommerce UI library is that no code-behind or C#/VB source code is shipped with the library.  Instead, they want to be able to easily package it up and deploy all code as compiled .dll assemblies.

 

For the purposes of the below walkthrough, I am going to assume that the development team building this web UI library wants to build-it as an isolated VS solution, separate from any web projects that might be consuming it (this seems to be the most common scenario I see when I talk with customers).  Note that you could also incorporate this library as part of a bigger solution that also contains web projects consuming it.

 

Step 1: Define the Re-Usable Page/Control Web Solution and Directory Structure

 

We want to cleanly encapsulate and maintain our ecommerce library solution.  To help with this I can use a straight-forward directory structure and VS solution architecture.

 

Specifically, I’m going to define an “EcommerceUI” directory underneath a “libraries” sub-directory in my source tree.  Contained within this will then be 4 sub-directories: a “myclasslibraryproject” directory to encapsulate the non-code-behind pieces of my library within a class library project, a “mywebproject” directory to encapsulate the web UI pieces of my library using a web project, a “mytestproject” directory to encapsulate the functionality testing of my library using a new VSTS test project, and a “buildoutput” directory which I’ll use to build and ultimately publish this library into (more on this later).  In addition to these sub-directories, I will define and store a VS solution file called “EcommerceUI.sln” underneath the root EccomerceUI library directory that defines the solution structure and cross-project relationships.

 

My resulting directory structure will look like this:

 

C:\sources\libraries\EcommerceUI\

C:\sources\libraries\EcommerceUI\EcommerceUI.sln

C:\sources\libraries\EcommerceUI\myclasslibraryproject\

C:\sources\libraries\EcommerceUI\mywebproject\

C:\sources\libraries\EcommerceUI\mytestproject\

C:\sources\libraries\EcommerceUI\buildoutput\

 

Note that VS 2005 makes it much easier to manage and store web projects outside of your inetpub and wwwroot directories.  This makes it possible to easily store web projects side-by-side with companion projects as part of a solution (like above).  I can configure the above web project directory to run using either the built-in VS file-system based web-server or using IIS directly.  For this particular solution, because I am not using any sub-applications or vdirs, I am going to be using the built-in VS 2005 web-server – which will avoid me having to register anything with IIS.

 

When I open up the solution defining the above projects using VS 2005, I will see a corresponding solution explorer view that looks like this:

 

 

One last note: I obviously don’t recommend calling sub-directories “mywebproject” or “myclasslibraryproject” – I’m using those names here only to add clarity about what each directory does. 

 

Step 2: Develop the Re-Usable Page/Control Web Solution

 

Once the above library structure is in place, obviously the next thing to-do is write the code and build it.  For the web project, this typically involves building one or two top-level directories to encapsulate the pages and user-controls of the solution. 

 

For our ecommerce solution I’m going to take the approach of defining a top-level directory called “storefront” that will encapsulate all of the content for our re-usable web project library.  Contained within the “storefront” directory will be the .aspx pages that make up our pre-built page functionality, as well as a “controls” sub-directory that will contain all of the .ascx user controls for the library.

 

 

A couple of things to note in the above solution:

 

1) In addition to the /storefront sub-directory above, I’ve added three test pages (testpage1.aspx, testpage2.aspx, testpage3.aspx) in the root of the web project.  I can use these for easily testing my library without having to first deploy it inside another web application.  I can also use these pages with the VSTS test project I have in my solution to host and then perform Web UI testing of the user-controls in the library (note: the VSTS edition of Visual Studio now includes a built-in web UI recorder that makes building ASP.NET UI unit testing easy).

 

2) I have a “site.master” master page file defined in the root directory.  Master Pages are one of the big new features of ASP.NET, and allow developers to define a common layout across pages within their application.  I can structure my EcommerceUI library pages (underneath the /storefront directory) to use a master-page defined outside of /storefront – which would allow the web application that is taking advantage of the EcommerceUI library to integrate it within their overall web application look and feel without having to modify the .aspx pages contained within /storefront.  If I wanted to I could even compile away the HTML within these /storefront pages so that the application couldn’t modify these – and was limited to only changing the masterfile or using the new ASP.NET 2.0 themes feature to integrate it within the site (this can make versioning dramatically easier, and avoid messy merge-hell scenarios when upgrading or deploying a new version of the EccomerceUI library).  Because Master Pages can be specified both declaratively and programmatically, the EcommerceUI library could optionally allow developers using the library to configure the exact Master Page they should use and then dynamically select this one at runtime.

 

3) I have a web.sitemap file defined underneath the /storefront directory.  Web.sitemap files are used by the new ASP.NET 2.0 Site Navigation system to define the logical scope and structure of a site layout.  Developers can then write code against the SiteMap API to get access to this structure and figure out where a visiting browser is within the site hierarchy at runtime, and/or can use some of the new built-in ASP.NET 2.0 UI controls like the Menu, Treeview and Breadcrumb Navigation controls to easily visualize it.  One of the cool things about the built-in XML Site Map Providers in ASP.NET 2.0 is that it allows you to partition the site definition across multiple files which can then be automatically merged into a single sitemap at runtime.  The web.sitemap file defined underneath the /storefront directory above would then contain only the site structure for the EcommerceUI library we are defining.  When added to a web application that had its own sitemap defined, the site structure we defined would be merged into that, and can show up in a menu defined on the Master Page of the entire site – without us having to-do a lot of extra work.

 

4) One of the goals we tried to accomplish in ASP.NET V2.0 was to provide a much richer framework for building web applications, and to build-in “building-block application service APIs” that provide a common model and framework for accomplishing core things like Membership, Role Management, Profiles, Personalization, Health Monitoring, etc.  One of the nice things this provides is a consistent way for components, controls and libraries to integrate and work better together.  For example: in our EcommerceUI example we could have our library use the new ASP.NET 2.0 Membership, Role Management, and Profile APIs – and as a result have our /storefront section of the web app integrate nicely with the rest of the application if they are using the same APIs.  Because these APIs are pluggable via providers, it also means that we don’t loose flexibility as a result (read http://weblogs.asp.net/scottgu/archive/2005/08/25/423703.aspx for more on how providers work and how they can be configured).  The end-result should be much richer code-reuse and flexibility of libraries with ASP.NET 2.0.

 

So what can’t I do within this web project library?

 

You can pretty much use all the same designers, code-editors and features when building a re-usable web project library that you can with a normal standalone web application.  Because you’ll be shipping and re-using the library within other web applications, though, there are a couple of things you’ll need to avoid:

 

-- Don’t define a global.asax file.  You are only allowed one of these per-application in ASP.NET, and so you don’t want to define one in your re-usable library.

 

-- Don’t define classes under app_code or service proxies under app_webservices.  Like global.asax, there are one of these each per application.  Code-behind class files are obviously fine inside the web project library and typically live next to their .aspx/.ascx equivalents.  Non-UI and business classes for the web project library should be defined within a companion class library project in the solution (for example: the myclasslibraryproject above).

 

-- Be careful about what you require in your root web.config file.  If possible, define applicationsettings and other configuration within the web.config file that lives underneath sub-directories (like /storefront above).  This will make re-using these web project libraries much easier and avoid having to write a setup program that does custom merge semantics.

 

Step 3: Building and Deploying the Re-Usable Page/Control Web Solution

 

Once you’ve built and tested your web project library, it is time to build and deploy it for re-use in other web projects.  There are a lot of new compilation and deployment options introduced by ASP.NET 2.0 and VS 2005.  In particular, there are two big new decisions that developers can now make:

 

Decision #1) Whether to preserve the HTML + Server Control markup when deploying a web project (which is what VS 2003 does today), or whether this should be removed as part of the compilation process and compiled directly into the generated \bin assemblies.  The benefit with the first approach (preserving the html) is that it allows later modification of the markup without having to re-build the project (hence the reason we call this the “updatable” build option in dialogs you’ll see below).  The benefit with the later approach (compiling the mark-up out) is that it allows ASP.NET to avoid having to ever parse and compile the .aspx file at runtime – which can dramatically improve the first-load/first-request performance of the application.  It also allows ISVs to better protect their intellectual property and hide their HTML and server control definitions.

 

Decision #2) How granular the deployed assemblies should be.  Specifically, VS 2005 + ASP.NET 2.0 now by default compiles your web project so that each separate directory of .aspx/.ascx content compiles into a separate assembly.  For even more flexibility, you can also optionally choose to compile each .aspx or .ascx file into its own separate assembly (this option is called the “fixed name” option because it also results in assemblies whose names are fixed across multiple compilations).  The benefit with this later approach is that you can now deploy individual updates on your system without having to re-build and update your entire site.  It can also sometimes make deploying web project libraries much easier – because it allows you to copy and deploy just those .ascx user controls and associated assemblies that you want out of the web project, without having to grab everything.

 

Note: one request we’ve heard from several people since Beta2 has been to provide a new third compilation granularity option above which would allow you to merge the assembly output from multiple directories into a single assembly that has a well known name that you define (and which does not change across re-builds – which is one unfortunate side-affect of the per-directory build option today).  We are working on a tool right now that does this, and have a prototype up and running that seems to work great.  I’ll provide more details on this over the next week or two once we confirm that it fully works for all scenarios.

 

There are two ways I can easily build and deploy my solution: a) from within the VS IDE, or b) from the command-line using MSBuild.

 

Building and Deploying the Web Project Library from the VS IDE

 

To build and publish/deploy my web library solution within the Visual Studio IDE, I can go to the “Build” menu and select the “Publish Web Site” option.  This will bring up the “Publish Web Site” build dialog which provides me with the various deployment/compilation options on how to build the site:

 

 

For this walkthrough I am going to use the default “updatable” option (meaning the HTML + Server control markup is preserved), and select to have individual assemblies created for my .ascx and .aspx files.  The reason for selecting the individual assembly option is because I want to be able to remove the compiled code for the root test pages and master templates that I am currently using to test my store-front library, and want to have the flexibility to update these assemblies on a more granular level in the future. 

 

Note: For simplicity sake in this walkthrough I’m going to only describe one deployment combination (specifically I’ll use updatable html + individual compiled assemblies).  I could have just as easily picked another (for example: fully compiled html + per-directory assemblies).  You as a developer are allowed to pick whatever you feel is most appropriate for your particular web library deployment scenario.

 

When I click the “ok” button, VS 2005 will compile all three projects (myclasslibrary, mywebproject, mytestproject) and then deploy the classlibrary and webproject into the “BuildOutput” directory we defined earlier under our c:\sources\libraries\ecommerceUI\ directory.

 

 

Note that the .aspx/.ascx files will remain (because they still have .html/server control content defined within them), but all code-behind files are now gone – since they have been compiled into assemblies underneath the \bin directory.

 

Building and Deploying the Web Project Library from the VS IDE

 

To build and publish/deploy my web library solution from the command-line (without having the VS IDE loaded or potentially even installed on my machine), I can take advantage of the new MSBuild support that ships with VS 2005 and .NET 2.0.  There is *a lot* of richness in MSBuild – easily 20+ blog entries worth.  I’m going to only show a super basic (but still pretty useful) way to use it below with web projects.  I’ll blog some more about it in the future to go into some of the more advanced ways you can use it with web projects.

 

To configure basic MSBuild options with my web project library solution, I can right-click on my web project in the solution explorer and select the “Properties” menu item on the context menu.  This will bring up a configuration dialog for the web project, and allows me to configure lots of different things (start pages, references, accessibility compliance checker, etc).  If I click on the MSBuild tab I will see the below options:

 

 

Once I have configured the MSBuild options this way, and hit “save all” to make sure the solution is up-to-date (note: I always forget to-do this), I can now perform command line builds on my solution.

 

MSBuild.exe is installed underneath the framework redist directory (c:\windows\microsoft.net\framework\v2.0.xyz).  If this was on my command-line path, then I could simply type the below command to kick off a command-line build:

 

 

This would then generate the below console output and produce the exact same bits we did before using the IDE:

 

 

Obviously this is a very simple command line build scenario – but I could compose additional MSBuild rules to make this much richer (including adding additional steps to copy the appropriate files from the produced library into multiple projects).  MSBuild has a custom task called “AspNetCompiler” that can also be used to declaratively author custom MSBuild scripts from scratch.

 

Step 4: Using the Page/Control Web Library within a Web Application

 

To use the EcomerceUI library we just created inside a new web application in VS 2005, I need to-do two things:

 

1) Copy the appropriate .aspx/.ascx files from the built EcommerceUI solution into my new web application project directory.

 

2) Copy the appropriate .dll assemblies from the built EcommerceUI solution into my new web application project’s \bin directory (note: I could either copy these manually or as part of an automated build process, or have a CopyLocal reference setup to auto-refresh these assemblies when new versions get built and deployed under the EcommerceUI solution).

 

Here is what my blank web-application will look like when I copy the above items into it:

 

 

Note that because I’ve built using the option to generate separate assemblies for each control/page, I end up having several granular assemblies in my \bin directory.  Note also that this allowed me to remove all of the testpage assemblies I was using within the web project to verify things.

 

I can then go ahead and build my web project and take advantage of the Ecommerce UI library.  I can add whatever pages I want into the project and integrate them around the /storefront subdirectory.  I can also use the user controls from /storefront/controls on any page within the site.

 

Here are two screen-shots of this in action with VS 2005:

 

 

Note in the above screen-shot how the catalog page we defined within the EcommerceUI library picks up and integrates within the custom Site.Master masterpage file we defined at the root level within this new web project.  It shows up both in WYSIWYG in VS 2005, and obviously also at runtime.

 

Also note the treeview control on the left that is defined within the master page in our new web project as well as the bread-crumb control that is defined within the catalog.aspx page of the EcommerceUI library.  Both of these new ASP.NET 2.0 controls are binding against the new ASP.NET Site Navigation system – and are showing a consistent site hierarchy view of the overall web solution regardless of whether they were used inside the storefront or outside of it.  This view shows up consistently both at runtime and also at design-time in VS 2005.

 

 

Note in the above screen-shot how the wishlist.ascx user-control from the /storefront/controls directory shows up in WYSIWYG on the default.aspx homepage defined at the web project root.  With previous versions of VS user-controls were rendered as grey-boxes – now developers using the ECommerceUI library will be able to see the actual representation of the user control content they’ll see at runtime.  VS 2005 also now provides strong-typing and intellisense against the usercontrols when writing code-behind code for default.aspx (previous versions of VS declared these controls by default as type-less usercontrols). 

 

Note that as I’m building my new web project I can regularly run (just do a standard F5 or Ctrl-F5 to run the web project).  When I’m finished I can also then do a “Publish Web” or command-line build operation on this new web project and solution, and generate a completed web application with EcommerceUI library included that is ready to deploy.

 

Hope this helps,

 

Scott

52 Comments

  • Scott,



    Two questions arise from this.



    1. I thought the App_Code was where you were supposed to put shared code (source or binary). Why did you choose to put the DLLs into the Bin folder rather than App_Code? A follow on to this, if you used non-updatable compile you would not have had to copy the aspx/ascx files, correct? If so how could you reuse the ascx controls?



    2. Does the default sitemap provider allow cascading files, i.e., can one sitemap file refer to another. This is how our modular menuing system currently works.



    Thanks,

    BOb

  • Timo,



    Why would you not put your shared libraries in the GAC? That is exactally what it is there for.



    Also, I think Scott above showed that he used using your option B (copying my DLL to every single bin-directory in my directory tree). These Dlls/Files would have to be copied to each application that used them.



    BOb

  • Scott,



    Thanks for this excellent article but I have a question for you. Why do you guys like this command-line thing so much? :) Isn't it time to get rid of it? I was just trying to use aspnet_regiis this morning and was wondering why we were still stuck in the "middle ages". ;-)



    Regards,

    J.S.

  • Hi J.S.



    We try to have both IDE/GUI and command-line support for everything (that is why I showed both above).



    IDE/GUIs ceretainly make things more approachable and discoverable, and for most scenarios can be a lot more productive.



    Command-line support is very useful, though, for highly automated scenrios -- especially for enterprise builds. That is why we are spending a lot of time in VS 2005 and ASP.NET 2.0 making sure we have a rich story here.



    Hope this helps,



    Scott

  • Wouldn't it be nice if there were a way to do this without having to copy .ascx and .aspx files around?



    Admittedly the non-updateable build option in VS2005 makes the story here much better - you only have to re-copy the files when new ones are added, and not on every change. But it would be really nice if you could just "reference" a project containing .aspx's and .ascx's and somehow use them directly...



    You mentioned you're working on a tool that will cause the entire project to be built into a single assembly with a predictable name. I wonder if that will be the killer feature for me that allows .cs files outside of App_Code to still be usable? If everything's going to the same assembly, everything can see everything else...



    I do have one question, though: in this tool, will it be possible to *exclude* particular folders so that those get compiled using the per-file or per-folder assembly models? I have a particular subfolder that contains .aspx and .ascx files that actually sometimes get written by code at runtime, and I'd prefer to avoid the entire project getting recompiled every time that happened.

  • Scott, in response to your reply to Bob:



    I'm a little confused as to what the non-updatable compile option does. I thought that it compiled everything into the dll but the aspx and ascx files were still needed for path mapping purposes, so a "stub" file got created instead.



    If in fact the aspx and ascx files aren't needed at all in that scenario, do you actually need to create stub files at all? Can you deploy with just an assembly in bin/ and a web.config file (plus images and other static files)?



    Thanks,

    Stuart.

  • Hi Stuart,



    The good news is that you can now actually do it without having to have .ascx and .aspx files (this wasn't possible with VS 2003 and ASP.NET V1.1). The trick is to compile without the "updatable" checkbox selected -- this will then remove all the .ascx files, and leave only stub files for the .aspx ones. These stubs are there so that you can set NT file ACLs on resources -- but you can remove them if you are just using URL authorization instead (which is what most people do).



    Unfortunately the tool I mention won't directly allow you to store non-UI .cs files next to your pages -- these would still need to live under the app_code directory or in a separate project. What you *could* do though is partition your application into multiple sub-apps using the approach described in my blog-post above. That way the app_code would live relative to your content tree. There is then a trick that I can show you using the new tool I mentioned where I think it would be possible to deploy these app_code assemblies.



    On the last point regarding excluding some directories -- you won't have any problem writing to a folder underneath your project at runtime. This will only cause compiles in that directory -- it would not force the entire app to be recompiled.



    Hope this helps,



    Scott

  • Hi Stuart,



    [This is in response to your second post -- which I didn't see before responding to your first one]



    When you do a non-updatable compile the .ascx files are removed by default. There are then stub .aspx files that have a "these are placeholder" files text inside them. These are purely to allow you to optionally set ACLs. If you want, you can remove them entirely.



    I'll try and do a blog about this at somepoint in the future since several people have asked about this.



    Hope this helps,



    Scott

  • Hi Scott,



    Thanks for explaining the importance of command-line support. I knew there had to be a reason for it; I just didn't know what it was till I read your response.



    You mentioned that you try to provide IDE/GUI support as well and I would have liked to ask if such support was available for encrypting parts of web.config files in VS 2005 but it's probably off-topic so I'll take it up on another forum.



    Thanks,

    J.S.

  • Scott, thanks for the clarification. The ability to not have aspx and ascx files at all is a big plus, and might actually make it possible to set up our product as multiple projects all of which get referenced into a single solution.



    Did you see my newer comment to the previous blog post (asking for more details about App_Code and how it interacts with build providers)? That explains why I'm still not clear on what exactly is going on with .cs files outside of App_Code.

  • Hi Scott,



    Do you mean the ASP.Net 2.0 Configuration Settings or the MMC admin tool in the Longhorn server?



    Thanks,

    J.S.

  • Hi J.S.



    The ASP.NET MMC Snapin for IIS5 and IIS6 that ships as part of ASP.NET 2.0 will support reading/writing encrypted settings (although i think you need to first manually encrypt them -- once encrypted though the GUI will full respect them).



    The IIS7 MMC in Longhorn will also then add support for encrypting values directly in the tool.



    Hope this helps,



    Scott

  • Hmmm... has this stub scenario changed since beta 2? If you removed the stub file in beta 2 you'd get an error.



    I'll be interested to see how this compiler tool works out.



    Without this tool I don't think any vendor would deploy their application as a bunch of semi-randomly named assemblies as the ones above generated by the compiler now. Imagine if you're a user and you have two such solutions - what a mess that would make of your BIN directory. The imagine an update... Ugh <g>.



    You say that without the ASPX files it still works except ACL rights. Is there any way that ASP.Net could still pick up directory level validation? Guess not without a file...



    The stub files are not a big issue as long as there's an easy way to do a repeatable build that doesn't produce one file per assembly plus the marker files.





  • Hi Bob,



    What about the scenario where I don't have any access to GAC, for e.g. in hosted environment ? Also I would find it much more convenient to copy the needed file just to one location and just reference to that file from other applications. If I have ten apps that use the functionality, copying the file to ten locations is cumbersome instead of just copying it to one place. Maybe I'm missing something crucial here, just wanted to figure out if this is possible in the first place.


  • Hi Scott,



    The ASP.NET MMC Snapin looks pretty good.



    Thanks,

    J.S.

  • Timo,



    Have you tried to add a <probing> Element in your web.config to do this? Of course, that will only work in the folder is a subfolder of you apps base.



    I think you can also do what you want using reflection to load the assembly into the app domain.



    BOb

  • This is a question to Scott. I'm using the August CTP and when I do a build on my web app, the System.Windows.Forms assembly reference gets automatically added in my web.config file. Why is this happening? I don't have classes in my web app referencing the Winforms assembly, but I do have some third party dlls in my bin that I am not sure of if they reference Winforms.

  • Hi Vurg,



    The behavior you are seeing is pretty weird -- I really don't have a good idea why that would be happening.



    Can you send me email at scottgu@microsoft.com describing the exact scenario more and what you are doing? Are you seeing this happen when you create a new web project? Or when you add a specific item to it? Or when you add a reference to another component?



    Thanks,



    Scott

  • Hi Rick,



    I just tried removing the stub files on two machines here and it worked just fine. One thing for you to check is that the ISAPI script-mappings for ASP.NET do not have the "check if file exists" selected for .aspx files -- if so then you'll get an error if the stub files are removed.



    You do also need to have the directory structure in place on your site for the .aspx files -- because otherwise IIS will not map default.aspx files correctly to the ASP.NET ISAPI. Maybe this was what you were running into?



    Hope this helps,



    Scott

  • Hi Stuart,



    You can register build providers for any file extension type -- so for example you could have a .ORM file be an XML file that defines an Object Relational Mapping schema and drop it into your app_code directory, and then have an OR class automatically be compiled as part of your assembly. It ends up being a pretty powerful way to express declarative types without having to-do tons of code-generation into a file.



    I am working with someone who built the BuildProvider architecture to come up with some samples that either he (or I) will blog somepoint soon that should show how to build these and do some cool scenarios with them.



    Hope this helps,



    Scott

  • Scott, my specific question is whether I could register a custom build provider for .cs that simply caused the C# file to be compiled...

  • Hi Stuart,



    Unfortunately you can't do this outside of the app_code directory I'm afraid. :-(



    Sorry,



    Scott

  • A very useful article.



    I have already posted some info on the new page model that needs to be borne in mind, and is repeated here.



    You cannot add another code file or re-build the deployed project, but you can add server side scripts.



    If you intercept "code-behind" events in a server side script in the deployed file (e.g. Page_Load), then you should call the base class so that it can perform its processing, otherwise unexpected issues and/or exceptions will occur.



    You can also add useful properties, methods, and events in the source aspx pages whhich can be picked up by deployment developers.



    Another tip. If you need custom methods and properties on controls such as a TextBox, create your own custom web control based on a TextBox and add your own properties, etc. These properties can then be set in the HTML script just like the standard ones such as ID, Width, etc.

  • Hi there,



    I am attempting to use the pre-compiled page model, I am finding that IIS is in fact serving up my placeholder files rather than using the referenced dll.



    Is there any setting required? I note a PrecompiledApp.config file but it's presence (or lack-of) in the client project doesn't make a difference.



    Cheers,



    Adam.

  • I'm a little confused at how you would use a library of user controls in another project without having the .ascx files present. I've been able to load user controls in the designer as well as dynamically from the library as long as the .ascx files are present. When deploying into another project and having the build flagged to not allow updating, therefore having no .ascx files, how do I get the user controls from the library into a page either with the designer or programatically?

  • Hi Chris,



    ASP.NET can resolve the .ascx references at runtime without them actually being present on disk. If you want WYSIWYG designer support, though, you will probably need to use the "updatable" compile option -- which will leave them there on disk.



    Hope this helps,



    Scott

  • Hi Adam,



    If you are finding that IIS is serving up the actual placeholder file content, then it is likely that your app is not configured to use ASP.NET V2.0 -- and is instead using ASP.NET V1.1 (which doesn't understand the precompiled concept). I'd recommend verifying that you have the correct version set in IIS.



    Hope this helps,



    Scott

  • We are using third-party controls (Infragistics) that are installed in the GAC.

    We are not using all the controls in the package so we just want to deploy the specific dll that is required based on the application reference. Are we forced to install the whole Infragistics suites in the web server since I don't see any option to copy the dll locally to the application?



    Raul

  • Hi Raul,



    You could do one of two options:



    1) Install in the GAC and reference it from there (ideal if you are using the controls in several different applications).



    2) Use the copy local option that is supported in the RTM version of the product (it isn't there in Beta2 - but is there in RTM). This gives you the ability to refresh the assemblies in the \bin directory on your dev boxes which would allow you to deploy the ones you need.



    Hope this helps,



    Scott

  • Hi Scott



    This looks like a very useful concept and this article is a good primer for this kind of mode of working.



    However I have hit one problem, as an expermient I tried moving some classes I had already created into a Class Library project and immediately hit a problem wherever I've used httpcontext or server.mappath etc



    For example I have business logic which access files/folders in a directory and one part of my code is to use server.mappath to convert the filenames etc.



    In a scenario like this I obviously need to move that code somewhere else (back into the original Web Project?) but what do I do then if I can't have classes in the app_code folder?



    Any ideas?

  • Hi again



    Another query, this time about app_theme folders.



    Is it possible to use themes in the MyWebProject in this example?



    If not, how do you handle themes, obviously you can define them in the Site that employs this generic site, but what about SkinID's etc, can you still make use of them in this example?



    Regards

    Jon

  • Hi Jon,



    You can continue to have your code in a class library project. To access HttpContext and things like server.MapPath you need to-do two things:



    1) Make sure your class library project has a reference to the System.Web.dll assembly.



    2) Access the context object like this:





    System.Web.HttpContext context = System.Web.HttpContext.Current;



    You can then reference objects like Request, Response, and Server off of this local context reference.



    Hope this helps,



    Scott



  • Hi Jon,



    To use themes you'll need to copy them to the main app's app_theme folder. Ufortunately there isn't a way to just store in underneath the sub-folder for the web project library.



    Hope this helps,



    Scott

  • Good article !!



    Can you explain the difference between User control & Custom Control?

    What are those used for? etc...

  • Hi Ami,

    User controls are controls in ASP.NET that are built using a .ascx file for the view.

    Custom controls are controls in ASP.NET that are built by writing source code that derives from a control base class.

    Hope this helps,

    Scott

  • Hi Ashok,

    I cover how to create a re-usable user control library in this tutorial here: http://webproject.scottgu.com/CSharp/UserControls/UserControls.aspx

    I'd also recommend checking out this blog post here: http://weblogs.asp.net/scottgu/archive/2006/08/16/Tip_2F00_Trick_3A00_-Creating-Sub_2D00_Web-Projects-using-the-VS-2005-Web-Application-Project-Option.aspx

    Hope this helps,

    Scott

  • Hi Scott,

    I've followed your instructions, and I have to say, wow! This is mind blowing stuff.

    However, I would like to uncheck "Allow this precompiled site to be updatable". When I do this, I get the stub .aspx pages.

    Then if I create a link in my consuming application it displays the stub file rather than showing the actual file content.

    How do I create a link (like <a href="...") to an aspx page inside the control library?

    Thanks,

    Glen

  • Hi Glen,

    I think you will need to keep the "allow this site to be updatable" option selected to make the above scenario work. Unfortunately I don't think we support having part of the site be updatable, but not other parts. Note that when you have this option checked, your code-behind code will still be pre-compiled. It is just the stub .aspx files that will still have html source in them.

    Hope this helps,

    Scott

  • Hi,

    Are usercontrols compiled into the application at build time or are they dynamically loaded at run time. When we hit the loadusercontrol statements for the first time the application is really slow, but once loaded the application performs as we would expect.

    Thanks
    Rich

  • Hi Richard,

    User controls are dynamically loaded -- so the first time you call LoadControl ASP.NET will parse and compile the .ascx file.

    The result of this compilation is persisted on disk - so even if the app restarts it shouldn't needed to be compiled again.

    Hope this helps,

    Scott

  • Hi Scott,

    We experience the problem when we first access the page and also when we clear the cache. Are you saying that every time the page is first visited the usercontrols will be retrieved and compiled - we have experienced delays of 20+ seconds which obviously would not be acceptable. Is there anything we could do to speed this up or should we move the usercontrols into the application.

    Thanks for your help.
    Rich

  • Hi Richard,

    No -- you shouldn't see this everytime you first visit the application. A user control is only compiled the first time it is accessed. From that point on it is saved on disk and doesn't need to be compiled.

    20 seconds also sounds like a long time for compilation to occur. Are you doing anything else on the usercontrol when you first load it? Do you store something in the ASP.NET Cache?

    Thanks,

    Scott

  • Hi Dave,

    It is pretty hard to read the code above (unfortunately it also caused some problems with the html so I had to delete it). If you want to send me via email a simple .zip file with a sample I can take a look and try to help.

    Thanks,

    Scott

  • This works for me if I use the 'updatable' option and copy the .aspx into the webapp, but I can't figure out how to get it to work with the 'updatable' option turned off. I have one page (TestPage.aspx) that's compiled into my assembly and the assembly is in my bin directory, but how do I refer to the page in my webapp that's using the assembly? How do I create a link pointing to it for example...thanks!

  • Hi Scott. I am having a similar problem to a previous comment. This all works fine if I include the separate .ascx file. However, as soon as I set the build flag to not allow updating (which as a consequence does not create a separate .ascx file), I cannot get it to work. Your previous response was that ASP.NET can resolve the .ascx references at runtime. How do you register the control? without registering it, compilation fails.

    Thanks in advance

    Curtis.

  • Hi Curtis,

    What I'd recommend is for you to have the user-control project be marked as updatable, and copy the .ascx file into the consuming project.

    You could then compile the consuming project as non-updatable. This will then remove the HTML for both the pages on the site, as well as the user-control you are using.

    Hope this helps,

    Scott

  • Hi there,

    thanks for this great article. I am a newby to ASP.NET 2.0 and still have one question. For my project I want to use only on masterpage for all websites. Therefore I build an .dll with my mainMasterpage as you described. In another WebSite I tried to set the MasterPageFile attribute of the @page directive from my .aspx-file to my mainMasterpage. But this didn`t work. Can you tell me how to access my mainMasterpage?

    thanks in advance

  • It amazes me that after 5 years of .net and 2 major versions that support for the reuse of pages and user controls under ASP is still so awkward. In Windows Forms you create a control in a standard class library, set a reference to the project from another project, and use it. The idea that you have to copy aspx or ascx files seems like a step back to the old &#39;cut and paste inheritance&#39; days. If you are copying the ascx file you still have the problem of when it changes you have to go round all the consuming projects and change those too. Does that sound like reuse to you? Even setting references to dlls is not ideal, project references are just so much easier to manage. This really does have to be sorted out in the next release.

  • I'm fustrated that you 'claim' to be able to reference user controls from a library built with the build flag set to not allow updating, but then when asked how to reference the control in a consuming application you fall back to 'just build it as updatable, yet build the consuming application as not updatable. I've spent a bunch of time trying to get user control references to work from a compiled reference with no success. Please come clean and tell us if it's possible or not. And if so, please provide an example.

  • Hi Steve,

    Any chance you could send me a .zip file with a simple repro of the problem? I can then try and have someone take a look at it.

    Thanks,

    Scott

  • Would this work to package a master page, along with some custom controls, to be placed at a web site's root\bin directory and share it with all sub-applications as well? Or would the compiled DLL need to be placed in the BIN dir for EACH sub-application?

  • Hi Diego,

    I believe you'd need to copy the DLL into each of the sub-applications as well.

    You might want to check out this post as well on how to partition an application into multiple sub-applications: http://weblogs.asp.net/scottgu/archive/2006/08/16/Tip_2F00_Trick_3A00_-Creating-Sub_2D00_Web-Projects-using-the-VS-2005-Web-Application-Project-Option.aspx

    Hope this helps,

    Scott

Comments have been disabled for this content.