Syndication

News

     

Archives

Miscelaneous

Programming

July 2004 - Posts

Note: this entry has moved.

All MVPs now have greater visibility through the MVP community home page. It's cool to have our profiles in the public, endorsed by MS.

Some functionality is missing on the site, however. First and foremost, the URLs provided are clearly unsuitable for email signatures, newsgroup posts, etc. Imagine my signature with this url:
http://www.microsoft.com/communities/mvp/mvpdetails.mspx?Params=%7eCMTYDataSvcParams%5e%7earg+Name%3d%22guid%22+Value%3d%222d3626a6-dede-4abd-9e59-aa4807125a47%22%2f%5e%7esParams%5e%7e%2fsParams%5e%7e%2fCMTYDataSvcParams%5e
Ruined, completely. So, instead of complaining about how bad it is, we've provided short URLs for all profiles visible through the MVP Community site. You just use your name as it appears on that site, without spaces, with the following format: http://aspnet2.com/mvp.ashx?DanielCazzulino or
http://aspnet2.com/mvp.ashx?VictorGarciaAprea.

Alternatively, you can write us (webmaster at NO aspnet2 SPAM dot PLZ com) to add an alias for your link too, such as: http://aspnet2.com/mvp.ashx?donxml or http://aspnet2.com/mvp.ashx?olegt.

Finally, and almost as important, we've also provided search functionality. If you just go to http://aspnet2.com/mvp.ashx, or pass a non-existent MVP name or alias, you can search for the MVP you are looking for, even in a particular category.
If you just made your profile public and want this "database" to be updated with your profile, just send an email to webmaster at NO aspnet2 SPAM dot PLZ com

I hope this is useful to all MVPs, as well as those looking for a guy with recognized expertise in a particular technology. It's already useful to me for sure!
Daniel Cazzulino [MVP XML]

Posted by Daniel Cazzulino | 2 comment(s)
Filed under:

Note: this entry has moved.

The usual approach to custom role-based security using forms authentication (i.e. roles and users fetched from a database) on web apps is the following:

protected void Application_AuthenticateRequest(Object sender, EventArgs e) { // Only replace the context if it has already been handled // by forms authentication module (user is authenticated) if (Context.Request.IsAuthenticated) { string roles[]; // Fetch roles from the database somehow. // Reuse the identity created by Forms authentication. GenericPrincipal ppal = new GenericPrincipal( Context.User.Identity, roles); Context.User = ppal; } }

There's one *huge* drawback to this approach, and it's that it will hit the database on every single request! So, the proposed improved solution is:

protected void Application_AuthenticateRequest(Object sender, EventArgs e) { if (Context.Request.IsAuthenticated) { // Retrieve user's identity from context user FormsIdentity ident = (FormsIdentity) Context.User.Identity; // Retrieve roles from the authentication ticket userdata field string[] roles = ident.Ticket.UserData.Split('|'); // If we didn't load the roles before, go to the DB if (roles[0].Length == 0) { // Fetch roles from the database somehow. // Store roles inside the Forms ticket. FormsAuthenticationTicket newticket = new FormsAuthenticationTicket( ident.Ticket.Version, ident.Ticket.Name, ident.Ticket.IssueDate, ident.Ticket.Expiration, ident.Ticket.IsPersistent, String.Join("|", roles), ident.Ticket.CookiePath); // Create the cookie. HttpCookie authCookie = new HttpCookie( FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(newticket)); authCookie.Path = FormsAuthentication.FormsCookiePath + "; HttpOnly; noScriptAccess"; authCookie.Secure = FormsAuthentication.RequireSSL; if (newticket.IsPersistent) authCookie.Expires = newticket.Expiration; Context.Response.Cookies.Add(authCookie); } // Create principal and attach to user Context.User = new System.Security.Principal.GenericPrincipal(ident, roles); } }

The new version only goes to the DB once. It also uses the same encryption features of forms authentication, as well as its ticket and cookie. A huge performance boost, that's for sure.

Thanks to Hernan for pointing this out while reviewing the security chapter of my last book.

Posted by Daniel Cazzulino | 14 comment(s)
Filed under: ,

Note: this entry has moved.

I'm reading PAG guide on Improving .NET Application Performance and Scalability (a must-read for every .NET developer), and I noticed they missed one of the most interesting and useful state management features ASP.NET introduced, the one I call transient state. This is the state that lives in HttpContext.Items, which only lasts for the duration of the current request, hence its characteristic of "transient". It's really awesome because you can pass information between modules, pages and controls with it, and completely avoid Session state. It's quickly discarded as soon as the current request has finished processing, so it doesn't impose any of the drawbacks you need to care about with Session.

In my experience, a combination of HttpContext.Items and the Cache API almost completely removes the need to use Session at all. And this is a good thing, as you're also avoiding server affinity resulting from inproc session state (the only one that performs well, BTW).

Too bad it didn't make into that excelent guide :(
Posted by Daniel Cazzulino | 1 comment(s)
Filed under: ,

Note: this entry has moved.

Whenever you drag a component on a web form, you get that nice area below the web forms designer, where these components can add designer verbs, extend controls on the design surface through IExtenderProvider, etc.
This extremely cool functionality has vanished in Whidbey. Please vote the bug to bring it back!!!

Note: this entry has moved.

You will get this error message if you try to connect to a SQL Server 2000 database from Whidbey (either an app or the Server Explorer in the IDE) using a dot or (local) as the server name (i.e. data source=. in connection string).
This works in previous versions of .NET. I have no idea why it doesn't work anymore. You have to replace it with localhost.

Note: this entry has moved.

The Shadowfax Visual Studio Wizards are built on top of a managed framework for constructing wizards automatically from configuration files. When the source code for the wizards is released, you'll see that there's minimum code in them, mostly for those parts of the wizard that actually need to modify information on the current solution, called Commands. The whole wizard UI is built from the configuration file.

So let's see this XML format to see what's possible with the framework.

Configuration

Wizard definition file has the following main sections:

 

- <wizard>

--  <typeDefinitions> ?

--  <step> +

 

<wizard>

Root element of config. Contains the following attributes:

 

Attribute

Description

title

A title shown in the initial wizard page.

description

Full description of what the wizard does, shown in initial page.

type

Full type name of class inheriting from Wizard or reference to a TypeDefinition. If not specified, defaults to the built-in provided form. Optional.

prompt

An arbitrary text to show the user to confirm execution of the wizard. May warn about pre-requisites.

 

Title and description are shown as follows:

 

 

A custom form can be developed and plugged using the Type attribute.

State is kept in a simple IDictionary.

 

<typeDefinitions>

This element contains any number of <typeDefinition> child elements, to create aliases to repeated types being used in the file, having the following attributes:

 

Attribute

Description

name

A alias to assign to this type.

type

The full type name.

 

At any place in the configuration file, all attributes expecting a type can either specify a fully qualified type name, or an alias referring to these type definitions.

 

<step>

This element defines each visual step that will be available in the wizard. Steps are visualized through the Next | Previous buttons in the wizard form. It has the following attributes:

 

Attribute

Description

title

The title of the step.

description

A description of what this step does.

tip

A tip to show to the user about the current step. Optional.

type

Full type name of class inheriting from Step or reference to a TypeDefinition. If not specified, defaults to the built-in provided step. Optional.

dependsOn

An expression that determines whether the step should be shown or skipped.

 

They are laid out as follows:

 

dependsOn

Some steps may only be executed under certain conditions. For example, a step may collect additional values if a previous step has a certain value, or if an option (such as a radio button) was selected.

This attribute allows for such conditional execution through a reduced conditional (i.e. "if") expression with the following format:

 

([not] ArgumentName [ ( = | < | > | >= | <= | != ) VALUE ] [ ( and | or ) ])*

 

That is, an argument name, optionally preceded by the "not" negation, optionally followed by a value comparison (currently only string value comparisons supported) and any number of "and" or "or" operators chaining multiple argument checks. Operators are not case sensitive.

Semantics for an argument name in the expression is the same as for XPath boolean function: if the argument is not defined or it is null, it evaluates to false. If it's present and its not a boolean, it evaluates to true, unless it's a string and its length is zero. Otherwise, the actual boolean value.

 

Examples:

 

Transport = 'WebServiceTransport'    

 

Depends on a specific string value in an argument

 

MessageQueueTransport or MSMQDispatchingTransport

 

Depends on any of the two arguments to be specified, and if any of them is, to evaluate to true according to the rules for boolean evaluation.

 

WebServiceName

 

Depends on the argument to exist and actually have a value, subject to the rules for boolean evaluation.

 

A step contains the definition of arguments to collect from the user. Arguments can optionally be arranged in option groups (exclusive boolean arguments, i.e. a RadioButton group) or regular groups, with a title such as the one shown in the previous screenshot. Also, the step may contain one or more commands to be executed before moving to the next step (or upon finishing the wizard). Full definition is as follows:

 

- <step>

--  <optionGroup> *
---   <argument> *

--  <group> *
---   <argument> *

--  <argument> *

--  <execute> *

 

<optionGroup>

This group renders as a set of RadioButtons for each child argument, which are always of type Boolean. It has only one attribute:

 

Attribute

Description

title

The title of the group.

 

Its child <argument> element is a reduced version of the full argument element explained below. It can only contain the following attributes: label, tooltip, help, storeIn, selected (determines the initial state of the radio button). See explanation below for the full <argument> element.

<group>

Like we said, this is only a visual arrangement for arguments. It has only one attribute:

 

Attribute

Description

title

The title of the group.

 

Both kinds of groups render at the top of the form, before all non-grouped arguments.

<argument>

This is the element that defines the way arguments are collected from the user. It has many attributes that control the behavior and appearance of the Value Editor control:

 

Attribute

Description

label

A label to show next to the argument input box.

tooltip

Brief hint to the user about the purpose of this argument. Optional.

help

Complete help for the argument. Optional.

type

Full type name of argument or a reference to a TypeDefinition Defaults to string. Optional.

converter

Full type name of a class that can convert values to and from representations other than the argument type or a reference to a TypeDefinition. Defaults to converter associated with the argument type. Optional.

editor

Full type name of a class that provides UI editing of the argument or a reference to a TypeDefinition. Defaults to editor associated with the argument type. Optional.

storeIn

Key to use to store the value.

usage

Enumeration values: Required, Optional. Defaults to Required. It's optional.

defaultValue

A value to use as the default when the wizard starts. Either the argument must be of type string, or a converter must be able to transform it  to the argument type.

defaultExpression

An expression that can be a state key name (stored by another argument) optionally followed by property or field accesses on it. This is useful for setting a value's default to a previously collected argument.

 

Help causes an icon to appear next to the input box, and clicking on it causes a new window to show the full help for it.

converter and editor work together to provide the collection strategy. The former provides conversion to/from string (usually) representations of the value. For example, an argument of type Int32 is converted from the string used as a default value or the one entered by the user. Converter can also provide a list of values that are valid. For example, the .NET built-in converter for enums displays an ordered list of valid enum values. This value relies on the .NET TypeConverter base class.

The Editor can provide a UI for editing the value, such as the .NET built-in ColorEditor or CollectionEditor or custom ones such as a ClassBrowserEditor or a ProjectSelectionEditor. This value relies on the .NET UITypeEditor base class.

 

Collectively, they make for the following argument collection UI:

 

 

Editors and converters build upon the .NET System.ComponentModel features. Therefore, we offer instant availability of all .NET converters and editors. Plus, the documentation and expertise in building them for custom components and controls can be leveraged for the wizard construction process.

 

To really understand the power of this feature, let's just see a couple more screenshots. Let's say a wizard configuration file has the following argument definition (taken from the Add New Service wizard):

 

<argument label="Service folder" storeIn="ServiceFolder"

          editor="FolderEditor" defaultValue="BusinessLayer"

          tooltip="Parent folder to place the new service folder into." />

 

Note the editor attribute. It points to an alias in the typeDefinitions section that defines a type inheriting from UITypeEditor, which happens to be a dropdown editor that shows all the projects and folders in the current solution (implemented as a Windows Forms User Control). This is the UI rendered and the editor shown after the user clicked the down arrow:

 

 

And the following shows a similar argument specifying another editor that loads the list of handlers in the current configuration file:

 

 

A converter that shows a list of values is even more easy to develop, although it provides only simple dropdown capabilities.

 

Finally use attribute determines whether the value associated with the argument can be left unassigned or not. This will affect whether the Next button will be enabled too (only when all required arguments in the current step are filled).

 

<execute>

This element defines an optional command that will be executed when the step is finished (either before moving to the next step, or finishing the whole wizard). It has the following attributes:

 

Attribute

Description

command

Full type name of the command type to execute or a reference to a TypeDefinition.

description

Friendly short description of the command. Can contain references to arguments in the wizard state.

prompt

A message that will be displayed to the user before the action is taken This message can contain references to arguments in the wizard state.

dependsOn

Dependency expression that determines whether the command must be executed. See DependsOn for the Step element, as it has the same syntax and semantics.

 

prompt and description format is a string that can contain argument references with the form $(StateKey). For example:

 

<execute

  command="AddFolder"

  prompt="Folder $(TargetFolder) will be added. Continue?.">

 

Prompts allow the user to chose Yes/No options.

 

The Step class is responsible for executing commands at the appropriate time. At this point, it will request a service from the controller, ICommandService, which allows execution of commands. Commands may support Undo, by implementing a specialized interface called IUndoCommand. Undo functionality is managed by the controller. If a command does not support undo, the developer can let the user know it through the prompt attibute message.

 

Before execution, the Step sets a restore point in the command service, so that if any one command fails, all commands supporting undo are rolled back. The service implements this restore functionality through the memento design pattern.

 

The command may receive arguments. The mapping between collected state values and command arguments is performed through use elements:

 

<execute command="theCommand">

  <use stateValue="stateKey" value="expression" asArgument="asKey" />

</execute>

 

The use element maps a value into an argument to pass to the command. asArgument defines the key to use for the command execution. Value can be either directly pulled from the wizard state by using stateValue, which must be the same key used by storeIn argument element attribute. Alternatively, an expression built of mixed constant string values and argument references (with the same format as the prompt and description attributes) can be used. In this case, this attribute takes precedence over stateValue. For example:

 

<execute command="AddFolder">

  <use value="BusinessLayer\Services\$(ServiceName)" asArgument="Path" />

</execute>

 

Here we're mixing a fixed relative path and the actual value for argument ServiceName.

 

Commands must implement one of the following interfaces:

 

public interface ICommand : IComponent
{

  void Execute ( IDictionary arguments );

}

 

public interface IUndoCommand : ICommand
{

  void Undo ( IDictionary arguments );

}

 

Commands implement IComponent in order for the container to be able to "site" them, giving access to environment services to them.

 

Note that <execute> element is optional. The reason for this is that complex commands may require multiple input arguments. The wizard developer can split those arguments collection into several UI steps, and only execute the command in the last one in the sequence, passing the values accumulated so far. Steps, therefore, are a UI grouping for argument collection that ultimately are passed to a command for execution. There's no direct 1-to-1 connection between them.

 

Built-in arguments

When a wizard is launched from the Add New ... dialogs, the appropriate context arguments as explained Context Parameters for Launching Wizards are added to the wizard state. Therefore, they can be reused inside the wizard configuration file. For example, an Add New Item wizard can use the ItemName state slot as follows:

 

<argument label="Business action name" storeIn="ItemName" />

 

The value will be pulled from the pre-filled one the first time it's shown to the user in the wizard.

 

Likewise, any custom parameter passed through the .vsz file as a key/value pair, will also be filled. For example, the following .vsz file passes the Language state value to the wizard:

 

VSWIZARD 7.0

Wizard=IPE.IdeWizard

Param="Assembly=Microsoft.ReferenceArchitecture.Wizards"

Param="Wizard=Microsoft.ReferenceArchitecture.Wizards.AddBusinessAction.NewItem.xml"

Param="Language=C#"

 

An argument on the wizard can use this state slot as follows:

 

<use stateValue="Language" asArgument="Kind" />

 

 

On a future post I'll discuss a concrete wizard distributed with the Shadowfax Wizards, most probably the Add New Service one as it's the most comprehensive, from XML configuration, to Add New Project dialog hook to setup and deployment on top of the base Wizard Framework.

Note: this entry has moved.

Please, make sure these words get deep in your mind the next time you write an ASP.NET application:

If you're using Response.Write, you're a dreadful citizen of the ASP.NET world.

As my friend Victor said, "Response.Write is there just for compatibility reasons and for old script programmers to not feel lonely".
An app written in such a way will not only be difficult to maintain and evolve, it will be almost impossible to customize (specially its layout), will never catch up with the upcoming mobile features and just hurts the eye.
Everytime I see a Response.Write, and specially if it's not even kind enough to use HtmlTextWriterTag, HtmlTextWriterAttribute and HtmlTextWriterStyle, the developer who wrote it is instantly removed from my in-memory list of good ASP.NET programmers.

Bottom line: you should always design your web apps as reusable components and user or custom controls, so that they can be easily rearranged, styled and plugged into existing apps.

Posted by Daniel Cazzulino | 12 comment(s)
Filed under: ,

Note: this entry has moved.

The usual enumeration pattern in .NET is either of these:

foreach (string value in values) { // do something. } // or for (int i = 0; i < values.Length; i++) { string value = values[i]; // do something. }

When working with cursor-style APIs like the XmlReader or XPathNavigator, the pattern usual becomes something like this (note this is the same code for both APIs):

if (nav.MoveToFirstAttribute()) { do { // Do something with nav.Current. } while (nav.MoveToNextAttribute(); }

This is not as readable or compact as the usual approach. One solution to get back the for style of iteration, which I use all the time, is the following:

for (bool go = nav.MoveToFirstAttribute(); go; go = nav.MoveToNextAttribute()) { // Do something with nav.Current. }

With this approach, you can the usual iteration pattern again, and have more compact and readable code. It can be used with all XPathNavigator methods that use MoveToFirst/MoveToNext:

// To process namespaces for (bool go = nav.MoveToFirstNamespace(XPathNamespaceScope.Local); go; go = nav.MoveToNextNamespace(XPathNamespaceScope.Local)) { } // To process all child elements of current for (bool go = nav.MoveToFirstChild(); go; go = nav.MoveToNext()) { }
Posted by Daniel Cazzulino | 4 comment(s)
Filed under: ,

Note: this entry has moved.

I've already said why I believe FireFox is the best browser ever. Let me show you another amazing feature of this browser.

FireFox can be completely customized through CSS stylesheets. You know, the browser itself it built with XML (the I-came-first-than-XAML XML User Interface Language and Extensible Binding Language -think IE behaviors), javascript and CSS. What's more, all those XML, JS and CSS files are right there sitting in your profile folder waiting for you to play with them.

There are two main files that customize the browsing experience:

  • userChrome.css: modifies the browser's appearance.
  • userContent.css: modifies the appearance of all rendered pages.
Both files can be created inside your profile's chrome subfolder. Sample files for them are provided in the US\chrome subfolder inside your profile folder. You can rename and copy them to your chrome folder. You can create a new FireFox profile with the store location you want by using starting it with firefox.exe /p.

I my case, for example, I find the default search box at the top right of the browser too small. I usually perform searches like: xml performance site:weblogs.asp.net. That doesn't fit the textbox. What's more, as I'm using 1152x864 resolution, I've a huge wasted address bar.
In the userChrome.css stylesheet file, the following style declaration suffices to make the search box wider (see it in this screenshot): #search-container { -moz-box-flex: 300 !important; } Way cool huh?

But it doesn't end in browser customization. You can also affect the way ALL the pages you browse are displayed. That's the userContent.css's role. For example, I find the default font size for <pre> and <code> tags too small in comparison with IE. Easy enough to fix. I just edited the userContent.css stylesheet and added:

/* code font bigger. */ code { font-size: 10pt !important; } pre { font-size: 10pt !important; } It doesn't end in simple tag rendering modifications. You see, I spend a lot of my online experience either on MSDN or SourceForge. The former has the completely useless header with the usual MS menu I never use, the the later shows me the advertising banner which takes considerable space at the top of the page too. I didn't want to see them anymore. Piece of cake with FireFox.
I had a look at both sites' HTML source, located the elements I don't want to see, and added the following styles: /* MSDN */ #msviMasthead { display: none; } #msviFooter { display: none; } /* Microsoft.com */ #masthead { display: none; } #footer { display: none; } /* SF */ img[alt='Click Here'] { display: none; } Note the last style uses a CSS2 selector to hide the image with the specified alt attribute. This is possible because FireFox, unlike that 3 years old browser, supports the full CSS 2.1 specification, as well as some of the goodies from CSS 3. I needed to refer to the <img> alt attribute because there's no ID provided on it or its parent elements that I can reliably use, unlike MS sites. Of course, if the site changes, I'll need to update my css. No big deal.

And if you have the disgrace of having to work too much with GDN, the following will get rid of the amazingly useless header and search box and the advertising at the right:

td[background='/images/topbar_bg.gif'] { display: none; } span[id='_ctl2_RightNavigation'] { display: none; }

Of course, I've only scratched the surface. There are a lot more ways to customize your browsing experience. Happy firefoxing!
Posted by Daniel Cazzulino | 2 comment(s)
Filed under:

Note: this entry has moved.

I'll keep the updated list of posts relating to performance in XML manipulation here.

Check out the whole "High-performance XML" series:

More Posts Next page »