Tuesday, August 29, 2006

Every now and then somebody just has to do it. They need to override the GetHashCode method either because overriding Equals method or for some other reason. Doing so, you should follow the guidelines provided to us by one and only Microsoft:

http://msdn2.microsoft.com/en-us/library/system.object.gethashcode.aspx

The main problem with guidelines regarding the GetHashCode method is that the change from time to time which causes some confusion.

The last change I have noticed is the fact that now GetHashCode can return different values for the same object if the state of the object that the GetHashCode relies on, has been modified. Previously GetHashCode allways had to return the same value for a given object (which caused it alomost impossible to override both the GetHashCode method and the Equals method and at the same time have a mutable object). The change to the rule makes it easier, but has some other implications...

The most important implication of having an object return a different hash code during its lifetime is the fact that no it is possible to put someting in the hashtable never to be seen again (at least not in a way we would expect it to). When this happens is when we put some value in the hashtable using some object as a key. Then we change the object so that it returns a different hash code and we have a situation where the value in the hashtable is inaccessible using the same key we have used to put it there.

As a quick example try the following code:

public class Class1
{
public override int GetHashCode()
{
return new Random().Next();
}

public static void Test()
{
Hashtable t = new Hashtable();
Class1 c1 = new Class1();
t.Add(c1, 1);
Class1 c2 = new Class1();
t.Add(c2, 2);
object o1 = t[c1];
object o2 = t[c2];
}
}

What would you expect o1 and o2 to be? Given no knowledge of the hashtable object I would expect to get what I have put earlier i.e.: 1 and 2, but I get nulls. That is because the Hashtable uses the GetHashCode method as a key to find values. Keep this in mind when overriding the nasty method.

kick it on DotNetKicks.com

Tuesday, August 29, 2006 2:04:18 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
 Wednesday, August 23, 2006

In my two previous article on relational database schemas I have described problems that arise when dealing with sql database schema that needs to be changed. I have also provided a quick tip on using Enterprise Manager to get the schema of your database. Those are the problems of relational world...

As described in the mentioned articles there are problems when it comes to keeping your database schema up to date etc. There are also problems when you need to keep the application code in sync with a database. Either you do a database-driven design and add fields in a database and then adjust the model to reflect this change, or you do a more model-driven design i.e.: the other way around - change the model and then adjust the database you always have the problem of synchronization. Tools are available that generate either a model or a database from eiher the database or the model, but is it perfect?

Far from it. One thing that I really appreciate when using Db4o is that I have no such problems. Simply because there is no database schema or in other words: the database schema reflects what I have in my model.

Now I'm not suggesting that object databases are the solution to all your problems. There are problems with data migration also however I haven't encountered one yet.

Wednesday, August 23, 2006 1:40:57 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 

As promised in my article on upgrading database schemas, I will show you the trick that I have learned when I was preparing SQL database upgrade scripts for my databases (that is before I thought on using some automation such as SQL Delta).

The fastes way I have found to get the database schema from a Microsoft SQL Server 2000 is to use the Enterprise Manager. Just navigate to a database you want, select the Tables node and select the tables you want to get schema for (you can select multiple tables using either shift or control key). As an example I have selected two tables of MyGallery database:

Having selected the desired tables use the context menu and select Copy or use the ctrl+c shortcut. Now open some kind of text editor such as Notepad. Paste the content of a clipboard and what you get is something like:

Now that is very cool isn't it? I have used this technique fo comparing two databases some time ago. Just get the schemas from two databases, save them to files on your disk and use some text diff tool.

Far from perfect but if you have no tool this is what you got. One more thing to mention is that you can use this copy and past mechanism also with stored procedures.

kick it on DotNetKicks.com

Wednesday, August 23, 2006 1:28:01 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Every now and then there comes a time when you release a new version of you application. Some of the new versions do not require changes to the database schema, but there are times when such a change needs to be done.

So imagine that we have an application that several hundred of our customers run. The best possible situation is that all of them have the same version of a database schema. Then we do not have to test all the possible upgrade scenarios. Mostly however there will be multiple versions of databases that are out there and you have to handle all of them.

But what is really the problem you ask? We have developers that designed the database at some point in time, created an application that was sold with that particular schema version. Then, upgrades were made, between that version and the version that we are about to release now and developers have been told to create SQL upgrade scripts so that the we can ship them with a new version. All fine if developers were doing those upgrade scripts while changing the database. Worse if you have to make a diff of the initial database schema and the desired one. Either way it was, is and always will be prone to human error. People are error prone. We, developers make mistakes, especially when doing some mindless (most of the time) activities such as comparing databases.

So, how sure you are that the database upgrade scripts that you are about to ship are the right ones? Hard question. One thing you could do is to take an initial database, run the scripts and compare the schemas. I will post a short tip on how I do it with Microsoft SQL Server 2000 Enterprise Manager. If there are errors, correct them, run the scripts again, repeat until there are no differences (or you see none).

Another problem is that the schema is not the only thing that needs to be shipped. Imagine that there is some fixed data in your database that is constant. Imagine that this data need to be altered. Same solution exists as mentioned above. Do it by hand either at the end or incrementally.

Is this solution perfect? Is it cheap? Is it time and cost effective? When you think about it you will find out that there should be some automation available. And rightfully so. There are tools that let you compare the databases, point out the differences and even create an SQL upgrade script for you. Keeping in mind what was said earlier it should be obvious that such a tool is a must have tool in every software development company that does sometime upgrade its databases.

As mentioned, there are tools that help you automate this process. I have recently found the SQL Delta application that lets you do eliminate this time consuming and error prone process of manualy generating upgrade scripts. Now if I had such a tool back when I was wasting my time making the scripts instead of solving the real business problems...

kick it on DotNetKicks.com

Wednesday, August 23, 2006 1:05:41 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
 Friday, August 18, 2006

Today I have added a little "Add to del.icio.us" link at the bottom of each article. Feel free to use it :-).

Now the technical stuff. First of, for the blog engine I'm using ThinkJot. It is an ASP.NET 2.0 port of a popular dasBlog application. As any dasBlog user should know, the engine supports macros with which you can add some dynamic content to your posts. To use them you have to edit your template and use something like <%itemTitle%>. There are plenty of macros documented on the official dasBlog site and even more macros are supported that are not documented - or at least I haven't found the documentation.

So the procedure I went through while adding a del.icio.us link was a bit painful. First of when you google for an answer what you find is mostly far from perfect. Most sites just suggest adding a simple linkt to del.icio.us and provide some parameters in the url. What I have found on the del.icio.us site was far better.

The solution from del.icio.us by default uses javascript and a popup window for adding links and if javascript is not enabled it works just as a simple link.

The hard part was to integrate the solution with the dasBlog macros engine. I have found a dasBlogExtraMacros.aspx">ready made solution. I have needed something more customizable so I have not used it however. I have editted my itemTemplate.blogtemplate file by adding something like this below the item text:

<a href="http://del.icio.us/post" onclick="window.open('http://del.icio.us/post?v=4&noui&jump=close&url='+encodeURIComponent('<%permalinkUrl%>')+'&title='+encodeURIComponent('<%itemTitleText%>'), 'delicious','toolbar=no,width=700,height=400'); return false;"> Save This Page</a>

It is basicaly the script offered by del.icio.us but I have replaced the location.href with a standard permalinkUrl macro which I think is not documented. Secondly I have replaced the document.title part with itemTitleText - my own macro that returns current item's title as text. There is of course an itemTitle macro but it is an html anchor so it cannot be used (this can be changed in the config file, but since I want my article titles to be links I could not do it).

