Tuesday, August 07, 2007

ASP.NET Ajax comes with a nice way to attach to a load event of a page. To do it just call Sys.Application.add_load and pass it a function as an argument. Done. Everything works as expected... WRONG!

It comes out that add_load fires on each callback and not only when the page loads for the first time. That is of course a problem if you want something to happen on page load only.

From what I've been able to learn, this behavior is by design. Although it is never mentioned in a strigh forward way in a description:

"Raised after all scripts have been loaded and after the objects in the application have been created and initialized."

There are some places in the documentation, that suggests that this is a way it was intended to be. First of all, ASP.NET Ajax tries to mimic that ASP.NET Page life cycle and as such, fires the load event every time there is a callback. The other thing that makes me believe, that load's behavior is there by design is this:

"You can use the event arguments to determine whether the page is being refreshed as a result of a partial-page update and what components were created since the previous load event was raised."

So now I know, but I still cannot accept the naming convention. Sys.Application plainly suggests, it's a kind of singleton, and not a per load thingy.

Tuesday, August 07, 2007 12:18:19 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 
 Friday, July 20, 2007

For a couple of months now I've been running Windows Vista and Visual Studio 2005 without major problems (other than the commonly known ones). Since the first day of this setup I have been working on solutions that inlcude from one to many ASP.NET web applications. All of them are configured to use IIS rather than the built in web server. For all that time, everything was working fine until recently...

One of those days, while opening one of the solutions in Visual Studio, I was presented with a message telling me that my site is configured to use ASP.NET 1.1:

---------------------------
Microsoft Visual Studio
---------------------------
The site 'http://localhost/WebSite' is currently configured for use with ASP.NET 1.1.4322.573. Microsoft Visual Studio has been designed for use with ASP.NET 2.0; if not configured some features may make incorrect assumptions, and pages designed with the tool may not render correctly.

Would you like the site to be configured for use with ASP.NET 2.0?
---------------------------
Yes   No   Cancel   Help  
---------------------------

Needles to say that there were no changes made to IIS configuration of Application Pools or the pool the site is running on, but just to be sure, I've checked IIS Manager. The pool for the site was ASP.NET V2.0. I have agreed and allowed Visual Studio to make the "necessary" change. Needles to say, that nothing was changed in scope of application pools by Visual Studio. Fortunately, my solution kept working after that... for few days.

After few days I've got the very same message. Again, nothing was changed in IIS. This time I decided to leave my supposedly ASP.NET 1.1 in place. Of course everything worked after that also. Including debugging! But then I have the same message every time I open any of the solutions :-(.

I have found that other people also had this problem, and "aspnet_regiis -i" helped them, but it doesn't work for me :-(

