December 2003 - Posts

Upcoming MSDN Magazine articles
22 December 03 12:42 PM | despos | 5 comment(s)

Have you checked the Extend the ASP.NET DataGrid with Client-side Behaviors article on MSDN Magazine? It shows how a IE5 behavior (in general, script code) can add drag-and-drop capabilities to a DataGrid control. Any feedback you want to share? I think I'll post soon about DHTML and ASP.NET...

In the February 2004 installment, the Cutting Edge column on MSDN Magazine will feature graphic menu a-la Office 2003 and owner-draw in .NET. I endeavoured to make it work on top of existing menus so that it has a minimal impact on existing apps.

In the March 2004 installment, instead, I'll cover personalization in ASP.NET 1.x. I confess I've taken the shortest (and simplest) route in doing that. So don't expect to find advanced features like dynamic class compilation. It's really hard to accomplish in ASP.NET 1.x. Not impossible but it requires a big effort and probably requires some assumptions about web.config and permissions. I'm currently working on it in the perspective of a couple of projects. I'll post here any significant result. However, I spoke to Rob Howard about this and he confirmed my concerns. In ASP.NET 2.0, the new compilation model makes dynamic class compilation much easier...

 

 

 

 

 

 

Enjoyed the Process API in .NET
22 December 03 10:54 AM | despos | 1 comment(s)

The Process API in the .NET Framework is really well designed. I'm talking about 1.x. Basically, it integrates in a single class--Process--the functionality of the Win32 process API, the shell, and also the notorious ToolHelp API. In addition, it has a few gems like the Responding property and the WaitForExit method. The former sends a timeout message to the main window of the process. If it doesn't get a reply within 5 seconds, it concludes that the process is gone and not responding. The WaitForExit method simply stops the current thread until the spawned process terminates. The code you need is as simple as

Dim p As New Process
p = Process.Start("notepad.exe")
p.WaitForExit()

Another little known but useful feature is associated with the SynchronizingObject property. The Process class has an event named Exited that fires when a process terminates. If you handle this event, chances are that you then need to update the user interface of a Windows Forms application.

Windows Forms applications are STA apps and nothing guarantees that the thread in charge of the Exited event is the same that created the Windows Forms control you need to refresh. Make the SynchronizingObject property point to the control you will work with, and the Process class will automatically marshal the call from thread to thread with the certainty--for you--that no delay, no anomalies, no exceptions occur.

Capturing the output of a console program is much easier than before.

I've just sent an article on this topic to Code Magazine. It should be published in the next few months.

SQL Server Yukon and SqlCacheDependency
22 December 03 10:50 AM | despos | with no comments

The SqlCacheDependency class works differently according to the underlying version of SQL Server. If it works with SQL Server 7.0 or 2000, it can only detect changes on a table. Any change to the table invalidates a Cache item implicitly bound to it. If you work with SQL Server Yukon, then things are a bit different.

In SQL Server Yukon, you can exercise a finer control over the monitored data. In particular, you can detect changes only on the output generated by a particular, cross-table query. This capability descends from a new Yukon feature--command notification.

Whenever something happens to the involved tables that modifies the output of the command, a notification is automatically sent to caller. The caller this time is just the SqlCacheDependency class. Internally, the SqlCacheDependency class handles the notification event and bubbles it up to the Cache object through a new method defined on the new Whidbey's CacheDependency class.

All in all, I find that the custom CacheDependency mechanism is quite complex, though workable.

In ASP.NET 1.x it is tailor-made for files and other cache keys and works great. But that mechanism wasn't designed to be extensible.