Creating the itemTitleText macro was very easy. All I had to do is add a property to an ItemMacros class as follows:

public virtual Control ItemTitleText
{
get
{
Control control;
string title = entry.Title;
if (requestPage.SiteConfig.ApplyContentFiltersToWeb)
{
control = new LiteralControl(Utils.FilterContent(entry.EntryId, title));
}
else
{
control = new LiteralControl(entry.Title);
}
return control;
}
}

That's it. I now have a del.icio.us link :-)

kick it on DotNetKicks.com

Friday, August 18, 2006 12:15:41 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 
 Thursday, August 10, 2006

There is a feature in Visual Studio 2005 called Code Snippets. Basically what this feature allows you to do is type in a code editor, some special string such as "prop":

And then by pressing the TAB key once (or twice if using the provided intellisense), Visual Studio generates some code for you as on the picture below:

Notice that there are reqions highlited witha green color. You can tab through those regions with a TAB key. On the above example, If you eddit the type of the field, the type of the property is automaticaly updated for you. The same holds true for the field name which is used inside the property.

Visual Studio 2005 comes boundled with a couple of useful code snippets of which I use the "prop" the most. However, If you do mostly ASP.NET applications you know that the standart property with underlying field is not so widely used here. What we need is a property which uses ViewState as a storage medium. Fortunatelly it is very easy to create your own snippets. Just go to the folder where VS is installed - for me it was: "c:\Program Files\Microsoft Visual Studio 8\VC#\Snippets\1033\Visual C#". There you will find all the available snippets. When you look any one of them what you will find is a simple xml defining the snippet behavior. From there it should be no problem to create your own snippets.

Being ASP.NET developer myself I have created few snippets that help me doing my work faster and those are: propv, propvd, props and test. First two generate a property that uses the ViewState, the third one generates a static property and the third one a method that has a Test attribute of an NUnit testing framework. You can download the snippets here: Snippets.zip (2,23 KB). Just put them together with the rest of the snippets.

As a side note I must say that I'm mostly a C# developer, but I have written my share of the code in VB.NET so I know what I'm missing using C#. One of the things that I miss is the snippet support. VB.NET comes with WAY more standard snippets and those snippets can do a lot more such as add a using statement or a reference to an assembly. There are even application that support creating snippets for VB.NET. Given the limitations of C# snippets I don't think we need such a tool at the moment :-(. Additionaly I recommend browsing the internet for more information as this article is just an overview of what else Visual Stidio can do for you if you just ask :-).


Do you own a business that requires the latest in wireless barcode scanner technology? Find this as well as a wide selection of barcode printers or a the best brands of credit card reader at the barcode experts.

kick it on DotNetKicks.com

Thursday, August 10, 2006 10:51:58 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  | 
 Tuesday, August 08, 2006

Since I have first seen Db4o database it has became my database of choice for every personal project that I do. You can read more about this database on its home page and I strongly recommend you to do so, even if you are not planning to leave the relational world. Reading about object databases will broaden your horizons and maybe it will change the way you implement your applications as it changed mine.

Tuesday, August 08, 2006 8:09:01 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

In the first article about optimizing rendered page size I have pointed out that you should consider using short names for content placeholders on your master pages because each control's id inside those placeholders is prefixed with the id of the placeholder. But when you look inside the page there is of course another field where you can make some improvements - the ViewState.

There are lot of articles about what you can do to make the ViewState smaller. Mainly - disable it everywhere where it isn't needed. This is a first step you can take. Amongst other things you can also use the SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium methods of the Page class. The purpose of those methods according to MSDN is to save and load any view state information from and to a page object. And that is true. But how to use those methods?

Browsing the results returned by google you can find plenty of solutions out there each unique in its way. Why they are different? The problem with those methods is not saving the state. To save the state you can use anything from the Session object, flat files or even database. The real problem is making sure that when a form is submited to a server, its ViewState is properly loaded - the concrete ViewState that was saved for that concrete page. A solution to just use Session["ViewState"] as a storage medium won't do, because then we can only have one ViewState for each user - no multiple windows/frames allowed.

My solution would be to include a hidden field on each page, name it somehow and use its value as a key for identifying which ViewState to load. Such a hidden field may be added dynamicaly in a base page so no additional work is required when adding new pages to a project. This field of course shoud hold some unique value (such as guid) in order to distinguish one page request from the other.

kick it on DotNetKicks.com

Tuesday, August 08, 2006 7:41:13 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 

I'm in process of creating one web site on which I needed a checkbox but I needed it to de displayed in form of an image. So I went to google and performed a search for a ready to use control. What I have found was not satisfying at all so I have created my own and the result is available within my controls pack as along with some other controls here.

Tuesday, August 08, 2006 2:05:25 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have created an ASP.NET controls pack that I'm using on a daily basis. The pack includes:

Control Name Description
Button A Button that supports a Confirmation message before submitting a form.
Image An Image that allows you to set the MouseOverImageUrl property.
ImageButton An ImageButton that supports a Confirmation message before submitting a form and a MouseOverImageUrl.
ImageCheckBox A CheckBox that renders itself as an image either checked or unchecked. It also supports MouseOverImageUrl for both states.
MyObjectDataSource An ObjectDataSource that supports build in sorting and filtering of returned objects.
CompareValidator A CompareValidator that supports displaying error messages as an image.
RequiredFieldValidator A RequiredFieldValidator that supports displaying error messages as an image.
PageParameter A parameter that can be used in DataSource controls parameter collections such as SelectParameters. It allows you to get parameters from properties of a page.
TemplateControlParameter A parameter that can be used in DataSource controls parameter collections such as SelectParameters. It allows you to get parameters from properties of a nearest TemplateControl.

I find those control very helpful on a daily basis and hope you will like it also. Note also that some of them I have described earlier but now I provide them as a one download with a full source code. It is available here: Controls.zip (50.7 KB).

Using most of the controls should be obvious. The most complicated one is the MyObjectDataSource. Mostly I have described it in my previous articles about this control. I have added a filtering feature by specifying FilterParameters on the data source control. There are two options: you can either use the internal filter mechanism which will filter values for you or by providing an additional parameter to a select method that is used for selecting objects. This additional parameter should be of type Dictionary<string, object> where the key is the name of the property to filter. Working with internal filter requires almost no code for example using ControlParameter:

<asp:ControlParameter Name="Role.Id" ControlID="Role" PropertyName="SelectedValue" />

Where Name attribute corresponds to a name of the property by which you want to filter and PropertyName corresponds to a property on a control that provides a value to filter by. (I know it my not be very intuitive, but that is what ASP.NET provides and I have been building on top of that). Filtering currently works similar to SQL LIKE command with wildcards before and after the expression.

If you work without internal filter you have the responsibility to filter the collection yourself given the filter parameter to passed to a select method.

kick it on DotNetKicks.com

Tuesday, August 08, 2006 12:06:14 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
 Monday, August 07, 2006

So after two days of configuration and moving my articles from my old blog I finally have my new blog set up :-). I'm still to create my own template, but for now the standard one will have to suffice.

Monday, August 07, 2006 6:55:15 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 

I haven't played with it a lot but but the most obvious was the far from complete support from the IDE. Given it is not a complete product I'm not blaming MS for it. What I blame MS for is the fact that installing LINQ is a destructive process i.e.: it damages some of the existing features of VS 2005.

For me the One thing that hurt the most was the fact that the refactoring SmartTags stopped working from a keyboard shortcut and that the Refactor option was missing from the context menu of the code window.

