project location is not trusted


Thursday, August 17, 2006

When a .NET project is stored on a network share, a "project location is not trusted" warning will appear if you attempt to connect to it via a UNC.  This happens because UNC locations are not trusted by default and must be added into the Local Intranet Zone security policy in order for them to work without erring.  This can be done through the .NET Framework 2.0 Configuration tool (Mscorcfg.msc).  A shortcut to this tool can be found in the Administrative Tools menu.  The process is pretty straightforward.  The only trick is to get the syntax right when entering the UNC into the code group:
 
file://\\server\share\*
 
For full details on how to accomplish this, refer to MSDN's directions.

10:38:56 PM   | c# |
 
recent visual studio 2005 projects


Wednesday, August 16, 2006

I have often found that the 'Recent Projects' section of the Start Page in Visual Studio 2005 (VS) will become cluttered with projects that I am not interested in seeing any longer. One way to get rid of projects from this list is to delete or move the project and then click the project in the 'Recent Projects' list.  VS will say that the project cannot be opened and will ask if you would like to remove the project from the list. Of course, deleting or moving a project will often not be a viable option.  Instead, you can simply manipulate the 'Recent Projects' list manually via the registry.  Navigate to the following registry key:
 HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\ProjectMRUList
You can manipulate the list by modifying the string values in the ProjectMRUList key.  One word of caution, VS looks for the values to be named in consecutive order (i.e., 'File1', 'File2', 'File3', etc.).  If you create a gap in the order, all 'Recent List' items after the gap will no longer show up.  So, make sure to copy data between values and leave the unwanted items at the end so that they can be safely deleted.

8:02:53 PM   | c# |
 
download options for asp.net


Tuesday, August 15, 2006

In the September 2006 edition of MSDN Magazine, Joe Stagner has written an excellent article on different ways to handle file downloads in your ASP.NET applications.  Stagner speaks to the issue of breaking up file downloads into manageable pieces in order to not overload memory as files are buffered when they travel from the ASP.NET worker process to the IIS process.  Of particular interest, Stagner gives details on how to create a HTTP handler class to buffer download files and provide a mechanism for resuming downloads if the client disconnects in the middle of downloading.  This HTTP handler class implements the IHTTPHandler interface which consists of the IsReusable property and the ProcessRequest method which is responsible for the custom HTTP handling code.  Custom HTTP handlers can be enforced for a desired file type by mapping their extensions to a particular custom HTTP handler in the httpHandlers stanza in web.config.  Here is an example taken from Joe Stagner's example (his HTTP handler class is in the Download namespace and is named ZIPHandler):
<httpHandlers>
   <add verb="*" path="*.zip" type="Download.ZIPHandler,Download"/>
</httpHandlers>

HTTP handlers are especially powerful for .NET coders because they allow custom handlers to be written without having to create ISAPI extensions in C or C++.

The key to Joe Stagner's resuming download HTTP handler is the Entity Tag (ETag) header element used by the HTTP 1.1 protocol.  This identifier provides a unique identifier for the session and allows the custom HTTP handler to resume the download.  Check out all the details in Joe Stagner's article and code download.


9:52:36 PM   | c# | asp.net |
 
typed datasets


Monday, August 14, 2006