Today I noticed that it gets worse. Now I get the message every time I open any of my solutions that include web sites :-(

Friday, July 20, 2007 2:05:07 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 
 Sunday, July 15, 2007

ASP.NET despite its many nice features, has also a lot of nasty ones. Some of them are critical - like a design flaw in the way controls are rendered - by the controls themselves (only in version ASP.NET 2.0 Microsoft introduced the concept of Adapters, but this thing is beyond repair. There is just to much logic already in Render methods of all the existing controls to make using adapters easy). Others are just plain annoying, but we mostly we can live with them and even find workarounds.

Today I simply had enough of the style="border-width:0px;" attribute that ASP.NET adds to every img tag it renders from the Image control. There is strightforward way (that I know of) to remove this thing! Try as you might, there will always be a border-width style attribute on you images with either 0px, or whatever value you assign in you ASPX file. But there is a workaround.

To make the border style gone, we have to create our own Image control (inheriting controls is usually a good thing). In this control we have to resort to a trick of overriding the BorderWidth property by returning anything other than Unit.Empty:

public override Unit BorderWidth
{
    get { return Unit.Pixel(0); }
    set { ; }
}

This will cause the border style not to be rendered at all. Additional side effect which is obvious when looking at the above code is that now it is impossible to set BorderWidth property in any way. The value will alwyas be Unit.Pixel(0). This is also a good thing since we really shouldn't set any of the style properties inline but rather use a css style sheets for this purpose.

Sunday, July 15, 2007 2:39:59 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [6]  | 
 Saturday, July 14, 2007

From time to time, there is a need to get something from a file system in our ASP.NET applications. In those cases, we use the Server.MapPath() call on our pages classes. But what about class libraries?

Usually in class libraries in order to get the physical path of a file on disk we can use something like HttpContext.Current.Server.MapPath() and it works as long as there is a context i.e.: HttpContext.Current is not null. Sometimes however it may happen that there is a task running on the server which does some work without any request being processed. What then?

Enter the HostingEnvironment.MapPath() method where HostingEnvironment is a class defined in System.Web.Hosting namespace. It works the same way, as Server.MapPath() but it is a static method requiring no context to be present.

Saturday, July 14, 2007 5:46:21 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
 Thursday, July 12, 2007

ASP.NET Pages offer us a declarative way to set some of the properties such as Theme, MasterPageFile or Title in the Page directive. A nice feature indeed. The problem is that the same ASP.NET or maybe the Web Forms framework and Visual Studio stand in our way when we try to set our custom properties this way. It is possible but not developer friendly in a least.

To do it, we have to use the CodeFileBaseClass property and set it to the same base class that our page inherits from. More on this on K. Scott Allen's blog. Although it is technically possible to set this attribute to some class upper in the hierarchy I have encountered random weird behavior of Visual Studio after doing so. To be safe it is better to use the same base class both in the inheritance and in the CodeFileBaseClass attribute.

What about generic types? The tool (Visual Studio) support for generic types has never been great (not to say there is virtually no support). The fact that Visual Studio makes it hard to use CodeFileBaseClass difficult does not make it easier when it comes to generic base pages, but it can be done!

Suppose we have a type in the App_Code directory:

public class MyType
{
}
And also, defined in the same directory, we have a base page class:
public abstract class BasePage<T> : Page
{
}

And finally there is a Default.aspx page in the project that inherits from the our BasePage class:

public partial class _Default : BasePage<MyType>
{
}

Obviously we cannot just put a type name as BasePage:

CodeFileBaseClass="BasePage"

It won't work, because there is no such type. The message is: "Could not load type 'BasePage'". Our type is generic so we have to use it's full name:

CodeFileBaseClass="BasePage<MyType>"

But this also won't work. It will fail with the same message. That's becuse it is a C# specific representation of a generic type name. What CLR sees is something different. In order to make it work with a generic class we have to lower ourselves to the CLR level and use it's notation. This would mean using something like:

CodeFileBaseClass="BasePage`1[[MyTypebecause]]"

This thing actually works! If your types reside in some kind of namespace, has many generic parameters or worse yet, is part of a strongly named assembly, the whole CodeFileBaseClass starts to look scary and I don't think it is worth it. There is a trick however that may civilize the thing you enter in CodeFileBaseClass that allows to use any kind of base page class without making it complex. Just create an intermediate class like this:

public class StandardBasePage : BasePage<MyType>
{
}

and inherit your page from it. Than you can use this new type's name in CodeFileBaseClass without having to deal with generic parameter issues.

kick it on DotNetKicks.com

Thursday, July 12, 2007 4:56:35 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, July 11, 2007

Since my first days of using Windows Vista I have noticed that the "Documents and Settings" folder is somewhat different than it used to be in Windows XP. The main difference is that it no longer exists. Not as a directory at least. The new place for your-everything is now the Users folder - a good choice if you ask me - I've never liked the long name with spaces inside. But how are all the applications that rely on "Documents and Settings" supposed to work? And what is the "Document and Settings" "folder" that we see on our disks?

The answer is simple: symbolic link. A thing that every Linux user knows and loves. A thing that is almost never used on Windows platform.

I have noticed that there are two types of "symbolic links" in use in Windows Vista. If you go to the Users directory using command line and invoke a "dir /a" command, you will get an output similar to the following one:

2007-05-16  17:06    <DIR>          .
2007-05-16  17:06    <DIR>          ..
2006-11-02  15:02    <SYMLINKD>     All Users [C:\ProgramData]
2006-11-02  15:02    <DIR>          Default
2006-11-02  15:02    <JUNCTION>     Default User [C:\Users\Default]
2006-11-02  14:50               174 desktop.ini
2007-07-11  21:13    <DIR>          mikeon
2006-11-02  14:50    <DIR>          Public

Notice that the <SYMLINKD> and <JUNCTION>. From what I've been able to learn, the <SYMLINKD> is the new feature in Windows Vista, that replaces the old <JUNCTION>.

So how to create a symbolic link? I've found no way to do it using GUI. The only way I have found is the command line tool "mklink".

Beware however, before using this feature. Some people report that it may not be 100% transparent for your application code. So if you try to get something from "Document and Settings" it may not be there.

Wednesday, July 11, 2007 9:12:10 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
 Monday, July 09, 2007

There is a very useful feature in Visual Studio since I remember. It is accessible through Debug->Exceptions... menu item. It allows you to specify when you want the debugger to break. By default, it is when an exception is unhandled, but to make sure, everything works as expected, I often turn the when thrown option on. This allows me to detect all exceptions that are thrown in my code, even those that I handle but shouldn't.

Normally the Exceptions window looks like this:

But for some unknown reason, mine looked like this:

Notice that there is no User-Unhandled checkbox column. For some reason I just needed to have this column so I went searchin over the internet, and I have found that the reason for not having the checkbox column for User-Unhandled exceptions is the setting I have made in some other part of Visual Studio: Tools->Options...->Debugging->General->Enable Just My Code (Managed Only).

After checking the above mentioned option, the checkbox was back!

Monday, July 09, 2007 12:33:00 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
 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]  |