Web Projects and .NET 2.0

I’ve spent a frustrating day (again) attempting to setup a web project that is a sub-project of our main application. For whatever reason, I can’t reference code in a referenced assembly unless I load it as a control reference and, at least in most cases, copy the referenced assembly to the main /bin folder.

Works like this:

  1. NetQuarry is installed. The core assemblies are in the <webroot>/bin folder.
  2. The application needs some custom controls (mostly for wizard pages).
  3. The application wants to reference another custom assembly. To do this, we copy the assembly to the /bin folder of the new project. We include the reference and we can use the code in the debugger.
  4. The application’s new web project is installed and developed in a sub-folder of NetQuarry. (<webroot>/Apps/<myapp>).
  5. The code compiles, but you can’t load any of the custom controls because it can’t resolve the type.
  6. On most machines (I can’t tell you why this isn’t all machines) all you have to do is add a reference in the .ASCX page like this:
    <%@ Register TagPrefix=”myappref” Namespace=”MyApp.Common” Assembly=”MyApp.Common” %>
  7. On other machines, you have to copy the referenced assembly to the root /bin folder.

Incidentally, I’ve tried the new Web Application Project model to solve this and failed as well. Scott Guthrie has a good post about it: Web Application Projects that you should read. The (really) good news about this new project model is that it compiles significantly faster. The bad news is that I have a similar reference problem when I try to create a web user control dynamically unless the assembly is copied to the <webroot>/bin folder.

So, why not just copy the sub-project .DLLs to the main /bin folder? Because I really don’t like it. In NetQuarry, sub-projects are loaded dynamically (a somewhat foreign concept to everything ASP, I know) and they don’t have a dependency on the main NetQuarry Web assembly. The idea is that one installs the core NetQuarry web, then builds their own web components (web user controls), references them as components using the NetQuarry Studio and uses them as PageElements to build wizards.

NetQuarry also loads extensions dynamically, which is exactly what we want to do with these web projects. So, I tried converting to the new Web Application Project model for sub-projects and loading the assemblies dynamically. Still didn’t work. Since these are web projects, you would think that the way to do this is in two steps: first, load the assembly, and second, load the user control via its virtual path. Once the assembly is loaded .NET should understand the types in the control but for some reason it doesn’t.

The idea behind NetQuarry is that you don’t have to know any of this stuff, but just so you know, the idea (that doesn’t work) is like this:

private IWizPage LoadWizardPage(NetQuarry.ComponentInfo ci)
    System.Reflection.Assembly asm = ci.LoadAssembly();
    return LoadControl(ci.Component) as IWizPage;

Where the ComponentInfo.LoadAssembly method is a little complex (and ommitted here for brevity). Basically, we try and find it in the list of loaded assemblies first, then in the specified path, then in <webroot>/bin, and finally in Apps/<appid>/bin.

Turns out that after you load the assembly, the component still doesn’t load. So we’re still discussing this. Perhaps I’ll break down and have custom projects deployed to the <approot>/bin folder, but I sort of doubt it. As ususal, it feels as if we’re the only ones solving this problem, but I did find this post from over a year ago (Dynamic LoadControl of ascx with dll not in bin path) and there is a response there (from a DevelopMentor staffer) that says: “ASP.NET mandates implicit loading of assemblies from ~/bin or the GAC. You can always call Assembly.LoadFrom, but I’m not sure if the LoadControl will work with that. It’s worth a try.”

I nearly refused to believe it, but after about 2 bad days on this, I’m convinced. Love to know why, Microsoft, anyone?

For now, we are leaving it alone and leaving the hacky @Register business in place.

We did, however, convert our main project (EAP.WebHost) into the new model and boy oh boy is it better.

NetQuarry and OptionEase

COSTA MESA, Calif. – March 17, 2006 – NetQuarry, Inc. announces that its NetQuarry Enterprise Application Platform has been selected by OptionEase, Inc. of San Juan Capistrano, California, as the development platform for its new OptionEase application.

About NetQuarry

NetQuarry develops and licenses the NetQuarry Enterprise Application Platform. The NetQuarry platform helps professional software development teams develop significantly better enterprise and hosted applications.