Since I could not imagine working without some useful shortcuts I started the process to recover the lost features. I've tried to reset the shortcuts from Tools-Options-General-Keyboard menu but it had no effect. Next I have tried to reset all settings using Tools-Import and Export Settings - no effect. Next there came Google.

I have found and that someone had a similar problem and there was a solution. Few posts from the top there is a 4 steps instruction (which didn't work for me) and than a 5th step which finally worked. I'm putting the stepps I have followed in for your convenience:

  1. Start up RegEdit.exe
  2. Open HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Packages\{A066E284-DCAB-11D2-B551-00C04F68D4DB}\SatelliteDLL
  3. Edit the "Path" value and change it from "C:\Program Files\Microsoft Visual Studio 8\VC#\VCSPackages\1033\" to "C:\Program Files\Microsoft Visual Studio 8\VC#\VCSPackages\"
  4. Restart Visual Studio and see if these problems are fixed?
  5. Go to C:\Program Files\Microsoft Visual Studio 8\Common7\IDE and run devenv /setup followed by devenv /resetuserdata followed by devenv /resetsettings CSharp.

All this stuff makes me wonder. I have been using beta software since I have learned using computers but I cannot remember having this kind of problems. Maybe the betas I use are not as complicated as Microsoft products but hey! They are not developed by the army of developers!

kick it on DotNetKicks.com

Monday, August 07, 2006 10:12:55 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

All of us who have been using any kind of ASP.NET Templated Controls such as FormView, sooner or later come to a problem of extracting value from a field inside a template. For example when you are using a FormView control and want to programatically access a control inside one of the templates. What are the options? You have to resort to some kind of FindControl calls which are way from perfect. I have been thinking about this issue for some time now and I have an idea.

The idea is to change tha way the PageBuildProvider constructs the part of class that represents the ASPX file of your page. (the other one is of course the code behind). So what could be changed? Imagine a situation where you have a page and there is just one FormView on it. The FormView has its templates defined in an ASPX file. What happens now is the ASP.NET framework builds the part of the class given this ASPX file and what we get is a nice intellisense in the code behind telling us that the our class has a field FormView1 of type FormView which of course does not have any knowledge about controls inside the templates. But what if...

But what if instead of the FormView1 being of type FormView, the part of the class constructed from ASPX file provided us with a field FormView1 of type derived from the FormView but with few additional properties which represent controls found inside the templates - in a strongly typed manner.

Now. The benefits of such a solution are obvious mainly compile time type checking.

Is it possible to make ASP.NET 2.0 to provide such a solution? This is a hard question. I have checked the major components that are responsible for the way the classes are constructed now. I haven't gone deep into details but it it looks like some changes inside the PageBuildProvider (or some base classes) would be required. Also a ControlBuilder responsible for building a templated control would have to constuct a whole new class representing our control. I suppose that the major problem lies in constructing such a derived class with all those properties representing inner controls.

So basically I hope MS will/is thinking about making our lives easier and more type safe :-) or maybe some brave developer is willing to try to implement my concept? Either way it would be nice to have such a feature some time in the future.

Some additional considerations include the problem with accessing controls from ItemTemplate of a FormView control when in Edit mode. Another issou would be with controls such as GridView where some of the templates represent a repeating content and not a single data etc...

kick it on DotNetKicks.com

Monday, August 07, 2006 10:11:13 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have written few times about the little known features of variuos products etc. Today I will add one more to the list. There is a little known feature that web browsers have that can be very useful...

The feature I'm talking about is the possibility to execute simple (or even complex) Javascript code from the address bar. While reading this go ahead and type something like:

javascript: alert(2+2);

in your brwoser's address bar and hit enter. You will see a messagebox containing the result of the expression passed as the argument to the altert function. A simple calculator, but you can go and create more complex scripts such as scripts modifying some DOM elements.

Here is a script that I sometimes use to get the current DOM of the page - after it has been modified by any user actions/javascripts such as AJAX calls.

javascript: var x = window.open(); x.document.write(document.childNodes[1].innerHTML.replace(new RegExp(/</g), "&lt;").replace(new RegExp(/>/g), "&gt;"))

If the page you are trying to view does not have the DOCTYPE declaration just change the document.childNodes[1] to document.childNodes[0]. I have tested this with IE 6.0 and it seems to work well. For FireFox users there are a lots of plugins available to do the same thing.

kick it on DotNetKicks.com

Monday, August 07, 2006 10:10:05 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

ASP.NET 2.0 comes with a mechanism called two way databinding which allows us to declaratively bind a form element to a property of an object in such way that updates are supported. For the readonly display you typically use the Eval method in your aspx page. For the two way mechanism, you use the Bind keyword (or method?).

Using the Bind keyword is really simple in most scenarios that you encounter, especially if you are using the SqlDataSource control. Problems start to come up when you try to use a more object oriented approach and use the ObjectDataSource control.

Now, still in most cases using ObjectDataSource will not cause you any problems when what u bind is a simple property such as a name of a client i.e.: you have a collection of clients that you bind to a GridView and one of the columns displays the name of the client. To do so you use something like Bind("Name"). The problem arises when you need to bind to a subproperty such as in Bind("Address.StreetName"). This won't work unfortunatelly...

Why it is not possible to perform a two way databinding in such a way, there are discussions over the Internet. BTW: Eval("Address.StreetName") works as expected. So what can we do about it? Of course there is a solution for this problem and it has came to me when I was thinking why there is no such a problem when you use the SqlDataSource control.

The reason why there is no such problem when you are working with relational data is that you are creating an SQL query that is a VIEW of the data that you want to display i.e.: it has all the columns you need and there are no "sub-columns". So what we need to do is to translate this to an object world.

So basically what we need to do is create an object that will serv as a view on our objects and bind to this view object. For example given the aforementioned client object with a name and an address we create a ClientView object that encapsulates our client object and exposes the needed properties such as Name or StreetName. Those properties in turn call on the properties of the client object either directly as in Name or to some nested property as in Address.StreetName.

Making a select method used by the DataSourceControl to return the collection of ClientView object should not pose any problem. When using such a technique I would suggest putting the view classes somewhere outside the domain model since the only reason they exist is to allow for the two way databinding to work so there is no reason to pollute the model.

kick it on DotNetKicks.com

Monday, August 07, 2006 10:08:44 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 

Sometimes you really need to debug some part of the application but you don't want to start it. For example you want to debug some lower layer of the application and the startup time takes too long. There is a quick solution for this problem. You can use the Immediate Window from Visual Studio to start a debug session. Just type a class name (with namespace) and a method name you want to call if it is static. Otherwise you have to add a call to constructor in a form of "new" keyword. Just remember to put a breakpoint somewhere :-)

As far as I know this window is not available by default so use Debug/Widnows/Immediate to show it.

The sad thing is that it does not work for an ASP.NET project, but other than that you can use it not only for testing your own methods, but to call methods of the built in classes such as System.DateTime.Now.

Monday, August 07, 2006 10:07:58 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

I'm not working with threads much since ASP.NET hides almost all of this complexity from me, but then I'm not working with ASP.NET exclusively. There are times when I need to do some multi-threading. In times like this I'm very happy that there are resources such as this available on the Internet. Currently It is the best article on threading I have seen. A good read.

Monday, August 07, 2006 10:07:22 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

For a long time I have been in need of a mechanism that allows me to create an instance of an object without calling any of its constructors like the Activator.CreateInstance does. All this time I have also been aware of the fact that it can be done. My motives weren't strong enough to dig dipper in to the problem, though. Until recently...

On my recent project I have enforced the use of a factory pattern for creating each object so for example to create a Document object we use something like Document.CreateDocument(). To enforce the use of this method, all classes should have a no public constructors declared. So it worked that way for some time now. Recently I have been forced to make some changes to the code and I have found the public parameterless construcor on the class that I have been modifying. A quick scope change to private and no compiler errors - good I thought. But..

Then came the runtime exceptions :-(. A quick memory refresher to remind me that the reason the public parameterless constructor is there lies in the parts of the code which use the late binding mechanisms of Reflection such as Activator.CreateInstance which throws errors in the runtime. I have used this mechanism in MyObjectDataSource control to create objects for insertion. Another place was a simple in house data mapper.

Now my motivation has been upgraded to a level that pushed me to make some investigation and after a while I've found the solution: FormatterServices.GetUninitializedObject. This thingy creates your objects without calling any constructor. Sweet! No more problems for me.

I have also checked the performance of this kind of instantiation and it is very good, much faster than Activator.CreateInstance. The only drawback is that any logic from the constructors is not invoked, but that is not a major issue for me since mostly the objects construced in such a way are data transfer objects. I also wonder WHY Microsoft controls such as ObjectDataSource does not use this technique but forces you to have the parameterless construcor?

kick it on DotNetKicks.com

Monday, August 07, 2006 10:06:38 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  | 

Today I have been struggling with a typical table layed out page. It was a MasterPage with few ContentPlaceHolder controls - one for content, one for menu and few for other things. The problem was that the place holders were inside the td elements and some of the elements were made in such a way that they dropped shadow (background-image) and it was not possible from the content page to override this behavior (at least not in a clean way). First I have tried to override the style which made the cell to have an image at the bottom by adding the style element inside one the contents. Unfortunatelly it is not valid html to do so. Then I have thought about adding a ContentPlaceHolder inside the head element. Unfortunatelly Visual Studio does not provide the ContentPlaceHolder control in the intellisense so I thought that it will not wokr... But it did!!!

What is a very good thing to know is that despite the VS not telling you about it, you can put a ContentPlaceHolder inside the head element. You can work with it just like with any other ContentPlaceHolder by providing default content for example. It can also be used as a place for additional page level style elements. One great feature that VS DOES provide is the fact that in the content page, when you edit the head ContentPlaceHolder, you get the intellisense for the head element so you wont see any divs or other body elements there.

After this discovery I have made a search on google to find if anyone had the same problem and I have found the following: artcle.

kick it on DotNetKicks.com

Monday, August 07, 2006 9:59:46 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 

While working on one of the web projects in asp.net that was targeted for FireFox browser only I have found an interesting thing. Take a look at the memory consumption of a FireFox process:

Now, I wasn't doing anything unusual. Just testing how the site looks like in the browser. And I have only used 1 tab and only for this one application. Also the memory consumption got as high as 300mb in few hours. On my machine (1gb ram) FF stopped working around 500mb. So I think that is just one proof for all you FireFox lovers, that not only IE has problems :-P.

BTW: I have sat with one of the FireFox lovers from my company and tuned some caching options but it didn't help :-(.

Monday, August 07, 2006 9:57:58 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 

Being a curious person I have wondered how the GetHashCode method of the string class is implemented so I have performed some research. The results are interesting at least.

First thing I have checked is if the GetHashCode method for the same string say "xxx" on two separate machines returns the same value - and in fact it does. This has led me to use the Reflector to see the internals of the GetHashCode of the string class. What I have found there? It turns out that the hash code for any given string is calculated based on the characters making the string - that's why on two machines, the hash code is the same. But the question arises: how does this impact performance? A quick test has shown that for a very long string, calling the GetHashCode method can take a considerable amount of time because the result is not cached after the first call. For short strings it my not be a problem but for a larger ones? And what about a hash table with strings? There I suppose the GetHashCode is called very often.

Now I ask myself: why the hash code is calculated using the strings that the string is made of? Since strings are using the mechanism called interning (which more or less makes ensures that any particular string representation is kept in memory only in one place and string objects are only pointing to it). Given this fact, it would be orders of magnitude more performant to use the memory addres of such an interned string as a base for the hash code.

The same question araises for the Length property. It is also taking longer the longer the string, and subsequent calls are not faster.

So as for the algorithm for generating string hash code I have no idea why it uses characters and not some memory address. As for why the results of the calculation are not caches I suppose it has to do with memory consumption - caching a hash code would reqiore an additional integer variable. If anyone has some more insight on this topic, I would gladly read it - in the comments section. :-)

Monday, August 07, 2006 9:56:13 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

I have made some research on how to create a container control - a control which works in a similar way as the Panel control does. There are three key thing you have to do in order to make it work:

  • Add ParseChildren(false) attribute
  • Add PersistChildren(true) attribute
  • Add Designer(typeof(PanelDesigner)) attribute where PanelDesigner is a custom class deriving from ContainerControlDesigner. I haven't tried it, but I suppose that using the ContainerControlDesigner in with Designer attribute would also do.

It's all. You do not have to add any more code. Since, the custom PanelDesigner does not require any code, the question arises - why do we need it? Shouldn't it be some kind of attribute?

A creative usage for such a control could be for example when you need a panel control which has some kind of static content, or maybe images as borders. You get the picture.

Monday, August 07, 2006 9:54:06 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

From time to time a strange thing happens to my Visual Studio - a strange line appears on the screen in a random place and stays there until VS is restarted. It is only visible in VS, when switching to other programs it disappears. Switching between windows inside visual studio does not help.

This is just one of the hidden and secret features of the VS that most people don't know about. The other one, a more common one, is the fast disappearing feature which makes VS dissapear (self terminate devenv.exe process) at random when you are working.

Monday, August 07, 2006 9:52:51 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have used my PathsBuildProvider a while now and I have came across some issues. I have found two major issues.

The first issue had to do with the fact that from some strange reason the development web server treats root directory "/" in a different way than IIS. So redirecting to /aplicationname/page.aspx has different effect those two servers. I have made a change so that the property is not statically encoded to return a string but rather to use System.Web.VirtualPathUtility.ToAbsolute("~/Default.aspx"). As far as I know it works on both IIS and the development server.

The second issue has to do with the application name being encoded in the code as in Paths.WebTest.Default_aspx. Imagine however that you deploy your application under a different name say WebTest2. It no longer works and strange things happen. To overcome this I have changed the code to allways use the AppRoot as a root directory name.

I have also included the changes proposed by Will Gant. The changes are simple yet brilliant. He proposed that the properties returning file paths to be static. In fact that was what I have first implemented but then I have run to a problem with doing something like Paths.AppRoot.Directory1.Directory2.Default_aspx since if all properties are static than I'm not able to return anything meaningful (an object instance) from such property. Will's solution uses a fact that when you reference a directory as in Paths.AppRoot.Directory1 what you really get is not a property Directory1 of AppRoot object/class, but a namespace qualified Directory1 class name which in turn has static properties.

As usuall, the code is available here PathsBuildProvider.zip (11,13 KB).

Monday, August 07, 2006 9:48:46 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 

After a lot of time spent on working with the Page.ClientScript.GetWebResourceUrl method made it work and it was good. I had my ImageCheckBox control which worked well using this method. The problem occured when I have inherited from the control in another project. It stopped to properly reference the javascript from the resource url. After short investigation I have found the that the problem was caused by the call Page.ClientScript.GetWebResourceUrl(GetType(), ...); The GetType method of course returns a different type when called inside the inherited control and so, the web resource url was incorrect. A quick change to typeof(ImageCheckBox) fixed the issue.

So basically it is worth to take a minute and think when to use the GetType and when to use the typeof.

Monday, August 07, 2006 9:47:51 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I do not often rename the controls that I do not use in the code behind code, so when I place a Label on a page it most often is named something like Label1. It does not make a big difference when you are not paying for the bandwidth and you only have a few controls on a form. Imagine however that you are working with Master Page and there you are using the defaul ContentPlaceHolder1 as a place for pages to put their contnet. Now it is only 19 characters long yes? But when you look at the generated html, you will see that each control put on a page using such a Master Page has its ID prefixed with the ID of the placeholder. A quick calculation on one of my pages and It appeared that for 100 controls on a page I was wasting 2000 characters only for the id of the placeholder!!! Just renaming the placeholder from the default ContentPlaceHolder1 to something like CPH saves 1700 characters. Such a name change does not cause any major inconvinience on the developer's part since you will rarely reference the placeholder by its ID.

The same mechanism holds true especially for controls such as GridView and UserControls which tend to have a long ID.

Currently I'm renaming all my controls that I put inside a GridView or FormView templates to one letter strings since I'm not using them. I also rename all my controls on pages to a shortest string that I can come up with without loosing the meaning.

kick it on DotNetKicks.com

Monday, August 07, 2006 9:47:00 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

While working with my validator controls that support displaying images, I have come to a situation where I needed the image to be themable. Easy you think?

Not so easy as it should be. I have added the Themeable(true) attribute to an ImageUrl property, put a control on a page set everything in the skin file, compilled and... ??? No it didn't work. Url points to the same directory as specified in the skin file but is not prefixed with the theme folder name. A quick reflector peek at the Image control and the solution was found. There is a little known UrlProperty attribute that has to be applied to a property which we want to behave as expected when applying urls from skin files.

Monday, August 07, 2006 9:45:06 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Yesterday I have found the post about the 0.(9) (zero, and infinite number of nines) equals 1. All of you weak at heart don't read it :-).

Monday, August 07, 2006 9:43:59 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have been trying to make the Validation controls show an image instead of plain text in case of an error. In doing so I have used Reflector a lot.

My investigation had lead me to some conclusions and even more questions. The main problem here is that for some creepy reason, the BaseValidator inherits directly from a Label control!!! Now I have always been aware of this fact but it was until not long age when it struck me how bad decision it was on Microsoft part. Keeping the parent class in mind it should be obvious that making a Label display as an image was not going to be an easy task.

There are few possible ways in which you can make the validator control show an image instead of text. One of them is providing a img tag as a Text property for the control and it works, but is very unellegant. I thought that it is time to get to know the new feature of ASP.NET 2.0 - the Control Adapters.

After a rather long time it came out that it is not possible to use the control adapters for the validation control since some of the important logic that renders the control is in the Render method of a BaseValidator class and it cannot be easily replaced. I have left the adapter path but having learned a lot nonetheless.

Afer yet more time I have realized that the only real solutions are to either create my own classes implementing the IValidator interface - good there is such a thing or use some third party controls. I had however no spare time for writing my own fully blown controls and choosing the right toolset of third party controls is also time consuming I have decided to take a dirty shortcut.

Below is a listing of all the things I have done in my inherited validator control. Baasicaly I'm changing the TagKey to img, I'm providing a property for users to specify the ImageUrl. The rest is to trick the BaseValidator control to render image instead of a label. The important thing is that the Text property has to be something different than a null, empty or white-space string - otherwise it is possible that ErrorMessage will be rendered inside the img tags which is invalid.


protected override System.Web.UI.HtmlTextWriterTag TagKey
{
get
{
return System.Web.UI.HtmlTextWriterTag.Img;
}
}
public string ImageUrl
{
get {
return (string)(ViewState["ImageUrl"] ?? String.Empty);
}
set { ViewState["ImageUrl"] = value; }
}
protected override void
AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
{
writer.AddAttribute(
System.Web.UI.HtmlTextWriterAttribute.Src,
ResolveClientUrl(ImageUrl));
if (!string.IsNullOrEmpty(Text))
{
writer.AddAttribute(
System.Web.UI.HtmlTextWriterAttribute.Title, Text);
writer.AddAttribute(
System.Web.UI.HtmlTextWriterAttribute.Alt, Text);
}
base.AddAttributesToRender(writer);
}
protected override void
RenderContents(System.Web.UI.HtmlTextWriter writer)
{
// to prevent rendering
}
[DefaultValue("Error")]
public override string Text
{
get
{
return (string.IsNullOrEmpty(base.Text) ? "Error" : base.Text);
}
set
{
base.Text = value;
}
}

kick it on dotnetkicks.com

Monday, August 07, 2006 9:43:07 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Few days ago I have found some tool which I can honestly say is almost as good as the famous Reflector.

The tool is called RuntimeObjectEditor and does just that: it allows you to edit your applications at runtime. Amazing! You have to check it out!

Monday, August 07, 2006 9:41:23 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, August 03, 2006

Some time ago I have posted an article about using Build Provider feature of ASP.NET 2.0 to build a strongly typed classes for accessing the files found in the application virtual directory. I myself have been using this provider ever since for every Response.Redirect(). I hope that it serves you as well.

I have found yet two more ways of using the Build Providers to make your applications safer (the second one I will describe in few days). Today I present to you, the ClassPropertiesBuildProvider. This time we get a strongly typed way to access name of the properties of our objects. When this could be usefull? Of course everywhere where we have to specify the name of the properties using a plain string. And where could that be? Mostly in data-binding expressions such as Eval and Bind.

Take for example a sample data-binding scenario where we bind a GridView control to an array of Client objects. Each client has Age, FirstName and LastName:

As you can see we get the full intellsense over available properties. Keep in mind that those properties actually return a string containing the name of the property - exact thing needed to use the Eval or Bind. Notice also that in case some property changes its name, or is deleted, we get an instant compile time error as oposite to the runtime exception you get when you use a not strongly typed Eval("Age").

Using the ClassPropertiesBuildProvider is similiar to the PathsBuildProvider. Just add extension=".cpbp" type="ClassPropertiesBuildProvider.ClassPropertiesBuildProvider" to a web.config file and put one or more file with .cpbp extension in the App_Code directory. In this file the first line declares a namespace under which the classes will be generated ("Classes" in this example). On the following line put the name of the assemblies you would like to have analyzed.

The solution is available as a source and binary here: ClassPropertiesBuildProvider.zip (57,43 KB).

As with PathsBuildProvider, the provided solution is for demonstration purposes and as such you should be aware that it might not always work as expected. If you find some bugs, or wish to provide some improvements, please feel free to do it, and contact me so I too can benefit from it :-)

kick it on dotnetkicks.com

Thursday, August 03, 2006 4:59:21 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

While working on MyDataSourceControl (see my other articles) I have found an interesting thing. It appears that when properties of a control are set to the values provided as attributes in the aspx file, the control is not yet very functional. The most important thing that my be not set is the Parent and other control-tree related properties of the control! It seams however that it is not always so. I may be mistaken, but from my observation it is possible that sometimes the Parent property will be set before the properties defined in the aspx. If somebody can shed some light on this I will be grateful.

Thursday, August 03, 2006 4:53:45 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

When developing stateless applications sooner or later there comes a time, when you need to store some information between requests. In technologies such as PHP and ASP.NET there is a special object to serve this function. It is called the Session object in ASP.NET. Using it is very easy, just use an indexer in a form of a string to set and retrieve some information that you want to persist between requests. Now the main problem with such an approach is the fact that it is hard to control. As an example: suppose that there are two pages using the Session object to store some state and make it accessible to each other. The simplies approach is to just use the Session object on one page to store an object and on the other to retrieve it:

