Thursday, July 05, 2007

Coming from MySQL and PostgreSQL background I am used to tools such as mysqldump for getting a complete dump of an SQL database into an a file. The file then contains SQL commands for creating the database structure and more importantly, for filling it with data using INSERT statements. A nice feature indeed.

Since I've begun working with Microsoft SQL Server, it has always been a problem for me to get the same result. There is no command line utility that I know of that comes with SQL Server 2000 that allows you make the same dump as mysqldump provides. There is however a hidden feature in the Enterprise Manager that you can use to achieve the more or less same result as with mysqldump. I have written about how to get the database schema using Enterprise Manager some time ago. The problem is that it does not work for SQL Server 2005 - there is no Enterprise Manager for v2005! The Microsoft SQL Server Management Studio does not have that useful feature so we are left alone... Or maybe not.

Some time ago I was determined to find a solution for this problem. So I have searched high and searched low, and I have found something. The thing is the Database Publishing Wizard. It does exactly what is needed - it dumps the schema, the data and even stored procedures if any are available! It has a command line interface, a GUI interface and on top of it it integrates with Visual Studio!

What more can you want?

kick it on DotNetKicks.com

Thursday, July 05, 2007 10:19:44 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
 Wednesday, July 04, 2007

Following my last article on creating specialized validators, below I present the EmailValidator control which validates user input with a pattern of an email:

public class EmailValidator 
    : RegularExpressionValidator
{
    public EmailValidator()
    {
        ValidationExpression = 
        @"^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@
        [a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.
        [a-zA-Z][a-zA-Z\.]*[a-zA-Z]$";
        ErrorMessage = "Email is incorrect";
    }
}
Note that ValidationExpression is broken so it may be better displayed in the browser. As for how accurate, the expression is. It was taken from the Regular Expression Library page and I have had no problems with it.

Usage on a page after registration:

<my:EmailValidator runat="server" ID="EmailCorrect" 
    ControlToValidate="Email" />
Wednesday, July 04, 2007 6:03:19 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

Validation controls are one of the best features that ASP.NET has to offer. They allow us to perform both client and server side validation and work very well well with the Control model that is given to us by the Web Forms model. Here I will describe how to use RegularExpressionValidator so that never again will you be searching for that email matching regular expression on all of your pages.

Usually when you use a RegularExpressionValidator you just drop it on a form (or code it by hand) and set few properties. Among them, there is the ValidationExpression. When done, it looks more or less like this:

<asp:RegularExpressionValidator runat="server" 
    ID="OnlyNormalLetters" 
    ControlToValidate="Login" 
    ErrorMessage="Login contains illegal characters" 
    ValidationExpression="[a-zA-Z]" />

As I have described in my article on the best practices of inheriting controls, it is a good idea to limit the number of times important things are repeated in the code. In case of RegularExpressionValidator, the important thing that gets repeated is of course the ValidationExpression property.

To avoid repeating the same expression on each page that requires it, it is better to create a new class that inherits from RegularExpressionValidator. In this class set the RegularExpression property to some constant string like on the following example:

public class NormalLettersValidator 
    : RegularExpressionValidator
{
    public NormalLettersValidator()
    {
        ValidationExpression = "[a-zA-Z]";
    }
}

And that's it. Using this validator is the same as using the built in one, but you don't need to provide the same ValidationExpression any more. Just register it in either web.config file or on the page and you are good to go.

Of course the example is very simple, but I hope it demonstrates a useful concept.

kick it on DotNetKicks.com

Wednesday, July 04, 2007 5:55:43 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Everyone knows the using statement. The statement that deals with IDisposable interface for us in a clean to write way. There is however one feature of this statement that is almost never mentioned. The feature I'm talking allows for multiple objects initialization of variables. Usage looks as follows:

using (SqlConnection conn1 = new SqlConnection(), 
    conn2 = new SqlConnection())
{

}

This way, both conn1 and conn2 will be disposed - no need to write 2 nested usings.

There is a note about this feature on MSDN but I've not seen it mentioned anywhere else.

Wednesday, July 04, 2007 8:34:02 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  | 
 Tuesday, July 03, 2007

I cannot remember how many times I was entering the same piece of code over and over again with few (if any) changes. The piece of code that I'm talking about is an event handler method with a signature similar to the following:

protected void Accept_Click(object sender, EventArgs e)
{
    //....
}

The whole structure is method is usually the same. We have access modifier, a name of an object, an underscore, a name of an event and finally the sender and EventArgs part of which only three things tend to change.

Keeping this in mind I have created a code snippet that saves me a lot of time when I need to create event handlers manually (which usually happens when working with ASP.NET controls).

Some time ago I have written an instruction on how to use code snippets and also I have provided a couple of useful snippets. The new snippet added to the collection is used by typing "eventh" and it allows for customizing 3 parts of an event handler that are most likely to change.

kick it on DotNetKicks.com

Tuesday, July 03, 2007 10:01:48 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

While working with some obscure Microsoft's technology called MPS (Microsoft Provisioning System) I've been presented with one of the best error messages ever: "The server is unwilling to process the request.". So now we have to ask servers if they are willing to help us? Huh?

Tuesday, July 03, 2007 6:36:13 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 

Today I have found a really useful class inside the System.Diagnostics namespace. It's called DebuggerTypeProxy and it allows you to customize how you types behave (or more precisely what data do they present) inside the debugger.

Often I have overwritten the ToString method just to get my type look nice in the debugger. A common problem is when there is some kind of collection of objects and the only thing that you see when you look at it is the all of them are of a certain type. That's because of the default implementation of the ToString method. If you overwrite it to return - say a Name property of you Client object, you immediately have it easier when it comes to finding the concrete instance on the list. Although DebuggerTypeProxy won't help in making you types more easily visible on the list, it can do so much more!

Basically DebuggerTypeProxyAttribute is just what the name suggests - a proxy. It is a kind of view that you can assign to your types and debugger will use it much like DebuggerVisualizerAttribute is used to provide a custom view over a data type.

A simplest possible example to demonstrate how to use DebuggerTypeProxyAttribute:

[DebuggerTypeProxy(typeof(MyTypeProxy))]
class MyType
{
}

class MyTypeProxy
{
    MyType type;
    public MyTypeProxy(MyType type)
    {
        this.type = type;
    }
    public string Hash
    {
        get { return type.GetHashCode().ToString(); }
    }
}

And result of the code turns this:

Into this:

It is highly unlikely the you would ever need to create a type proxy to display it's HashCode, the example demonstrates a concept and that is: exposing method calls as properties. Normally debugger won't show you values that result from a method call. You can access them manually by calling methods in the Watch Window, Quick Watch Window or even Immediate Window. Using DebuggerTypeProxy you can achieve a more debugger friendly access to those results (if you ever need them).

kick it on DotNetKicks.com

Tuesday, July 03, 2007 5:51:40 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
 Friday, June 29, 2007

Today while I was working on my usual solution inside Visual Studio I have encountered a serious problem with how Visual Studio, SourceSafe and Web Site projects interact. My solution that I was working with consists of several projects including few Web Sites. My environment is configured to use SourceSafe database as a version control system. Nothing unusual - a 100% Microsoft only environment. I had been working like this without any changes to the configuration for a long time but I noticed that no matter what I do, my solution file (.suo) is growing larger and larger...

Since .suo (solution user options) files only contain information about my options e.g.: opened files, break points etc I thought that it will not hurt much if I just delete this file. I didn't care about opened files nor the location of breakpoints. Besides, sometimes deleting the .suo file is just the only option to restore Visual Studio to a working state after it refuses to open a project file. On top of this, I have deleted the .suo file many times before without any negative effect. So I did again, but this time I was hit right between the eyes and I'm still recovering from the blow.

After deleting the file and starting the solution I got the following message:

"The Open from Source Control operation is still in progress but you can start working now. The rest of the projects will be retrieved asynchronously."

I thought, oh... OK, the message was not a warning and there are a lot of useless messages in Visual Studio so there is no need to worry. I was WRONG, but it came out some time later.

Everything opened correctly and it even seamed to work, but the pages looked different from what I was expecting. They looked exactly the same way as before I made my last changes that I didn't commit before the deletion of .suo file.

After a bit of investigating and testing I have found the problem. And the problem that is! It appears that if you have a file checked out inside of the Web Site project than the fact it is checked out is somehow remembered inside the .suo file. If you delete a .suo file then Visual Studio will try to be "smart" and will get the latest version of that file from the source control - SourceSafe in this case. What this means of course is that any changes in the checked out file will be lost WITHOUT ANY chance to stop and WITHOUT ANY warning message!!!

This issue is only a problem for Web Site projects. Other project types like Class Library are not affected. Now the questions are obvious: why Visual Studio is using .suo files to keep tract of what is checked in and what is checked out inside Web Site projects? Are .scc and .vspscc files not enough? Why would it even try to get the latest version? Is the fact that the file on the disk is not Read Only and is different from the version in the Source Safe not enough to at least issue a warring/question?

In my opinion it is obviously a bug and it has just caused me to lose half a day of work!

Friday, June 29, 2007 1:52:19 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 
 Monday, June 25, 2007

Almost every time I'm working on an ASP.NET project I create a Visual Studio solution that consists of at least two projects: the web project and a class library. The first one is obviously needed. As for the second, what I put there include all kinds of ASP.NET related classes such as the BasePage class or just custom controls. This makes it easy to use those controls since Visual Studio (usually) automatically adds them to the Toolbox.

There are times however, when I need to make something quick. Perhaps a small project to test a new idea. In those cases, I rarely go for the 2+ projects solution layout since Visual Studio is standing in my way a bit - i.e. by hiding the possibility of adding new project to an already existing Web Site project (solution node is not visible on the tree view in Solution Explorer, but it is still possible to add the project using File menu). So I end up with only one project and the App_Code folder.

Working with App_Code is not a problem as long as you don't need to make some configuration in the Web.config file. Some elements require you to specify a type name. Normally in such a case, you need to provide a valid type format name in a form of <typename>,<assemblyname>. As long as you know the assembly name it's OK, but wait! There is no explicit assembly for App_Code. There is however an assembly behind the App_Code directory. It is simply called App_Code!

That said, it is usually enough to just specify the type name, without assembly name, for types defined in the App_Code directory.

So what about controls? In order to work with a control defined in App_Code directory we need to either register it on a page or in a Web.config file. There is however one issue. In order to register a control in a Web.config we need a namespace. By default however, neither pages nor classes added to an App_Code folder have a namespace. This is only a minor inconvenience because ASP.NET does not prevent us from adding a missing namespace declaration to a class in an App_Code directory. By adding such a namespace to a class representing ASP.NET Control, we can then add a registration in a Web.config file like the following one:

<pages>
  <controls>
    <add namespace="MyControls" tagPrefix="m"/>
  </controls>
</pages>

Notice that assembly attribute is not required.

For working with code, there is also a special class that helps with issues arising from the fact that there is no explicitly assembly nor a namespace for types in an App_Code directory. If at any time, there is a need to work with a type object of a class from the mentioned directory, .NET framework offers us a class called BuildManager which defines a GetType. Using this method it is possible to get an instance of a type object by providing just a name of a class defined in the App_Code directory.

kick it on DotNetKicks.com

Monday, June 25, 2007 6:17:51 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, June 20, 2007

After reading my article on recursive properties of ASP.NET controls, where I point out that not all properties are recursive, I have decided to fix one annoying behavior. The problem is that one of the most important property of all, the EnableViewState property is not recursive. This of course makes it useless in most scenarios. Never will we be able to rely on it while authoring our controls since ViewState can be disabled on any of the parent controls thus preventing our control from saving its state.

To solve this a very simple method can be used to check for the state of EnableViewState property:

public bool IsViewStateEnabled(Control control)
{
    if (control.Parent == null)
    {
        return control.EnableViewState;
    }
    return control.EnableViewState && 
        IsViewStateEnabled(control.Parent);
}
Wednesday, June 20, 2007 7:44:05 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |