You mean my web app has to support characters other than English?!? – level 300

The time will come when some text or some data will need to contain foreign characters.  For me, this means Japanese Kanji text for a global application under development.  I need to use the following text: ??????????????. You are seeing question marks because .Text doesn’t support these characters in all places.

ASP.NET is unicode-based, so a lot of the work is done for me, but in order to work with this text, I have to make some changes to my development workstation and database (potentially).  First, I looked at the database, and the database was developed with a forward-thinking method, and all character fields are nchar or nvarchar, so SQL Server 2000 will be able to store all unicode characters without anything special.  I also had to check to make sure my stored procedures all used nvarchar and that no strings were ever converted to another codepage.  I was please to find the database in order, and I could store and retrieve this text.  With .Net, I was able to whip up a web app, and it just worked, but when looking at our existing application written with ASP & VB6 COM+, I found that it didn’t “just work”.  I separated the parts and discovered that I could call the COM+ pieces to store and retrieve this data, so the large part was taken care of.  Thank God VB6 supports unicode.  Of course, all that is happening is the transport of character codes.

The problem came with ASP making the call to COM+, getting information, but it was written to the page garbled.  After a lot of research, the fix was to set the CodePage that ASP uses to stream the response to the client.  This can be done in the header line with CodePage=”65001” – which is the unicode codepage, or I can use Response.CodePage = 65001 at the top of the ASP.  But header information also needed to be in the HTML page to display properly on the client, so I use Response.CharSet = “utf-8” to tell the browser to use this character set.  Doing this is every page did the trick, but I have a LOT of pages, so I set about looking for a global setting for the CodePage.  After a lot of searching, I found the AspCodePage IIS Metabase setting.  This is an obscure setting because we don’t normally have to change the IIS Metabase.  It’s kind of like a registry for IIS.  IIS Manager have GUI for some common settings, but this isn’t one of them.  I downloaded the IIS Metabase Explorer with the IIS 6.0 kit from Microsoft, and I was able to set this setting to 65001 for my application, and this affected all the pages in my app.

For good measure, I went ahead and added

<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>

to all my pages. 

It took me quite a while to educate myself on character sets because up to this point, I’d only had to deal with English.  It’s good education though.  I think all developers should know that text doesn’t always translate to normal ASCII codes.

ASP.NET base class refined for total control – level 300

In my last post, I wrote about creating an ASP.NET base class that is in complete control of its execution without the possibility of a derived page executing code when it shouldn’t.  With OOP, we can’t guarantee this if we are exposing virtual methods, but what I have done is laid a framework for developing aspx’s on top of this base page.  Some of my base page is below:

        protected Page()

{

base.Init +=new EventHandler(Page_Init);

base.Load +=new EventHandler(Page_Load);

base.PreRender +=new EventHandler(Page_PreRender);

base.Unload +=new EventHandler(Page_Unload);

}

public new event EventHandler Init;

protected new virtual void OnInit(EventArgs e)

{

Trace.Warn(“Begin Base OnInit”);

if(Init != null)

Init(this, e);

Trace.Warn(“End Base OnInit”);

}

private void Page_Init(object sender, EventArgs e)

{

Trace.Warn(“Begin Base Init”);

OnInit(e);

Trace.Warn(“End Base Init”);

}
Notice that I use the “new” keywork for OnInit as well.  This is so that if the aspx overrides the OnInit method, it still cannot execute code before the base page gets a chance to.  The base page reacts to the Init Event from its parent, executes some code, then calls its OnInit method (which raises this class’s Init event).  The aspx subscribes to its base class’s Init event.  The end developer experience is exactly the same, but what I do in my base class results in complete control of page executiong most of the time.  Most of the time the aspx will override On* methods and execute event handlers. 

ASP.NET base page that controls page executiong – level 300

Have you ever wanted to make an ASP.NET base page that controls execution of any aspx that inherits from it?  Like controlling exactly WHEN the Page_Load logic occurs?  Maybe logging the beginning and ending of the Load method.  I’ve come up with a way to do exactly that.  I’m not claiming that this is a unique idea, but it’s a very slick way to track and control the execution of all derived pages.

1:     protected new event EventHandler Load;

2: private void RaiseLoad(EventArgs e)

3: {

4: if(Load != null)

5: Load(this, e);

6: }

7: private void Page_Load(object sender, System.EventArgs e)

8: {

9: Trace.Warn(“Begin Load”);

10: RaiseLoad(e);

11: Trace.Warn(“End Load”);

12: }

13: Page()

14: {

15: base.Load+=new EventHandler(Page_Load);

16: }

Notice that I’m using the “new” keywork on my event.  This hides the real event and creates another of my own.  This method will trap the Load event from System.Web.UI.Page and then raise a new Load event that it completely controls.  It can do some work before and after this happens.  Now any aspx that derives from this will be executing within this framework.  When it subscribes to the Load event, it will be subscribing this this class’s load event.  You can also do this with the other events of the Control class.

Virtual Server uses VNC – level 200