Page1.aspx
Session["SomeKey"] = "some value";

Page2.aspx
object value = Session["SomeKey"];

Suppose further that there are many pages that access the value with "SomeKey" key. Sooner or later (sooner) you will lose a track of where and what is setting and retrieving this value. More over, it is hard to change since it requires you to look through multiple files - a very error prone technique.

Another solution would be to use some kind of public constant variable in place of the "SomeKey". It is better but not perfect.

A more secure solution would be to create a strongly typed class for accessing the Session object by means of properties. This way you only have to change session related stuff in one place and every braking change is detected at the compile time. Additionaly, when working with other developers, they do not have to ask you, what kind of object is available through the Session[“SomeKey”].

As a side note I would strongly encourage you to avoid Session object whenever you can. It is a hell to work with a statefull statless application :-(

kick it on dotnetkicks.com

Thursday, August 03, 2006 4:52:46 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

There comes a time when you have to develop a page which allows its users to go back to the page they came from. Keeping in mind the statlessnes of the web applications, it is hard to tell where our users came from since every page is (or at least should be) working on its own. Suppose that on one of the pages we want to put a kind of “Cancel” button which takes users back. One possible way of doing it would be to use some client-side JavaScript such as history.back(). What if for some reason the use of JavaScript is inacceptable?

We are left with the server-side code. But there is a problem. On the server, there is no way of telling the previous page. We have to create our own solution. There are couple of possibilities here. You can use a Session or Profile object and every time a page is loaded put some information there so we have a way of checking where the user was before. You can even use a Stack object to make it possible to drill down and up as you like. This solution has however an impact on the server resources (memory occupied by the session object). Another solution uses the query url to pass the returnUrl address of page from which the users came. In fact this pattern is used every time you try to access a page which requires authorization and you are redirected to a login page. This way you save some valuable server resources and make your solution a lot more scalable.

kick it on dotnetkicks.com

Thursday, August 03, 2006 4:44:18 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

Have you ever wondered when is the Select method of the ObjectDataSource called in the page life cycle? It probably depends on your particular page configuration, but on an ordinary page or user control, the select method gets called after the OnPreRender method and before the OnPreRenderComplete. Keep this in mind if you want to perform some custom logic after the whole control tree has been built.

My friend has checkd the SqlDataSource control by handling the Selecting event and the he found out that the same holds true for it also.

Thursday, August 03, 2006 4:43:18 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have been using MyObjectDataSource control for some time now with great success. I have however observed one thing that was missing. The missing thing was the possibility to use the container on which the control was placed as the actual TypeName object which provides the methods for Select, Insert, Update and Delete. Oh, of course it was possible before by using the TypeName and providing the name of the type that the page inherits from, but it had two major drawbacks:

  1. It required the page object to be instantiated 2 times: one for handling the request and the second time to provide an object on which the DataSource methods were called. (possible workaround was to use static methods, but then, no page state information was available)
  2. Providing a type name for a page is not so easy. It depends on few factors. By default the type name is the name of the code behind class with _aspx postfix. But it can be anything you choose by using the ClassName attribute of the Page directive in the aspx file.

So I have made some changes to the control and now if the TypeName property is not specified, the methods of the containing object are used. Further more, the same object is used as the one used to serve the request. Of course all the rest of the functionality remains unchanged. The source code and binary file is accessible here: MyObjectDataSource.zip (30,43 KB).

kick it on dotnetkicks.com

Thursday, August 03, 2006 4:38:50 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

For all webmasters it is a bread and butter, but I have found that most ASP.NET developers are not very skilled the CSS stuff. The one thing that I often see is the lack of understanging for the position: absolute style. Many people think that what it does is positioning a given element absolutly on the page relatively to the whole page (the View Port). Mostly so, but that’s not the whole truth. By design, the position: absolute positions the elements in relation to the nearest Postioning Context. Of course by default the View Port is the nearest positioning context but this can be changed. By design, each element that is relatively or absolutely positioned becomes a Positioning Context.

One possible and often used way is to declare an element to be relatively postioned and not offsetting it so it remains in place. This way you can absolutly position elements in relation to any element you choose.

Thursday, August 03, 2006 4:34:29 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

There is a little known feature in ASP.NET that is called the "Server-Side Comments". What is cool about this feature is that it works server side.

Using Server-Side comment is similar to using Html comment in all respects but one. ASP.NET does not process any content a block commented in such a way. This may be very usefull if what you want is to temporarily disable some part of the page and that part performs some logic other than rendering itself. Ordinary Html comment will not prevent ASP.NET from including the commented controls in the page life-cycle so your Page_Load methods will fire with Server-Side comments they will not.

Thanks to the this kind of comments you will no longer have to temporarily delete some part of the page just to make it work, because some control was throwing exceptions.

kick it on dotnetkicks.com

Thursday, August 03, 2006 4:33:37 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have always wondered how practical if at all is writing the test first. Now, for me the most questionable thing was the fact that working in such a way I do not get any help from the editor. It came to me as a surprise that not only I do not miss the intellisense telling me what parameters I must pass to the method I’m about to call but I get a far more powerful feature instead...

I had already modeled the problem domain in classes. One of those classes was the User class. Now the time came to create a custom MembershipProvider that will integrate smothly with my classes. The classes of course were not created with the Membership feature in mind, so it was obvious that some methods will need to be implemented. I have started coding. At first I have created MyMembershipProvider and inherited it from the MembershipProvider class. Next I have moved to implementing each method. Suppose that I have started with nothing more than an empty User class declaration. The first method to implement on the MyMembershipProvider was the ChangePassword method. I have started typing:

Note that there are no methods to chose from, so I start typing the desired method name:

Once I get to the end Visual Studio detects that there is no such method defined on the User class and offers me an option to generate it (using the smart tag - ALT+SHIFT+F10). Of course I use the feature and what I get in the User class is a static GetUset method with two string parameters named after the variables I have used. The method also returns a user object. It also throws an Exception with message that the method is not implemented (I wonder why not the NotImplementedException). I have implemented the whole MyMembershipProvider in such a way and it went really smothly.

It is not hard to imagine what would happen if the place I first write the GetUser method is in fact a test method and the whole implementation of MembershipProvider is in fact a NUnit TestFixture. We would have a test-first written fragment of code which is what TDD is all about.

I strongly encourage everyone to try this approach. It is not only possible but it also leads to a much cleaner solution with only those methods that you really need and not the ones you think you will probably sometime use.

kick it on dotnetkicks.com

Thursday, August 03, 2006 4:26:16 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Recently I have argued with one of my fellow developers. On the topic was the point of validating input parameters for null values. The standard practice is for a null valued parameter (that we do not expect to be null) to throw some kind of exception: ArgumentNullException - most likely. But what if we don’t check the parameter and let the execution flow? It is possible that in the few instructions, the null reference exception will occur.

Now what is the difference between those two kinds of exception? Ultimately both signal that something went in an unexpected way. they both halt the execution of the code etc. Why bother?

There are numerous reasons why you should bother some of them include:

  • ArgumentNullException is way more meaningful when it comes to finding out the cause of the problem. For one, it allows you to specify the name of the parameter - something the automatically thrown NullReferenceException does not.
  • Throwing earlier saves both memory and processor time since if ultimately we are going to get the exception it is better to get it before executing some possibly time consuming sub-routine. Additionally it is easier to rollback since there is nothing to rollback :-).
  • It is easier to debug the code. It is just a single line where you throw “connection cannot be null”. Compare this to a line where there are multiple instructions invoked as it often happens and you wonder which one of the calls caused the exception.
  • What are you going to tell the author of the component if you happen to not have the stack trace for the exception - just message? That their component is not good :-P.
  • I personally believe that it is a shame then one of my methods throws a null reference exception.

