July 2008 Blog Posts
Earthquake in Los Angeles

imageYes, it's confirmed, in fact, the earthquake at 11:42PM that happened today was located around Chino Hills.  More info on the earthquake can be found on CNN.  This could be just the beginning :/.  Looks like there were a few more aftershocks just after the big one.  Thanks USGS!

 

UPDATE 12:10PM:  All cellular phone communication are down at the moment.  Land line -to- land line phone communications seems to work, but calling cell phones from land lines do not.

 

UPDATE 12:29PM: Cell phones seem to be partially working again.  Calls are partially getting through.  Looks like cell phone traffic is decreasing.  Originally, the earthquake was estimated at 5.8 magnitude.  Updated USGS stats say the earthquake was 5.4 magnitude.

Understanding ScriptResource and WebResource in ASP.NET

Here are some common questions about ASP.NET and web resources:

  • What is a web resource?
  • How do I get my embedded scripts to be delivered by ScriptResource.axd handler?
  • How do I get my embedded scripts to be delivered by WebResource.axd handler?
  • What is the difference between ScriptResource.axd and WebResource.axd?

First, let's tackle the first question.  What is a web resource and why would you use such a thing?

Web Resources

A web resource is a file embedded in an assembly.  This file can either be a JavaScript file or a BMP, or any other emendable type of resource in an assembly.  Just take a look at System.Web and all the embedded resources that are defined:

image

You'll notice there are both, Images and Scripts.  There's even some html!  So, web resources (at an assembly level) can be composed of just about anything you want.

How do you define Web Resources?

Meet the [WebResource] attribute.  You define web resources by using the WebResource attribute.  The WebResourceAttribute acts as an access marker to allow resource handlers to find your resources.  The first parameter to WebResource is the name of the web resource, the second parameter is the ContentType.

[WebResource(
  webResourceName
    Type: System.String
    The name of the of Web resource.
,
  contentType
    Type: System.String
    The type of resource, such as "image/gif" or "text/javascript".
)]

image Once you have your [WebResource] defined in your assembly, the next step is to mark the file you want embedded as an "Embedded Resource" in Visual Studio.

 

 

 

Working with Assembly Resources

There are two basic ways to getting at your assembly resources loaded on your ASP.NET web page.  ScriptResource.axd and WebResource.axd.

Using WebResource.axd

Generally, you'll want to use WebResource.axd when you are dealing with binary resources.  Things like emendable images or other types of media.  You can use WebResource for serving out JavaScript files but there is a better alternative.  However, if you're stuck in ASP.NET 2.0 land with out Microsoft AJAX, then WebResource.axd is your only option to serve out your embedded assembly resources.  To make your assembly resources available on your ASP.NET page, simply use:

  104  //Uses WebResource.axd

  105  this.Page.ClientScript.RegisterClientScriptResource(

  106     typeof(SwfObject), "ProjectBase.Web.Scripts.swfobject.js" );

  107 

  108  string urlToFunnyWebResourceUrl =

  109     this.Page.ClientScript.GetWebResourceUrl(

  110     typeof(SwfObject), "ProjectBase.Web.Images.Header.gif" );

urlToFunnyWebResourceUrl is the the actual absolute path to your webresource.  So you could potentially use it to link to an image or script.  ClientScript.Register* are generally reserved for loading JavaScript.  It's pretty straight forward, pass in the typeof(Control) that's requesting the resource, and the full name to the assembly resource.  The result of these calls will generate URLs to WebResource.axd.

Using ScriptResource.axd

As I mentioned earlier, there is a better alternative for loading your JavaScript assets if you're working with ASP.NET AJAX.  Using ScriptResource.axd handler actually has some interesting features.  Some features include:

  • Automatically GZip/Compressing your scripts over HTTP for delivery.
  • Dynamically resolving Release/Debug scripts based on build parameters.  This is useful, if you keep two types of the same script: one for debug, and one packed for release.
  • Can be used for Non-MsAJAX Framework script assets such as jQuery.

The ScriptManager object is how we can get our embedded JavaScript into our page using ScriptResource.axd:

  112  //Uses ScriptManager.axd

  113  ScriptManager.RegisterClientScriptResource(

  114     this, typeof(SwfObject), "ProjectBase.Web.Scripts.swfobject.js" );

The calling semantics are pretty much the same as the previous calls to WebResource.axd, the only difference is that we are passing in this instance of the control that wants to register the script.  The effect of calling this method results in scripts being loaded from ScriptResource.axd.

That's it!  Happy coding!  I'll probably add some more tips on this post if I come across any.

Brian Chavez

The ParseChildren PersistChildren and PersistenceMode.InnerProperty

After a while of non-web control development, ParseChildren and PersistChildren attributes are important attributes to remember when trying to get the desired results your looking for in the Visual Studio designer.

So, this post should clear up (and serve as a reminder for me) how and why these attributes are important.  Let's explore what these two attributes are used for.  Let's start with ParseChildren.

The [ParseChildrenAttribute]

The ParseChildren Attribute is probably, the most important attribute you should pay attention to when developing web controls.  It's actually used by the ASP.NET Parser and ControlBuilder object to figure out how to parse the ASP.NET code you write.  Visual Studio also uses this attribute to figure out what valid sub-controls and components are allowed within the contents of a server control.

Let's say, I want to create an AggregateFeeds control that displays an aggregate list of RSS feeds.

A Basic and Boring Control Syntax

image

You'll notice that the RssResource is the only available option that is allowed as a child from the AggregateFeeds control.  Here's the code behind the AggregateFeeds control:

  113     [

  114     ParseChildren(

  115         typeof(RssResource),

  116         DefaultProperty = "Feeds",

  117         ChildrenAsProperties = true

  118         )

  119     ]

  120     public class AggregateFeeds : Control

  121     {

  122         public AggregateFeeds()

  123         {

  124             this.Feeds = new RssFeedCollection();

  125         }

  126         public RssFeedCollection Feeds

  127         {

  128             get;

  129             private set;

  130         }

  131         protected override void Render(HtmlTextWriter writer)

  132         {

  133             this.Feeds

  134                 .ForEach( rssRes => writer.Write( rssRes.Url ) );

  135         }

  136     }

  137 

  138     public class RssFeedCollection : List<RssResource>

  139     {

  140 

  141     }

  142 

  143     public class RssResource

  144     {

  145         public string Url { get; set; }

  146     }

The ParseChildren attribute on AggregateFeeds tells the ASP.NET, that any children within the AggregateFeeds control should be typeof(RssResource)ChildrenAsProperties=true let's ASP.NET know that it should STOP parsing server controls with "runat=server", and switch to instantiating objects into the properties of the ArggregateFeeds control.  DefaultProperty says, that the results of the parsed objects should go into the default property Feeds.

Syntax Goodness With InnerProperty

The previous example was great, it's simple and get's the job done.  But let's say, the requirements have changed, our control is growing, and we need to allow more customization, and extensibility for the consumers of our AggregateFeeds control.

Let's clean up the markup and allow our developers to create markup like this:

image

To get this type of syntactical behavior, check out the code below:

  113     [

  114     ParseChildren(

  115         ChildrenAsProperties = true

  116         )

  117     ]

  118     public class AggregateFeeds : Control

  119     {

  120         public AggregateFeeds()

  121         {

  122             this.Feeds = new RssFeedCollection();

  123         }

  124 

  125         [PersistenceMode(PersistenceMode.InnerProperty)]

  126         public RssFeedCollection Feeds

  127         {

  128             get;

  129             private set;

  130         }

  131         [PersistenceMode(PersistenceMode.InnerProperty)]

  132         public AggregateSettings Settings

  133         {

  134             get;

  135             private set;

  136         }

  137         protected override void Render(HtmlTextWriter writer)

  138         {

  139             this.Feeds

  140                 .ForEach( rssRes => writer.Write( rssRes.Url ) );

  141         }

  142 

  143     }

  144 

  145     public class AggregateSettings

  146     {

  147         public int TimeOut { get; set; }

  148         public bool CacheResults { get; set; }

  149     }

  150 

  151     public class RssFeedCollection : List<RssResource>

  152     {

  153 

  154     }

  155 

  156     public class RssResource

  157     {

  158         public string Url { get; set; }

  159     }

Notice, we've removed DefaultProperty and typeof(RssResource) from ParseChildren attribute.  We're no longer working with a simple control that has simple children objects that need to be parsed, we're now working with a complex control with more than one property that we're setting in the markup, so we've removed the "default" stuff.  The syntactical magic happens with PersitanceMode attribute on the properties.  PersistanceMode.InnerProperty allows us to specify our cool <Feeds> and <Settings> tags.  How does Visual Studio know what members are available?  It does so by Reflection.

Get fancy, more than one child type

Also, I want to point out, suppose, we want to support multiple types of Feed objects.  We could use an enum in RssResource, or we could use inheritance to achieve the following:

image

All we would have to do is simply mark RssResource as an abstract class. Then, subclass for each type.

  156     public abstract class RssResource

  157     {

  158         public string Url { get; set; }

  159     }

  160     public class MediaRss : RssResource

  161     {

  162 

  163     }

  164     public class ITunesRss : RssResource

  165     {

  166 

  167     }

Again, I'm just showing that it's possible, but following my mantra of "less code, less maintenance," I'd use an enum to describe the type of rss feed on RssResource.

Where is [PersistChildren]?

Nowhere!  Is PersistChildren attribute needed?  No, it's not a required attribute to create your custom control.  The PersistChildrenAttribute only provides designer support for your control with Visual Studio and has no "processing" affect in ASP.NET, but remember ParseChildren does.

I'm a image  source-view only guy.  I really don't remember the last time I've used the Visual Studio "Design View", it's a waste, crashes all the time, so I've pretty much given up on it.  Besides, "Design View" is for n00bs anyway.  Just kidding!  If you plan on using the Design View, then you'll probably need your PersistChildren attribute...

In general, PersistChildren and ParseChildren are exclusive complementary attributes to describe the same semantic operation.  The rule of thumb goes:

If ParseChildren(true), then PersistChildren(false)

If ParseChildren(false), then PersistChildren(true).

Following the PersistChildren guideline above should keep your code out of trouble.  But again, I wouldn't use PersistChildren only until you actually need it.  Less code, less maintenance.

Here's a nice list of attributes you should consider when writing your custom controls:

http://wdevs.blogspot.com/2007/10/attributes-to-consider-applying-when.html

Hope that helps! Happy coding!

Brian Chavez

Recursive Find Control using LINQ

imageJust came across a really cool way to recursively enumerate through a flattened Page ControlCollection hierarchy using LINQ.  This is a useful page extension you'll definitely want to add to your toolbox.

Happy Coding!

-Brian Chavez  party0034.gif

Pencil Project - GUI Prototyping

imageJust stumbled across some GUI prototyping software for Graphical User Interfaces.  It's called "Pencil Project".  It's basically an XPI Add-In for Fire Fox 3 and runs anywhere FF3 runs.

This opens up some interesting possibilities.  Check it out and let me know what you think :)

 

-Brian Chavez

NAnt Addin for Visual Studio (VS) 2008

image I've finally committed and upgraded VS 2008.  Fortunately, everything has gone pretty smooth.  Third party tooling support for VS 2008 is now reasonable, ReSharper, Code Rush, all now are supporting 2008.  But one of my favorite helper tools is NAntAddin developed by Netlogics Software.  It's quick and easy to execute specific NAnt tasks in the window.  Unfortunately, it doesn't support 2008 out of the box.

However, after playing around with the AddIn file, I was able to get NAntAddin working with VS 2008.

Here's how to do it:

  1. Download the latest version.
  2. Unzip and copy the addin files and folder to:

    On Vista:
    \Users\%UserName%\Visual Studio 2008\Addins

    On XP:
    \My Documents\Visual Studio 2008\Addins

    Note: If you don't see an "Addins" folder in, then create one under "Visual Studio 2008".
  3. Next, open the NAntAddin.Addin file with your favorite text editor, and edit the <version> value to 9.0 as shown below:

    image 

Now start Visual Studio 2008, and you should have NAntAddin up and running!

Your final directory structure should look like the following:

image

 

Happy coding!

Brian Chavez

10 Comments Filed Under [ Tips & Tricks ]