In ASP.NET 2.0, the whole thing can be extended but it is better if your items are dependent on a resource that can send asynchronous notifications (like the Yukon's command notification or a message queue). Otherwise, polling is the only way to go and can be tricky, if not boring.

However, this is just my early feeling about the technology.


 

More on CacheDependency 2.0
22 December 03 10:47 AM | despos | with no comments

A traditional file-based cache dependency (like that available in ASP.NET 1.x) uses the file notification change mechanism and asynchronously receive an event when the file system detects a change to the timestamp of a particular file or folder.

In ASP.NET 2.0, a custom CacheDependency object will be responsible for detecting any changes that affect the controlled item(s). The behavior of the object depends on the characteristics of the invalidation mechanism of choice. For example, the SqlCacheDependency class uses a timer and polls a built-in, helper table for changes. When instantiated, the class does some work on the database that contains the table to monitor. This work includes creating an helper table to track changes and a trigger to detect changes to all the tables in the database.

  1. Administratively or programmatically configure the database (e.g., Northwind) to support notification. This entails creating a helper table and adding a trigger
  2. The helper table will contain one row per each table in the database to monitor
  3. Programmatically define the table to monitor (e.g., Employees)

The trigger writes to the helper table after each update operation that involves the monitored table(s).

The polling mechanism just looks for changes in the helper database using the table name as the key. The SqlCacheDependency class periodically accesses the helper table, reads a column that indicates if changes occurred, and invalidates the cached item.

When created, each SQL cache dependency object is made dependent upon an helper Cache key, whose name depends on the table and the database. When the SqlCacheDependency object detects a change in the monitored table, it deletes the helper Cache item thus invalidating the item in turn to the SQL Server table.

In the end, a custom cache dependency object is always bound to a helper cache entry that is created and maintained just to invalidate the cached data. And polling is essential for the success of the implementation.

Sounds a bit complex? This is what we need to know and do to implement a custom cache dependency object in ASP.NET 2.0.

Unless we're so fortunate to bind to a resource that has some sort of built-in notification framework. Want an example? SQL Server Yukon or a message queue system.

More in a moment...

 

ACL in ASP.NET
22 December 03 10:40 AM | despos | 11 comment(s)

Suppose you need to set programmatically the ACL of a file in a .NET application. For example, ensure that a certain XML file deployed with your new ASP.NET application allows the ASPNET user  (or NetworkService or any other particular user) to edit it. In most cases, the administrator will be more than happy (so to speak...) to take care of it and change the ACL for you.

However, should you have the need to accomplish that task programmatically, be ready to face a bad and a good news. The bad news is that you must necessarily resort to Win32 API calls and in particular to the SetNamedSecurityInfo API function from advapi32.dll. Neither version 1.0 of the Framework, nor 1.1, and probably not even Whidbey, will provide a redesigned managed API for system security.

In the end, either you write a managed wrapper for the API (sample code is available at http://www.gotdotnet.com/team/csharp/code/default.aspx) or resort to an extremely handy tool that ships with the operating system: cacls.exe.

cacls.exe [resource] /E /G: [user_account]:F

The /E switch indicates that you want to edit the security descriptor, not replace it. The /G switch indicates that you want to add a new user to the group with the specified privileges. If the specified user exists in the group, the existing account is modified. The F argument means that you want to give the account full control over the specified resource.

This is exactly what ASP.NET applications need for a smooth setup if they need to deploy writable files. The best way to integrate this code with the setup is by defining a custom action on the Visual Studio .NET setup project and use that command line for it.

PS1: I was told that the setup of ASP.NET itself uses this trick
PS2: cacls.exe is pronounced "cackles"

Cackles is vaguely similar to an Italian word that indicates the delicate art of keeping the nose clean. What do security API and snot have in common? When you're done with both, you definitely feel better :-)

 

 

 

Spam and other delicacies
22 December 03 10:32 AM | despos | 4 comment(s)

Rich Strahl said that Spam is a Hawaiian delicacy. I don't think Rick meant all spammers are from Honolulu and environs :-)

Hawaii is one of the places that I wish I visit one day. Others are Alaska, Iceland, West Canada, and I'd like to return to Australia too. Sounds like a nice tour

Every Christmas time I repeat to myself that I would like to pass holidays comfortably surrounded by a wall of 50 inches of snow. In alternative, I'd also enjoy a Christmas swim in a tropical sea. As usual, instead, I'm only allowed to visit parents and in-laws. 

If you hear of any conference being held in the above places, don't hesitate to send a personal email with high priority. I can also allow for 5 MB of (useless) attachments and even for 10 spam messages.

PS1: training is fine as well :-)
PS2: feel free to set up a show on purpose :-)
PS3: yeah ... vacations
PS4: it's beyond human imagination what my kids could do when stuck for 10 hours on a plane


 

Updated Code: Freeze the Header, Scroll the Grid
12 December 03 12:47 PM | despos | 16 comment(s)

If you downloaded the source code for this aspnetPRO Magazine article, you probably missed the source code of the custom control the article is all about. In this case, retry today and get the correct ZIP.

The article discusses how to build an automatic, self-contained mechanism to make a grid of data scroll within a browser. Basically, I'll accomplish it by extending the DataGrid control to support scrollable areas while preserving the same capabilities and programming facilities for the base class.

To make the content of a Web control scroll, you simply have to wrap it in a

tag, assign an explicit height to the block, and set the overflow CSS attribute to auto. For a DataGrid, in particular, this poses the problem of the header and the footer. (The pager is reasonably set aside because you don't want a pager if you scroll the grid.) Unless ad hoc measures are taken, the header and the footer will scroll with the rest of the grid. To make it short, to obtain what's in the figure below you need some extra work. (Which can be tricky and challenging.)

Note that in order to read the article you need a subscription to the aspnetPRO Magazine and must enter your subscriber ID.

 

Free Newsletter: Whidbey Watcher
11 December 03 03:15 PM | despos | 1 comment(s)

Whidbey Watcher

As far as I know, this is going to be the first free newsletter about Whidbey. To make sure you get it, rush to the Code Architects web site and set up your free account. Only a few seats available...

(just kidding...)

The newsletter will start hitting your inbox quite soon, but I don't know when exactly. I think it is a matter of a few weeks. In the mean time, you can download any utility or tool you like.

The Whidbey Watcher will cover a range of technologies including ASP.NET 2.0, .NET Framework 2.0, Yukon, Longhorn. I won't be the only writer. Francesco Balena and Marco Bellinaso won't made you lack their valuable contribution. We plan to send it out on a monthly basis, maybe twice a month. Ready to ship articles should be about personalization, Web parts and master pages in ASP.NET 2.0.

Again, let me and Code Architects have your feedback.

PS: to start sending excellent feedback, you don't necessarily have to wait for us to send the newsletter...

 

 

Free Newsletter: ASP.NET-2-The-Max
11 December 03 03:06 PM | despos | 1 comment(s)

ASP.NET-2-The-Max

Twice a month I write a free ASP.NET newsletter you can get through the Windows Developer Network channel or, more simply, by just clicking here. The newsletter titles ASP.NET-2-The-Max  and covers ASP.NET 1.1 topics. The latest went out a couple of days ago (I think it's the 9th and the 23rd of each month) and was about ASP.NET 2.0 highlights. However, I don't plan to write more about 2.0 in the future of this newsletter. Upcoming editions will cover state management in custom controls and the implementation of cookieless sessions.

Don't let me run short of feedback...

 

 

Code Fix: Custom Extender Provider
11 December 03 02:47 PM | despos | 4 comment(s)

In the November 2003 issue of MSDN Magazine, I wrote about Windows Forms extenders, how to use existing ones (Tooltip, HelpProvider) and how to design and implement your own ones.

I designed a textbox extender that adds a background and foreground color for when the textbox gets the focus. Again, a bug sneakily slipstreamed in the code.

When you select the control at design-time and try to edit the values of the new properties, a "Object reference not found" message appears in the property grid. The code, though, works.

The bug is due to the fact that the get accessor of both extender properties doesn't check whether the an instance of the extended control has been placed in the helper hash table. The hashtable contains textbox/properties pairs which allows you to differentiate colors for each instance of the textbox control. Use the following code to replace GetSelectedBackColor and SetSelectedBackColor.

public Color GetSelectedBackColor(Control control)
{
   // Retrieve the textbox info (and add if not there)
   TextBoxInfo info = GetTextBoxInfo(control);
   return info.SelectedBackColor;
}

// SET--SelectedBackColor
public void SetSelectedBackColor(Control control, Color selColor)
{
   // Retrieve the textbox info (and add if not there)
   TextBoxInfo info = GetTextBoxInfo(control);

   // Store the new value
   info.SelectedBackColor = selColor;

   // If not already done, wire events up
   if (!info.EventWired)
   {
      TextBox t = (TextBox) control;
      t.GotFocus += new EventHandler(TextBox_GotFocus);
      t.LostFocus += new EventHandler(TextBox_LostFocus);
      info.EventWired = true;
   }
}

private TextBoxInfo GetTextBoxInfo(Control control)
{
   TextBoxInfo info;
   TextBox t = (TextBox) control;
   if (!Extendees.ContainsKey(t))
   {
      info = new TextBoxInfo();
      Extendees[t] = info;
   }
   else
      info = (TextBoxInfo) Extendees[t];

   return info;
}

In addition, add the GetTextBoxInfo function and apply the same changes to GetSelectedForeColor and SetSelectedForeColor.

 

More Posts Next page »