In the extreme case, you could want to forget about exceptions altogether but what would you say if .NET Framework was written in such a way? You wouldn’t be happy yes?

As for the very good description of how you should handle exceptions I suggest reading the chapter on exceptions in Jeffrey Richter’s book.

kick it on dotnetkicks.com

Thursday, August 03, 2006 4:15:56 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 

I have blogged about a working alternative to the ObjectDataSource control. One of the feature provided by my solution is the InternalSort mechanism. I will provide a short description here of how it works. The source code is packed together with my data source control (MyObjectDataSource.zip (30,43 KB)).

The SortUtility provides a generic capability to sort any collection of custom objects. It does so without changing the original collection. Internally it uses reflection to get the values of compared properties so in performance critical operations this utility should not be used. Otherwise it greatly simplifies development. Feel free to use it as you like and remember that feedback is always welcome.

Thursday, August 03, 2006 4:12:46 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have blogged about the problems with ObjectDataSource control and proposed two solutions neither of which was perfect. Today I will present a complete working solution. The code and .dll for this project is accessible here:MyObjectDataSource.zip (30,43 KB).

My solution deals with the problem of partially updating an object by providing a way for a developer to provide an instance of a business object on Updating event. Values read from the form are then transferred to this object. This solves the problem with properties not present on the form are reset to default because of the fact that object is constructed by the data source control. It also solves the problem with forcing the developer to provide a default constructor for each business object.

Unfortunately having to hook up to the Updating event would mean that instead of providing a default constructor, the developer would have to code the event handling method. This would not be such a big gain. Fortunately it is not necessary to provide the business object to the Update method by means of Updating event. If an object is not provided, it is retrieved using the Select method for which we already should have an implementation shouldn't we? Indeed we have, because otherwise how would we have displayed the object for editing in the first place? The only problem is that the select method should be able to accept the same number of parameters as was specified for the DataKeyNames property of the control which was bound to the data source control. This should not pose any problems since such a method will exist anyway in most cases.

Using the control is almost identical to using the ObjectDataSource control in that it requires you to specify the Select, Update, insert and Delete methods and a type name of an object providing those methods. Methods may be static or not. I wouldn't recommend using business objects for this. Rather create a separate classes to serve as a service layer for the control. Additionally the control makes a lot better use of DataObjectMethod attribute then ObjectDataSource. If a required Select, Update, Insert or Delete method name is not specified, the control will search for this method using the mentioned attribute. It will also automatically choose the method with required number of parameters. This make it super easy to build an application really fast.

The proposed solution I'm providing has one more feature which everyone should find really useful. This feature is called InternalSort and does just that - it is a generic sorting mechanism which will sort any strongly typed collection using a property specified in the sort expression. (reverse sort is also possible by adding DESC to the sort expression - ASP.NET does it automatically).

Ok, you ask: Where is the catch? One major inconvenience in using the control is that it does not have any support in form of designer. This makes it necessary work with it using the property editor. It also does not interact very well with controls such as FormView - i.e.: FormView does not generate templates given the configured data source control - like it would when used with ObjectDataSource.

If the described solution looks like it would help in developing your applications faster, feel free to use it. I only ask for one thing: a feedback. I would appreciate any kind of feedback: from "you suck" comments through "I would change this and this" to sending me free pizzas or some other stuff :-)

As a final note I have to say that while creating the control I was using the Reflector quite a lot to get to the guts of the original ObjectDataSource control and SqlDataSource. I have also used the sources of CSLA.NET by Rockford Lhotka, where there is an implementation of the DataSource control which works with the business objects of CSLA which is therefore not very generic.

kick it on dotnetkicks.com

Thursday, August 03, 2006 3:59:50 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have blogged about Problems with ObjectDataSource control some time ago. That was a problem I was aware of for some time now. It was until recently when I have come across yet another problem. This time it is with how the DataSource controls handle the SelectParameters. I'm mainly working with business objects so I have little experience using the SqlDataSource but from what I have seen it uses the same mechanism for specifying parameters. The problem is that you can only select a fixed number of parameter sources:

It often happens that you need to get a value from some other location such as a property on a page. What to do when such a need arises? Worry not! There is a solution. You will have to create your own class derived from the Parameter class from System.Web.UI.WebControls namespace. You will need to overwrite some of the methods. As an example I present the TemplateContainerParameter which makes it possible to use public properties defined on a page or a user control as a parameter providers.

public class TemplateControlParameter : Parameter
{
protected override object Evaluate(
HttpContext context, Control control)
{
if ((control == null) || (string.Empty.Equals(PropertyName)))
{ return null; }
TemplateControl templateControl = control.TemplateControl;
Type type = templateControl.GetType();
PropertyInfo property = type.GetProperty(PropertyName);
if (property == null)
{ return null; }
return property.GetValue(templateControl, null);
}
protected override Parameter Clone()
{
TemplateControlParameter parameter =
new TemplateControlParameter();
parameter.PropertyName = this.PropertyName;
return parameter;
}
public string PropertyName
{
get { return (string)ViewState["PropertyName"] ?? string.Empty; }
set
{
if (PropertyName != value)
{
ViewState["PropertyName"] = value;
base.OnParameterChanged();
}
}
}
}

The interesting part here is using the TemplateControl property which will return the reference to a nearest template control containing our parameter which in most cases will be either page or a user control. You can also create a parameter which always uses page properties:

protected override object Evaluate(
HttpContext context, Control control)
{
if ((context == null) || (string.Empty.Equals(PropertyName)))
{ return null; }
IHttpHandler handler = context.Handler;
Type type = handler.GetType();
PropertyInfo property = type.GetProperty(PropertyName);
if (property == null)
{ return null; }
return property.GetValue(handler, null);
}

Here the interesting part is using the Handler property of the context object which in most cases will return the reference to a page object but hidden behind the IHttpHandler interface. It does not mather though since we are getting the property value using Reflection.