NetQuarry is privately held. For more information, call (714) 881-4574, email info@netquarry.com, or visit our website at www.netquarry.com.


We’ve spent a bunch of time solving the problem of vocabulary lists for a database application. A vocabulary list is one of those tables that have a key (typically an integer or a GUID) and some text. The “key” (primary key in DBMS-speak) is referenced by a column in a more important table. Most of the time, the end-user selects this key by choosing an item via a drop down list box that has some human readable text and the application stores the item’s “key” into the database. We call the object that solves this problem a Picklist.

Normally, you solve the problem by creating a 2 column table with a key and some descriptive text. For example, say you wanted to have a status table:

Table: status

StatusID StatusText
1 Open
2 Closed

You might get a stab of reusability and conclude that a good idea is to store these sorts of things in a table that has a type and therefore keep yourself from having to create 300 of these tables in your database. So, the table might look like this:

Reusable design: picklist

id description list_type
1 Open status
2 Closed status

Now, all you have to do is change the SELECT statement and you can have one table to handle most everything. Next, you bump into a requirement where you have to store something besides and integer as the key (say, its data that you didn’t own and the key is some cryptic string). No problem, you just add another column to this list with an alternate ID (or another table, I suppose) and indicate that somehow.

2nd try: picklist

id text_id description list_type
1 OP Open status
2 CL Closed status

Next, you decide that some of the items in this list are required to be shown, but you don’t want the user to select them. So you add another column to the table and indicate which items are disabled.

3rd try: picklist

id text_id description list_type disabled
1 OP Open status 0
2 CL Closed status 0
3 PO Nearly Closed status 1

At this point you’ve thought of several more interesting requirements so your table design ends up with several more columns to support these:

  • Localization. If you plan to support a multi-lingual application you are very likely to need to have your vocabulary displayed in the user’s culture.
  • Readable string as a way to lookup an ID. The common case for this is when you want either to set a default value in a field but do not want to hard code some opaque primary key values in your code or you want to take some action based on the value that a user chooses and you don’t want to hardcode the primary key value.
  • Caching (or not) the items in the list. If you are going to model this, you’ve likely decided that you need to metadata tables – Picklist (for the name of the list and some attributes like “cache”), and PicklistItems (for the actual items).
  • Discrimination. Often you’ll have a requirement where the value in one column filters (or discriminates) the potential values in another. For example, you may have a list of vehicle make types in one list and based on the selection, you need to show the available models in another. The typical way to solve this is to take the value from the first control, post the results to the server, dynamically determine the new SELECT statement, and return the page with the second control filtered.
  • Two-way lookup. Often you have the value of the item’s key only and you need to find the text, but we have found that you just a frequently need to do the reverse (e.g. you have the text and you want the key). We use the reverse lookup, for example, when searching or filtering in a list – the user enters “Open” and we search for “1.”

The next issue you solve is how to fill the controls with the contents of these lists. The most straightforward method is to write code to open a DataReader with a statement like (SELECT id, description FROM picklist WHERE list_type = ‘status’) and add these items to a DropDownList control like this:

while (dr.Read())
    listControl.Items.Add(new ListItem (dr.GetString(0), dr.GetInt32(1)));

Or, a better way is to bind using the DataBinding features of the DropDownList– something along these lines:

DataTable dt = CreateTableFromPickListSQL();
dropList.DataSource = dt;
dropList.DataTextField = “id”;
dropList.DataValueField = “description”;

In both cases, you are responsible for creating either the DataReader or DataTable and properly disposing of it. Most folks know how to do this, or at least they know how to cut and paste some code somewhere that does it reasonably well. It’s still a pain and generally isn’t written in such a way to promote even moderate reusability.

Another consideration is that you may need to use one of these lists for something other than as a DataSource for a DropDownList control. For example, if you are displaying a table of data that has several columns which are foreign keys to your picklist table you either must create some sort of view to resolve these or do a lookup as you fill the list (this is almost never an option for performance reasons). The trouble with the view is that unless you strictly enforce the integrity of your data you are likely to lose some rows because the values in your main table have foreign key values that are invalid.

There are a bunch of other factors, of course, which is why there is a dedicated object to solve this problem. Again, a Picklist represents a domain specific list of values that can be used to translate the key of an item (typically a foreign key in a database table) to a description.