I have used VPC 2004, and now I have Virtual Server 2005 installed on my second machine, and I have server images set up with all my different environments.  I’m installing Yukon right now.  I found it interesting that vServer 2005 uses the VNC standard for it’s remote server control.  This was a bit of a nuisance since I use RealVNC on the server anyway.  Virtual Server wanted to use port 5900, and RealVNC was already using it.  I configured vServer to use 5901, but apparently there is more than one configuration point because that broke the configuration page.  I ended up having to configure RealVNC to use a different port so vServer could function properly.  I love VPC 2004, and vServer enables me to use virtual PCs on a remote computer, so as long as I have the disk space, I can set up many different server environments.  It’s a great product.  The hard drive files are compatible between VPC and vServer, but the .vmc configuration files are not.   No biggie.  The hard disk file is what matters, so you can take an image on the road with your laptop by using VPC.

Another Content Management System (CMS) – level 200

I’ve noticed that there more content management systems popping up, and they are all written in .Net.  There’s the hugely famous, DotNetNuke, I’ve got one (EZWeb), David Neal has one, and isn’t .Text a CMS in itself?  How long will it be before they all merge, and we have a defacto standard CMS?  One that handles everything you could want?  Right now, CMSs are geared toward a particular nitch.  DNN is geared toward a multi-user portal.  Mine is geared toward managing a n-sized website with multiple users earch owning a part of the site.  DNN has modules, I have plugins.  They are both .Net user controls.  DNN is fully database-driven.  Mine has a web.config switch that can make it fully database-driven, or fully file-driven. 

It makes me wonder if ASP.NET 3.0 will have a CMS project built in that does it all “without a single line of code”. 🙂

With ADO.NET, if the DB schema changes, restart your app – level 200

Wow!  Hard-to-find bugs can really give you insight into how the .Net Framework works.  I recently just battled an elusive bug that turned out to be quite simple.  In a history table, I logged events.  Each event had a description that a user could type in.  Well, I noticed that longer descriptions were being cut off short.  I looked at the database and noticed that my nvarchar(50) field was the culprit.  So I just changed it to nvarchar(4000) to give the users the most flexibility.  I change the corresponding stored proc to mimic the new field length and then went to test the change.  No dice.  It still cut off my description.  What gives?

ADO.NET!!!  I use an ADO.NET command to call my stored procedure.  The description was being truncated in the ADO call.  I restarted the app, and it worked fine.  ADO caches information about sproc parameters, and I had to restart the app for that cache to be recreated with the new length.

Sauce Reader is my favorite RSS Reader – level 000

Sauce Reader v1.8 (BETA)

Sauce Reader v1.8 is now available for download.


I had been using RSS Bandit, and I was pretty satisfied, but I’m using Sauce Reader now, and it is just amazing.  No longer do I even have to click on a title to read a post, because it previews them for me.  I can now easily post to my own blog right from the reader and write comments right from the reader.  I know this is possible with other readers, but it is completely intuitive with Sauce Reader.

It also looks just like the Outlook 2003 UI.

MSDN – “. . . all without writing a single line of code.” – level 100

Scott Stewart laments what he saw at his local MSDN event, and I have to say that I experienced the same thing at the Austin, TX MSDN event.  I, too, like writing code, and I tend not to use the designer to much.  Back in the days of FrontPage and Interdev, I didn’t use the designer.  I found that I had to tweak the designers code anyway, so it didn’t take me long to write the code myself. 

I think what Microsoft is trying to showcase is that ASP.NET 2.0 reduces a whole lot of plumbing, and while the designers help, they don’t actually write any code.  If the designers wrote code, it would be in the .cs class.  In v1.1 we have “Designer-generated code don’t touch”, but that doesn’t exist in 2.0 because of partial classes.  and pulling more functionality into the base classes.  The new GridView control supports sorting and paging through properties.  Now, the designer will write the markup for you, but it just sets the appropriate properties.  In the DataGrid, we have to write sorting and paging code (just a few lines), but the GridView abstracts that into the control so we don’t even have to do that.  I think the changes are better, and writing less code is better, but I know that I will always have to write code because there isn’t a way that a designer can write my business logic. 

Sure we’ll see some newbies that will hammer out something that works with the designer, and it may work fine for a small company, but as soon as the requirements get a little more complex, the need to actually type the code will be apparant.

Just by adding features to the language and the .Net Framework, Microsoft is meeting the needs of enterprise developers like us, Scott, but it seems to me that the MSDN events are really touting the hobbyist and RAD features that it adding on top of the features you and I use.

If I ever took a test on the RAD features in VS or the designers, I’d fail.  But I know exactly what code is generated by them because I write it every day. (Except for DataSet-DataAdapter stuff – I tend to use a DataReader to populate my custom objects).

RegisterClientScriptBlock() incompatibility in .Net v2.0 Beta 1 – level 100

This may impact many people because it is a change in the validation of the parameters of this method.  The method is defined below:

RegisterClientScriptBlock(string key, string script);

In .Net 1.1, the key parameter could not be null, but it COULD be a zero-length string.  In .Net 2.0 Beta 1, this parameter is validated so that an empty string is not valid input.  It throws an exception. 

Maybe a validation change for the better, but a breaking change none-the-less.