C#
C# related posts.
Enterprise Library Validation MessageTemplate Tokens

I always forget... pulled from MSDN with my notes added in italics:

Understanding Message Template Tokens

Custom message templates can contain tokens. The validator replaces these tokens with values before it adds the resulting message to an instance of the ValidationResult class. Tokens are represented by using the strings {0}, {1}, {2}, and so on within the message template strings. All validators provided by the Validation Application Block use the first three tokens {0}, {1}, and {2} for the same purposes. Different validators may also understand additional tokens, beginning with {3}. The following table describes tokens {0}, {1}, and {2}.

Token

Description

{0}

This token represents the value of the object that is being validated. Although it can be useful to show the original value as a part of the validation message, you must be careful to avoid injection attacks by escaping any characters that can be used to attack the system that conveys the message to the user.

In simple terms: returns "ObjectBeingValidatedFullTypeName+Field"

{1}

This token represents the key of the object that is being validated. When the validator is attached to a member of a type such as a property or a field, the key is set to the member name. When the validator is attached to an object, the key is null and the token is replaced by an empty string.

In simple terms: returns "Field" name being validated

{2}

This token represents the tag that is specified on the validator instance. If no tag is supplied, the token is replaced by an empty string.

In simple terms: returns contents of [Validator Tag="foo"] property defined in the attribute.