In the NetQuarry Platform, Picklists are of one of three distinct types:

  • A “standard” Picklist. This type of list is loaded from the metadata and supports the descriptive text in the current user’s culture (language). We use a pattern similar to the one just described to model this. (Picklist, PicklistItems (with a foreign key to a “Text” table to support localization))
  • A “SQL” Picklist. This type of list is loaded from one of the databases (can be the “main” operational database or the repository) and can contain 1 to 3 columns of data.
  • An “Enumeration” Picklist. This list is a 2 column Picklist loaded from a string type name that represents an Enumeration as its source. (The NetQuarry Studio makes good use of this.)
  • For the most part, Picklists tend to have the LimitToList attribute set. This attribute says that the item selected by the user MUST be one of the items in this list. There are several other attributes of interest as well, listed here and briefly explained:


Member Name Description
Cache This list should be cached.
HasDiscrim This list uses a discriminator to break items into sets.
LimitToList This list has at least 2 columns and the values must come from the list.
HideUnknownItems The list should hide unknown items.
MarkUnknownItems The list should mark unknown items.
StoreAltText The list stores the item”s Alternate Key Text column in the DB and uses it as it”s ID.
StoreAltInt The list stores the item”s Alternate Key Int column in the DB and uses it as it”s ID.
StoreItemName The list stores the item”s Name column in the DB and uses it as it”s ID.
NoNullEntry The list does not need to provide a null entry.
SortByText List should be sorted by the display text.
SortDesc List should be sorted in DESC order. (Standard Picklists only)
SortByKey List should be sorted by the stored key.
AllowUserAdd Users can add new items to this list (providing they have Configuration permission).
AllowUserDelete Users can remove items from this list (providing they have Configuration permission).
AllowUserUpdate Users can update items in this list (providing they have Configuration permission).
Disabled The picklist is disabled.
IgnoreWhitespace Ignore leading and trailing whitespace when matching values.

Mission Pharmacal Case Study