The power of typed datasets is a very impressive feature in Visual Studio 2005 (VS).  Creating a typed dataset is as easy as adding a dataset item to your project (an XSD file) which will launch a wizard to help you setup the dataset.  This typed dataset file is actually an XML schema definition file that describes the dataset and will be compiled at runtime only when needed.  After setting up a typed dataset, you are equipped with many standard abilities such as SELECT, INSERT, DELETE, and UPDATE capabilities.  But in addition to these functions (which can be highly customized), there are many ways to increase the functionality of the dataset.  One way is to add customized SQL queries into the TableAdapters created within the typed dataset.  These SQL calls can be ad hoc statements or stored procedures (new or already existing).  Each of these customized queries is referenced through a method call added to the typed dataset class.  As can be imagined, there is quite a bit of auto-generated code being created by VS behind the scenes (switch to class view and you can analyze this code by choosing 'Go To Definition' from any of the methods that are part of the dataset's class).  Make sure not to add any custom code into these auto-generated classes because it will be destroyed if the class is regenerated.  Instead, with .NET 2.0's partial class functionality, it is fairly easy to add any code customization you may want to your own class files.  In case you are new to the concept of partial classes, they make it possible to split a class's definition over two or more source files.  So, VS uses the auto-generated file for its code and you can use your own file to add your methods, properties, etc.  At compile time, all partial class definitions are merged to create a single class definition.

Typed datasets come in very handy when working with one of the most common asp.net controls, the gridview.  The gridview can easily be tied to a typed dataset and many standard functions (e.g., sorting and paging) are setup for you.  This saves the developer time as they no longer need to concentrate on this type of common, repetitive coding.

Another important aspect of typed datasets is type safety.  Since typed datasets have a schema defining the dataset's data types, data mismatches will generate errors at compile time, making typed datasets much more robust.

6:58:22 PM   | c# | asp.net | ado.net |
 
microsoft's DPM backup solution


Sunday, August 13, 2006

Backup solutions are always a difficult area for IT Departments. Disaster recovery is vital, yet centralized backup software solutions require a lot of hands-on to keep them functioning properly and to ensure all important data is backed up.  For several years, I have been working with a disk-to-disk-to-tape model that has been very efficient for fast restores.  Of course, this model may not be practical for companies with huge amounts of data, but can be great for companies that can practically utilize SATA RAID arrays for first-level backup (I have been successfully using Nexsan arrays for several years now).  We use a combination of Ultrium 2 tapes and LaCie external hard drives for off-campus storage.  I have worked primarily with Veritas (now Symantec) Backup Exec.  Before Veritas I used CA's ARCServe which was not a very reliable application, at least at that time.  I have mixed feelings about Veritas.  On the one hand, it has been a fairly reliable application, but when I have faced issues, I have been on my own.  Backup Exec tech support is based in India, as is almost all support these days, and I have had a pattern of unskilled, uninterested individuals suggesting rote answers to my issue.  In addition to these kind of difficulties, there are other challenges as well.  Even with differential or incremental strategies, backups are slow and storage intensive.  Compatibility issues can arise between the backup software and Microsoft Windows, especially when Microsoft upgrades their operating system or key enterprise applications such as Exchange or SQL Server.
For these reasons, I am very enthusiastic to try out Microsoft's answer to central backup--Data Protection Manager 2006 (DPM).  There are many promising aspects of DPM:
  • It is designed on the disk-to-disk-to-tape backup model which provides for very fast restore times.
  • DPM only replicates byte-level changes to the backup array.  This means that if a user changes a very small part of a large file, only the bytes that were changed are written to the new backup rather than the entire file as happens in traditional differential or incremental backups.
  • DPM is a much more reliable solution for open-file backup since it is designed to work in conjunction with Volume Shadow Copy Service (VSS).
  • DPM is pretty cheap for the services it is provides.  DPM utilizes agent software on up to 50 client servers per DPM server to perform remote backup.  The server software costs around $950 and comes with three agent licenses.  Each additional agent license costs around $150.
  • DPM is Microsoft software working with Microsoft software (Windows).  My experiences have shown that this is the best way to go whenever possible.
  • You can set up to eight synchronizations to occur per day.  This allows you to have up to eight "snapshots" of your files per day.

Before installing DPM, make sure you have a server that meets the minimum requirements (plus some to be realistic) and has at least one unused physical disk.  This unused disk will become the designated backup location and must be a free physical disk, not just logical (of course, other disks can be added later).  Also, you will need to apply a hotfix (hotfix info is included in the release notes) along with Service Pack 1 if you are running DPM on Windows 2003.  Keep in mind that DPM does not support Exchange or SQL Server backups yet, those features are planned for version 2.

To get more information about DPM check out Microsoft's DPM site.


5:13:18 PM   | windows |
 
3-tier architecture


Saturday, August 12, 2006

A little while back I made an attempt to find documentation that would help me define the most appropriate way to design .NET projects.  I was aware that it was important to have a Data Access Layer (DAL), a Business Logic Layer (BLL), and a User Interface Layer (UI), but I was unable to successfully find any clear or concise literature to help define architecture guidelines.

Well, yesterday I was very happy to find that Microsoft has released a whole series of tutorials entitled "3-Tier Architecture for ASP.NET 2.0."  These articles were released in June of this year and provide some very useful guidelines on how to get started with a 3-tier architecture in your .NET applications.

11:38:55 PM   | c# | asp.net | ado.net |
 
excluding data with the sql except statement


Friday, August 11, 2006

I stumbled across an interesting SQL command the other day--the EXCEPT statement.  The EXCEPT statement returns distinct values from query A where query A records do not match query B records.  To explain how it works, lets work with two tables:

--Customers and their email addresses
CREATE TABLE [Customers]
(
   [CustomerID] [int] NOT NULL,
   [FirstName] [nvarchar](50),
   [LastName] [nvarchar](50),
   [Email] [varchar](100)
)
--Customer attributes assignment table
CREATE TABLE [CustomerAttributes]
(
   [CustomerID] [int] NOT NULL,
   [Attribute] [int] NOT NULL
)


The Customers table is responsible to hold customer data and the CustomerAttributes table assigns multiple attributes to the customers.  Lets say that attribute 5 is "No Mail" indicating that this customer does not wish to receive email.  In order to make sure customers do not receive email if they have the "No Email" attribute, we would need to create something like this:

SELECT DISTINCT
   c.CustomerID,
   c.FirstName,
   c.LastName,
   c.Email
FROM
   Customers AS c
LEFT OUTER JOIN
   (SELECT CustomerID FROM CustomerAttributes WHERE Attribute = 5) AS a
ON
   c.CustomerID = a.CustomerID
WHERE
   (a.CustomerID IS NULL)

Using the EXCEPT statement, we can create the following alternative SQL:

SELECT
   CustomerID,
   FirstName,
   LastName,
   Email
FROM
   Customers
EXCEPT

SELECT
   c.CustomerID,
   c.FirstName,
   c.LastName,
   c.Email
FROM
   Customers AS c
INNER JOIN
   CustomerAttributes AS a
ON
   c.CustomerID = a.CustomerID
WHERE a.Attribute = 5

There are a couple of constraints involved in using the EXCEPT statement.  There must be an equal number of fields returned in both queries and the data types of these fields must match.

The EXCEPT statement can be used to compare more than one set of queries.  In this situation, query A and query B are compared and a result set is created, then this result set is compared with query C and so on.  In the end, you will have a result set with distinct values  filtered of all records that match any of the EXCEPT queries provided.


11:26:39 PM   | sql |
 
regular expressions (dates and money)


Friday, August 11, 2006

Using regular expressions to validate user input is very handy, but they can be very difficult to construct since their syntax is foreign to most .NET programmers.  I am often finding myself in need of adding a custom validation control to a web form that requires a valid date format inputted by the user.  I built the following regular expression to handle short dates and it seems to work well:

^(((([13578])|(0[13578])|(1[02]))\/(([1-9])|([0-2][0-9])|(3[01])))|((([469])|(0[469])|(11))\/
(([0-9])|([0-2][0-9])|(30)))|((([2])|([02]))\/(([1-9])|([0-2][0-9]))))\/((\d{2})|(\d{4}))$


You can better see the logic by expanding the expression in notepad, using tabs and carriage returns.

Another common use for regular expressions is to validate currency data entered by a user.  I found the following currency expression somewhere on the net and it has worked well for me:
^-?\d+(\.\d{2})?$

9:20:55 PM   | c# |