Add Comment Filed Under [ Tips & Tricks C# ]
Fluent C Sharp Language Extension Helpers - Part 1

So, I found myself doing a lot of for( int i = 0; i < n; i++ ){} stuff lately.  So, I've decided to try something new. I've started a small collection of "Fluent Helpers" that alleviate a lot of the verbosity in C#.

About 28 characters (including spaces) for a simple for loop to do some constant iteration.

for( int i = 0; i < n, i++){

About 18 characters to do this (no pun intended):

Do.This( 5, () =>{

Here's an example:

   51             Do.This( 5,

   52                     () =>

   53                         {

   54                             Console.Write( "Hello " );

   55                             Console.WriteLine( "World!" );

   56                         }

   57                 );

Prints:

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!

Now that feels much better on my hands, and looks much cleaner too, IMHO.  Here's the simple implementation for Do.This:

   42     public static class Do

   43     {

   44         public static void This(int times, Action what)

   45         {

   46             for( int i = 0; i < times; i++ )

   47             {

   48                 what();

   49             }

   50         }

   51     }

I've already started a little library of these small syntax helpers I've collected.  If you have any suggestions, please share! cool0003.gif

-Brian Chavez

Add Comment Filed Under [ Tips & Tricks C# ]
Visual Studio 2008 SP1 and .NET 3.5 SP1 RTM

imageVisual Studio 2008 SP1 (Service Pack 1) is ready for download. 

 

Click below for the links:

VS2008 SP1 EXE Installer:

http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=en

or

VS2008 SP1 ISO Installer:

http://www.microsoft.com/downloads/details.aspx?FamilyId=27673C47-B3B5-4C67-BD99-84E525B5CE61&displaylang=en

 

Happy updating!

-Brian Chavez

Add Comment Filed Under [ ASP.NET C# ]
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

CSharp Polymorphism, Inheritance, Method Hiding, and Method Overriding

Classes that declare virtual methods allow inheritors to permanently replace the method with their own implementation regardless of type cast.  So, if Class A defines Xoo() as virtual, then any class inheriting from A, overriding Xoo(), the inheritor's Xoo() will be called regardless of wether the variable is treated or typecasted to A.

If you use the 'new' keyword (Method Hiding), then whether or not the declared method is called directly depends on how a variable is being used.

For example, consider:

namespace InheritanceTest

{

    class A

    {

        public virtual void Xoo(){ Console.WriteLine( "A::Xoo()" ); }

        public void Yoo(){ Console.WriteLine( "A::Yoo()" ); }

    }

    class B : A

    {

        public override void Xoo(){ Console.WriteLine( "B::Xoo()" ); }

        private new void Yoo(){ Console.WriteLine("B::Private Yoo()"); }

    }

    class BB : A

    {

        public override void Xoo(){ Console.WriteLine("BB::Xoo()"); }

        public new void Yoo(){ Console.WriteLine( "BB::Yoo()" ); }

    }

    class C : A

    {

        public virtual new void Xoo(){ Console.WriteLine( "C::Xoo()" ); }

        public virtual new void Yoo(){ Console.WriteLine( "C::Yoo()" ); }

    }

    class D : C

    {

        public override void Xoo(){ Console.WriteLine( "D::Xoo()" ); }

        public override void Yoo(){ Console.WriteLine( "D::Yoo()" ); }

    }

 

    class Program

    {

        static void Main( string[] args )

        {

            A a = new A();

            a.Xoo();   //A::Xoo()

            a.Yoo();   //A::Yoo()


 

 

            B b = new B();

            b.Xoo();   //B::Xoo()

            b.Yoo();   //A::Yoo()<- Private 'new' B.Yoo() is

                       //           not available so A.Yoo() is called



 

 

            A ab = new B();

            ab.Xoo();  //B::Xoo()<- B.Xoo() override replaces

                       //           virtual A.Xoo() regardless of cast.

            ab.Yoo();  //A::Yoo()



 

 

            BB bb = new BB();

            bb.Xoo();  //BB::Xoo()

            bb.Yoo();  //BB::Yoo()<- If used directly as BB,

                       //            then 'new' BB.Yoo() hides A::Yoo()



 

 

            A abb = new BB();

            abb.Xoo(); //BB::Xoo()

            abb.Yoo(); //A::Yoo();<- If casted and used as A, then A::Yoo()


 


           
C c = new C();

            c.Xoo();   //C::Xoo()

            c.Yoo();   //C::Yoo()



 

 

            A ac = new C();

            ac.Xoo();  //C::Xoo()

            ac.Yoo();  //C::Yoo()



 

 

            D d = new D();

            d.Xoo();   //D::Xoo()

            d.Yoo();   //D::Yoo()



 

 

            C cd = new D();

            cd.Xoo();  //D::Xoo()

            cd.Yoo();  //D::Yoo()



 

 


            A ad = new D();

            ad.Xoo();  //A::Xoo()

            ad.Yoo();  //A::Yoo()

        }

    }

}

Add Comment Filed Under [ C# ]
Slink Framework - Strongly Typed URLs for ASP.NET

 image926

image_thumb15_thumb45

I decided it was time to solve a very annoying and time consuming code maintenance/quality problem when working with ASP.NET and Visual Studio, URL verification.  If you're like me, you've probably had your fair share of HTTP 404s and ASP.NET maintenance troubles whenever you renamed a file in your web project and broken URLs in the code-behind pages that contain scattered uses of Response.Redirect() similar to the following:

protected void Page_Load(object sender, EventArgs e)

{

    if ( User.IsInRole( "admin" ) )

    {

        Response.Redirect( "~/Page2.aspx" );

    }

    if( User.IsInRole( "employee" ) )

    {

        Response.Redirect( "~/EmployeePages/ViewCustomers.aspx" );

    }

    if( User.IsInRole("customer") )

    {

        Response.Redirect( "~/CustomerPages/ViewCatalog.aspx" );

    }

}

The site validation in Visual Studio somewhat is limited in its ability to validate URLs.  Visual Studio validates URLs in the HTML markup view, but doesn't validate your URLs in code-behind pages.  That's a bummer, because the code above is somewhat common in projects.  Invalid URLs that exist in your code-behind pages are hard to debug and locate... you usually don't know when you have an invalid URL lurking in your code-behind until you hit the page with your browser.  Most modern refractoring tools today do a good job refactoring code for renamed files; however, since most refactoring tools are searching for strings when renaming an ASPX file, there is a potential for error.  There have been many times when refactoring didn't help me and only made the problem worse by selecting the "search string literals" option.  Refactorability degrades when you start dealing with different media types in your markup and code-behind pages, such as Images, SWF, CSS, and JavaScript URLs.  Media types like these go unchecked, try refactoring those in your pages!mad0259.gif  Personally, I'd love it if there was some kind of strongly typed URL framework.  Fortunately, there has been some work in this area by Fabrice Marguerie and his open source project PageMethods.  In summary, PageMethods was too strict, and didn't work well for my purposes.  I simply wanted a light-weight and fast URL framework to provide links to pages and media objects that I could use in code-behind pages and HTML markup.  I also wanted to know at compile time the validity of all the URLs in my project.  So, I decided to tackle the problem myself with a small project I created called (Strong Link), aka Slink.

Now, let's revisit the same maintainability problem above using Slink with strongly typed URLs:

protected void Page_Load( object sender, EventArgs e )

{

    if( User.IsInRole( "admin" ) )

    {

        Response.Redirect( Slinks.Page2.TidleUrl );

    }

    if( User.IsInRole( "employee" ) )

    {

        Response.Redirect( Slinks.EmployeePages.ViewCustomers.TildeUrl );

    }

    if( User.IsInRole( "customer" ) )

    {

        Response.Redirect( Slinks.CustomerPages.ViewCatalog.TildeUrl );

    }       

}

With Slink, not only do you get cleaner code, you get compile time checking for code-behind pages! You can also use type safe links in HTML markup:

<h4>Customer Pages</h4>

 

<!-- The old way, using relative path -->

<img src="~/Images/CustomerImage.jpg" alt="not strongly typed image" />

 

 

<!-- The new Slink type safe way, using img HTML tag -->

<img src='<%# Slinks.Images.JPG.CustomerImage.TildeUrl %>' alt="strongly typed url"

     runat="server" />

 

<!-- The new Slink type safe way, using a web control -->

<asp:Image ID="imgControl" runat="server"

           ImageUrl='<%# Slinks.Images.JPG.CustomerImage.TildeUrl %>' />

Yeah! And the list goes on:

  • Better Maintainable Code
  • Better Cleaner Code
  • Better Readable Code
  • Better Refactorable Code
  • Better Quality Code
  • Support for media types other than ASPX pages
  • Fast code generation
  • Non-intrusive overhead (no need to call any setup methods or expensive runtime checking)
  • Use as-you-go integration (doesn't require any rewrites of your code to start using Slink)
  • XML configuration based
  • Intellisense for any of your files and media objects!

Now that's what I'm talking about. So how do you get your hands on all this Slink ASP.NET goodness?  Keep reading...

 

Getting Started with Slink

There are two basic ways to use Slink:

  • You can use Visual Studio and an accompanying CR_Slink Plug-In (via DXCore) to automatically generate a type safe file in your projects App_Code directory.

OR

  • You can use Slink.exe in a build task to generate a strongly typed safe file in your App_Code directory.

Details about how to setup each method is discussed later.  First, there's some XML configuration you'll need to perform to tell Slink what to generate.  Here is a sample configuration that you place in your Web.config:

<!-- Web.config -->

<configuration>

  <configSections>

       <section name="Slink" type="Slink.Core.SlinkConfigSection, Slink.Core"/>

  </configSections>

  <Slink>

     <GlobalSettings EngineEnabled="True" RootNamespace="Slinks"/>

     <NamespaceRules>

        <add key="aspxFiles" Extension="*.aspx" UseFolderNamespace="True"/>

        <add key="jpgFiles" Extension="*.jpg" NamespaceOverride="Images.JPG"/>

        <add key="pngFiles" Extension="*.png" NamespaceOverride="Images.PNG"/>

     </NamespaceRules>

  </Slink>

  <!-- Other configuration settings go here -->

</configuration>

Below is a brief explanation of the XML configuration settings...

<section name="Slink" type="Slink.Core.SlinkConfigSection, Slink.Core"/>

  • This section handler needs to be added to the <configSections>.  The <section> tag defines the XML node that is to be handled by the SlinkConfigSection on behalf of the .NET configuration framework.

<Slink>

          <GlobalSettings EngineEnabled="True" RootNamespace="Slinks"/>

  • The <GlobalSettings> node has two attributes EngineEnabled and RootNamespace.
    • EngineEnabled - Boolean - This is a project level setting. You may want to disable type safe link code generation at the project level if you are working with multiple Web Projects.  Setting EngineEnabled="False" disables code-generation at the web-project level.
    • RootNamespace - String - Allows you to specify the Namespace for all type safe links.

image_thumb115 

<NamespaceRules>

    <add key="aspxFiles" Extension="*.aspx" UseFolderNamespace="True"/>

    <add key="jpgFiles" Extension="*.jpg" NamespaceOverride="Images.JPG"/>

    <add key="pngFiles" Extension="*.png" NamespaceOverride="Images.PNG"/>

</NamespaceRules>

  • <NamespaceRules> are at the core of Slink.  Namespace rules dictate how type safe code is generated by the Slink Engine.  Namespace rules allow you to define what type of files get type safety.
    • Extension - String - If you wish to have type safe code generated for all ASPX pages, add a namespace rule with the Extension attribute set to "*.aspx". Including the * (asterisk) is necessary.
    • UseFolderNamespace - Boolean - Uses the file path to generate the sub-namespaces below the root namespace.
    • NamespaceOverride - String - Overrides the UseFolderNamespace attribute and allows you to define your own custom path.  Your custom namespace override is appended to RootNamespace. See the example below for JPG and PNG namespace overrides:

image_thumb15_thumb35

NOTE: If you have multiple files with the same name but different extension, you'll want to override namespaces to avoid type collision.

Now that we have XML configuraiton out of the way, I'll walk you through on how to install Slink on your machine.

 

Using Visual Studio Slink Plug-In

image_thumb285

Installing VS.NET Plug-In

  1. Install the DXCore (free) extensibility framework for Visual Studio from Developer Express here.
  2. Download the Slink binaries Slink_bin.zip.
  3. Copy the contents of Slink_bin.zip into your DXCore Plug-In directory
    • Ex: C:\Program Files\Developer Express Inc\DXCore for Visual Studio .NET\2.0\Bin\Plugins
    • Note: All contents of the Slink_bin.zip must be extracted into the plugins directory.
  4. Make sure your XML config section is defined in your Web.config, and start coding away!

 

Using Slink.exe

image_thumb275

Now, if you're already using the Visual Studio Plug-In, there's no need to use the Slink.exe.   But for those of you who don't have Visual Studio, or are using Visual Studio Express, using Slink.exe is the way to go.

Installing Slink.exe

  1. Download the Slink binaries Slink_bin.zip.
  2. Extract the contents of to the directory of your choice
    • Ex: C:\Tools
  3. Run the following from the command line:
    • C:\Tools> slink.exe /webproject:<PathToWebProject>
    • Replace <PathToWebProject> with the full path to your project.
  4. Be sure to modify your Web.config and your Namespace Rules are set.  Otherwise, the Slink won't know what to do.

TIP: Unfortunately, Web Projects in Visual Studio are handled differently than ordinary projects.  With web projects, you can't specify any "Pre-Build" event tasks.  But there's an easy workaround for this limitation.  If you're using Visual Studio Express, and want to have your types generated before the build process/verification of your main web project, you can create a standard dummy "Class Library".  In the pre-build event for your dummy "Class Library" you can setup Slink to execute.  Then, add the dummy "Class Library" to your main web-project.  Now, anytime you build your website, your class library will be built first (and slink will run) before the build / verification process takes place on your main web-project.

That all!  After building web project (if you're using the VS.NET Slink Plug-In) or when you execute Slink.exe, you should get a file named <WebProject>\App_Code\Slinks.cs that contains your type safe URL generated code.

If you have any questions, comments, or suggestions please feel free to contact me. I hope other developers find the Slink framework useful.  Happy coding!


Slink CodePlex Project

http://codeplex.com/slink

 

Thoughts & future improvements to Slink

  • Add support for strongly typed parameter passing/parsing for query string parameters.
  • Create a standalone Slink Plug-In that does not rely on DXCore.
  • Implement more advanced code generation caching.
  • Possibly implement /code generate a helper methods on media types such as "MyImage.GetStream()" that would automatically open and return an IO stream.

 

Licence

This library and code generator is licensed under the terms and conditions defined in the GNU Public License. You are free to use it for non-commercial purposes. If you are going to use any part of it in a commercial application, contact me and we can work something out.  You may use the code generated output of Slink in both commercial and non-commercial applications.

Special Thanks

Special thanks and acknowledgements go out to Philip Laureano for building his open source TaHoGen code template generator.  Without it, Slinks would not exist.