This document outlines the use of the NetQuarry Enterprise Application Platform to rapidly build a web application to manage the medical meeting (“Trade Show”) process for Mission Pharmacal. Mission Pharmacal (http://www.missionpharmacal.com) is a privately held pharmaceutical manufacturer headquartered in San Antonio, Texas.

Mission Pharmacal has representatives that attend approximately 100 “medical meetings” a year on behalf of the company. A medical meeting is effectively a trade show where Mission displays, explains, and generates leads on their pharmaceutical products. During the course of a meeting, attendees of the meeting can register at the mission display (booth) to request more information. This data (attendee demographics), is sent to Mission post-meeting in a somewhat standardized format.

Original Process

The original process involved a manual import of the post-meeting data into a Microsoft Excel format. Next, a mail merge was used to generate mailing labels for each of the attendees. The labels were affixed to a thank you letter that included a response card that the attendee could send
back to request samples or more information. When the response card was returned, a separate Mission employee would manually key the responses, including all demographic information, into a Microsoft Access Database. Periodically, the names and their responses from the
response card were exported and printed in a tabular format. This final report was then sent to the customer service department for order fulfillment.

There were several problems with this process. First, it was extremely time consuming and error prone, requiring interaction with at least 3 different applications to manage a single meeting. Second, there was no way to track the fact that attendees can and do attend multiple meetings, which meant that Mission was unable to capitalize on this information. Finally, the process of matching an attendee to an assigned account required a looking into Mission’s SFA system, a step that was impossible due to access and license issues.

Problems Solved

The new software consolidates all of the original processes into a single web interface. From one application, one can enter information about the meeting, import attendees, export labels, manage response cards, and export fulfillment information for customer service. In addition,
the attendees are matched against the Mission Sales Force Automation system and notification is sent to the correct sales representatives of the fact that one of their accounts (called “professionals”) has attended the meeting.

How it was done

Using the NetQuarry platform and one developer, a complete, enterprise-class application was delivered to Mission in a remarkably short amount of time.

The entire process from initial discussions and analysis to running implementation took place in two and one-half days. Of this time, approximately one day was spent on analysis of the problem and existing systems (the SFA system) and one-half day was spent dealing with deployment and testing on Mission’s server.

The application includes rich import and export facilities, manages more than a dozen functionally rich web-based forms, and provides Mission
with a single application to manage all of their medical meetings. Again, all completed in less than three days.

The key to this success was the NetQuarry platform. Using the NetQuarry Studio, a single developer produced a complete application in less than three days.

About NetQuarry

NetQuarry is the Enterprise Application Platform for Microsoft .NET.

The platform is comprised of pre-built software, metadata and tools designed to help professional software teams develop significantly
better enterprise and hosted business applications. Developers using NetQuarry will deliver everything faster (less time and manpower equals less cost):

  • Rapid Prototypes (in as little as one day)
  • Functional applications that perform like highly mature ISV solutions
  • Continuous, quality improvements and iterations
  • Agile response to the reality of changing requirements

The NetQuarry platform is not a code generator. Rather, it is a declarative framework that provides a foundation of deep functionality common to all enterprise and hosted applications, including data binding, database virtualization, OS-virtualization, searching, filtering, user interface, and role-based security.

Today’s dynamic business environments demand a great deal from developers and their managers. Rapid, agile, iterative development allows developers to incorporate frequent feedback from end users, realizing that successful applications are constantly refined, changing rapidly to meet the needs of the enterprise.

Making agile development successful requires advanced software infrastructure and disciplined methodologies. Infrastructure should be
designed to facilitate iterative development, producing quality applications.

Our Value Proposition is simple: Higher quality business applications delivered in a fraction of the time.

For more information, visit www.netquarry.com or contact us via email: info@netquarry.com.

NetQuarry Version 1.1 Released

Version 1.1 adds important features to the platform, including enhanced cross-browser support, rich editable datasheets, and declarative validation. Most significantly, the 1.1 version adds support for Microsoft Visual Studio 2005, Microsoft .NET 2.0, and SQL Server 2005.

NetQuarry Studio

Application Developers build applications by doing one of three primary tasks. First, a developer develops or analyzes the data that is to be used in the application. Second, the developer uses NetQuarry Studio to manipulate meta-data that describes to the NetQuarry runtime how the end application will look and manage the application’s data. Third, any custom business logic is written using any .NET language and IDE (e.g. Visual Studio .NET) to produce focused application extensions.

To describe an application to the NetQuarry runtime the developer interacts with the NetQuarry Studio. The NetQuarry Studio is a Windows application that manipulates the meta-data objects and guides the developer through the creation and management of these objects.

The Studio is built using both Microsoft .NET and the NetQuarry platform. It provides a Visual Studio developer with a familiar user interface paradigm further enhancing the productivity of developers.

NetQuarry Studio is not a replacement for Visual Studio. Rather, it is the main tool interface used to describe the application. Developers still use Visual Studio to write business logic using the .NET language of their choice.

Read the full white paper.


Keeping at the forefront in any industry requires that companies cannot only imagine great new products, but can get them from the vision stage into full production in the most efficient possible manner. The NetQuarry platform provides an engine for driving innovation, enabling products to be designed quickly, collaboratively, and iteratively.

Read the full White Paper.

Issue Track Tutorial

This tutorial explains how to use the platform to create a simple, yet powerful issue tracking application.

In this application, there are two important objects, an “issue” and an “individual.” The issue holds information about the issue or problem report and the individual models information about a user in the system.

The basic requirements are as follows:

  • Users of the system are authenticated using a directory managed by the application.
  • Issues should be entered with a minimum of information – description, type, severity. The rest of the information should default to reasonable values.
  • Issues assigned to the logged in user should be easily available.
  • Issues can be related to each other. This relationship may be specified as related, duplicate, dependency. Relationships are displayed only in one direction.
  • The Issue and Individual objects must support attachments and free text notes.
  • The Issue and Individual objects should track the last updated user and last updated date/time.
  • Read the document here.

    NetQuarry Version 1.0 Released

    LONG BEACH, Calif. – August 31, 2005 – NetQuarry, Inc. announces release of v1.0 of its NetQuarry Enterprise Application Platform. The NetQuarry platform is developed in and for the Microsoft .NET 1.1 environment and supports customization in any .Net CLR-compliant language.