The bad news is that you will not be able to use those custom parameters in the designer :-(. The 6 parameter sources shown on the picture above are hard-coded in the .NET Framework library (to my best knowledge). You have to resort to the html editor - as in many more cases, more than it should be necessary :-(.

kick it on dotnetkicks.com

Thursday, August 03, 2006 3:43:56 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

ASP.NET 2.0 comes bundled with a control called ObjectDataSource. At first it looks like it is a perfect solution for all OOP lovers like me. The problem is that in practice it is completly unusable.

There are several problems with the control, the greatest of which are the fact that all objects that are to be updated by the control are required to have a default, parameterless constructor since the Update method takes as a sole parameter the object of a specified type created by none other than the ObjectDataSource control.
(another method is to provide an update method that takes simple parameters representing updated object's properties such as name, age etc. but this solution is even worse since it requires separate methods for every combination of parameters, and defeats OOP feature - the inheritance - altogether).
Now where exactly is the problem? You may think hell I can go with having a default constructor on every object since I will probably need it anyway to support the [Serializable] attribute. But wait! There is one more problem with the control. It creates our business object and sets its the properties!!! Now what is wrong with that you ask? Once the business object is created ALL its fields are set to initial values such as null/1/1.0/false. Next, each property that was bound using the two way databinding mechanism (Bind) is set to a new value taken from the html form. This is of course ok. But what happens to the properties that were not bound using Bind? AHA! Now's the catch. They are not updated with any value and so we end up having a business object with only some of its properties set.

A more realistic example: given a business object User with properties such as Id, FirstName, LastName, Age, Login, Password and a form on which we use an ObjectDataSource control and a FormView control to edit just the Login and Password. Of course the FormView allows us to specify the DataKeyNames so the Id property will be preserved - we will need it to update the right record in the database. The form is first displayed and both textboxes are populated with user's Login and Password. User edits the data and decides to save them. On PostBack the magic happens and the ObjectDataSource creates a brand new User object, sets it Login and Password property with the new values from the form. Such an object is then passed to an Update method expecting a User object. But what to do with such an object? We cannot save it to the database since there is no way to determine if a given property's value is the default value or a value just set by someone and we cannot just save all the new values because that would mean loosing the data that was not edited.
In most cases we cannot even compare the property value with the default value for that property or the value from the database since given an Age=0 we cannot tell if it results from a user's setting or the fact that it was not set at all.

Now. There are multiple workarounds for this problem. One mentioned earlier is to use a separate Update method for each combination of parameters.
The other is a hack. It is possible to fool the ObjectDataSource so that it thinks it uses the parametrized Update method. It is necessary in order to get the Keys and Values from the form. If the Update method is used, there is no way of accessing those values. Next step is to intercept the Updating event. There you will have access to a collection of Keys and Values read from the form (accessible through the event args). You can than get the destination object from the database or from some other location, and copy the new values to its properties using Reflection. Once you have copied the new values to the business object you have a stiutation where the object is properly set: properties present on a form are updated, the other ones are set to the original values and not the default ones. There is just one problem. What to do with such an object and what about the parametrized method? We still need them yes? No! After copying the new values to a business object we have to clear the ObjectDataSourceMethodEventArgs's InputParameters collection and add to it just one parameter - our business object. The good news is that it is only after the Updating event when the propert Update method is selected to be called. The method is selected based on the InputParameters and since there is only one, the Update method expecting our business object will be used :-).

Example code:
void DataSourceControl_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
IOrderedDictionary inputParameters = e.InputParameters;
// Get the business object
object element = GetElement();
// Copy the values from the form to an object - the hard part
CopyValues(element, inputParameters);
// Clear the parameters list and add a single object to it
e.InputParameters.Clear();
e.InputParameters.Add("element", element);
}

To fool the ObjectDataSource control we have to delete DataObjectTypeName attribute but do it from the html view and forget about using the designer for edditing the control from there after.

Of course the above mentioned methods are not something I would recommend, but for a starter this is the only way I'm aware of you can use the ObjectDataSource. The other way is to write your own ObjectDataSource. This is exactly what I have done and will provide a complete solution in a few days.

Thursday, August 03, 2006 3:12:18 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  | 

I have posted an article in which I describe the PathsBuildProvider that reflects the local file system of a web application as a strongly typed class hierarchy. The most obvious benefit that the provider brings is that once you start to use it, you can say good bye to a 404 error resulting from Response.Redirect to a nonexisting page. It is ensured that the error will occure at compile time sine once there is no file, there is also no property on a class to use as a redirect target :-).

Thursday, August 03, 2006 2:57:36 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Some time ago I have found some articles about a feature of ASP.NET called the Build Providers. I especially liked the one about generating classes representing tables from the database. More on that one on Fritz Onion's blog.
Since then I have found numerous ways of using build providers to make my life easier. Today I have built a library that will greatly simplify keeping all Response.Redirect's up to date.



So without further ado I present the PathsBuildProvider.
Using it is as simple as placing a single file with ".pbp" extenstion in the "App_Code" directory and adding a build provider under the compilation section of of the "web.config" file and:


type="PathsBuildProvider.PathsBuildProvider" extension=".pbp"


The .pbp file should contain one word which will be used as a namespace for the generated types. If the file is empty this namespace will default to "Paths".
From now on you can type your namespace name and when you hit "." the name of the application should appear as the only choice. The instance of this class provides a way to access the names of all files located in the application folder in a strongly typed way i.e.: each file is represented by a property such as "Default_aspx". Such a property returns an absolute virtual path to a file so that it can be used in places sucha as Response.Redirect, or Server.MapPath.
Directories are also accessible by means of the properties prefixed with "_". Each directory provides access to its files and sub directories.


You can see an example of how it looks here:

 

 

I have put the code for the soulution here: PathsBuildProvider.zip (11,13 KB).

Keep in mind that the code is for demonstrational purposes only and as so it is not a production quality :-). Feel free to use it as you wish though. Any feedback is always welcome.

kick it on dotnetkicks.com and/or digg it and/or vote on it on dzone

Thursday, August 03, 2006 2:54:12 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 

The books that I would really recommend reading are:

ASP.NET and .NET Framework 1.1

An absoulte must read: either "Programming Microsoft ASP.NET" by Dino Esposito or "Essential ASP.NET With Examples in C#" by Fritz Onion. As a complementary read I would suggest reading "Developing Microsoft ASP.NET Server Controls and Components" by Nikhil Kothari and Vandana Datye. The last one gave me a very good insight on the life cycle of ASP.NET controls. It is especially valuable since there is currently no v2.0 edition :-(.
As for the basics of the .NET Framework, there are two books which you cannot live without and those are: "Programming Microsoft .NET" by Jeff Prosise and "Applied Microsoft .NET Framework Programming" by Jeffrey Richter in that order since the first one talks about all major features of the .NET Framework such as Windows Forms, ASP.NET, Remoting, Web Services and in doing so it does not go in to details. The other one details the inner plumbings of the .NET Framework describing the Intermediate Language, the Base Class Library. Especially good is the chapter on exception handling where the author talks a lot about best practices.

ASP.NET and .NET Framework 2.0

There are just few books I can recommend and those are: both Dino Esposito's books on ASP.NET: "Programming Microsoft ASP.NET 2.0 Core Reference" and "Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics". The second of those books I have yet to read but knowing the previous works by Dino I'm pretty sure it will be a good one. The same is true for the "CLR via C#, Second Edition" by Jeffrey Richter which is a 2.0 version of his previously mentioned book.

While speaking about books there are of course other books than those dealing with computers. In this field I would strongly recommend reading the Dragonlance series - all books by Margaret Weiss and Tracy Hickman and the Wheel of Time series by Robert Jordan.

Thursday, August 03, 2006 2:41:05 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I need to write about few things:

  1. ObjectDataSource control and my own implementation. (with source and binary) - DONE
  2. My implementation of DataMapper.(with source and binary)
  3. My validation component. (with source and binary)
  4. BuildProvider for generating classes to enable developers to redirect to pages in a strongly typed way. - DONE
  5. Bug in the DataList control that causes properties set in ItemDataBound event to be not persisted on postback.
  6. Working with object graphs, ObjectDataSource and base detail page.
  7. Creating a class for handling Session variable access. - DONE
  8. Something about VirtualPathProvider.
  9. Why bother with exceptions if ultimately what you get is an error. - DONE
  10. Recommended books. - DONE
  11. Antipatterns on all levels.
  12. Custom ObjectDataSource select parameters. - DONE
  13. Working on a project using rich domain model with developers of various levels of experience.
  14. Pair programming in practice.
  15. Woring with Db4o in ASP.NET projects.
  16. ReturnUrl pattern. - DONE
  17. Conditionaly hiding a column in a GridView control - declarative way.
  18. Benefits of switching from PHP to ASP.NET
  19. Control.HasControls() instead of Controls.Count.
  20. Position Absolute - Positioning Context. - DONE
  21. When is the Select method of the DataSource control called? - DONE

Thursday, August 03, 2006 2:33:04 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |