Monday, May 23, 2011

A JavaScript Color Viewer

screen.jpg

Introduction

In CSS, HTML, WPF XAML, and many other files, color is specified in the following forms:
  1. a color name - like red
  2. '#' followed by 6-bit hex value - like #123456
  3. '#' followed by 3-bit hex value - like #123, which will be expanded to #112233 by system
  4. rgb color - like RGB(255, 0, 0)
I found many times, especially when I read other's code, I have to figure out which color these numbers really represent. So, I developed a JavaScript color viewer, which can be downloaded and used in your local computer. An online version can also be found here.

Background

The color is entered dynamically by the user. The program has no idea of what it will be in advance. However, the program has to pick a color for the foreground text. No matter which color we pick, it could be the same as the background color, so we could not be able to see it. For that reason, we need to use at least two contrast colors for the text. In the program, we use black or white as the text color. And use a function to calculate background color brightness based on its RGB value. The function is based on this article which refers to this article.
We can also display text below the color block and use black as the only text color. But I feel that makes this program quite boring.

Using the Code

The program has 3 files, one HTML file, one JavaScript file and one CSS file. The HTML file is easy, it is listed below:
Collapse
<div id="controls">
    <span>Color</span>
    <input type="text" id="txt" size="30"/>
    <input type="button" id="btn" value="Display"/>
</div>
<div id="message">Input is invalid!</div>
<div id="view"></div>
The "message" is displayed when user entered some invalid color. The "view" is where the color blocks will be inserted.
The JavaScript file contains the following parts:
  1. Two text brightness calculation functions
  2. A text parser, which is used to parse the input text, validate it, and find RGB channel values
  3. A display function, which insert squares into the HTML DOM tree
The JavaScript code to calculate the color brightness from RGB channel is:
Collapse
function getTextColor2(red, green, blue) {
    var brightness = ((red * 299) + (green * 587) + (blue * 114)) / 1000;
    if(brightness < 125) { //background is dark
        return 'white';
    } else {
        return 'black';
    }
}
In my humble opinion, for programmers, knowing this function exists is more important than knowing why it works. However, if you really want to know why, please refer to the previously mentioned articles to see the details.
You can also calculate the brightness from hex values:
Collapse
function getTextColor(hex) {
    if(hex.length == 3) {
        hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
    }
    var red = parseInt(hex.substring(0, 2), 16);
    var green = parseInt(hex.substring(2, 4), 16);
    var blue = parseInt(hex.substring(4, 6), 16);

    return getTextColor2(red, green, blue);
}  
The 3-bit hex color value like #123 is expanded to #112233. JavaScript parseInt function can take the second parameter, which is the radix (base) of the number to be parsed. The radix can be any number from 2 to 36. In our case, we use 16 to parse hex strings.
JavaScript has both substr and substring function. substr is not in the ECMAScript standard. So, we are not using it here. However, substr is supported by most web browsers. The usage of these 2 string functions is:
  • s.substr(start, length)
  • s.substr(start) // to end
  • s.substring(start, end) // 2 indices
The difference is substr goes from an index to some length, and substring goes from index to index. The way I remember it is: "ing" of substring is index.
The text parser uses the following regular expression to parse the input.
Collapse
var regHex6 = /^#?([a-f\d]{6})$/;
var regHex3 = /^#?([a-f\d]{3})$/;
var regRgb = /^rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
The beginning "#" is optional for hex input, this is for some lazy people like me. \d{1,3} means a digit repeat 1, 2 or 3 times.
The text parser also needs a giant dictionary "standardColors" to check all the standard colors. This dictionary is at the end of the JavaScript file and not listed here. The parser will check whether the color exists, and what is the hex value of the color, so the program can calculate the text color.
The code for text parser is below, it returns an object of 2 properties. One property, text, will be displayed as the foreground text. The other property, textColor, will be either black or white, which is calculated from previously mentioned brightness functions and will be used as the text color. The 3 regular expressions will be used to match the input one by one, if no one matches, the function will assume the input is a color name. And the "standardColors" dictionary will be checked.
Collapse
function parseInput(text) {
    var textLower = text.trim().toLowerCase();
    var result = textLower.match(regHex6);
    var hex;

    if(result) {
        hex = result[1];
        return {
            text: '#' + hex,
            textColor: getTextColor(hex)
        };
    }
    result = textLower.match(regHex3);
    if(result) {
        hex = result[1];
        return {
            text: '#' + hex,
            textColor: getTextColor(hex)
        };
    }
    result = textLower.match(regRgb);
    if(result) {
        var red = result[1];
        var green = result[2];
        var blue = result[3];
        if(red < 256 && green < 256 && blue < 256) {
            return {
                text: 'RGB(' + red + ', ' + green + ', ' + blue + ')',
                textColor: getTextColor2(red, green, blue)
            };
        }
    }
    hex = standardColors[textLower];
    if(hex) return {
                text: textLower,
                textColor: getTextColor(hex)
            };
    return null;
}
Finally, after user entered the color, the following function inserts a color block into the HTML DOM.
Collapse
var displayColor = function() {
    var result = parseInput(txt.value);

    if(result) {
        msg.style.display = "none";
        view.innerHTML =
            '<div class="' + result.textColor + '">' +
                '<div class="inner">' +
                    '<span>' + result.text + '</span>' +
                '</div>' +
            '</div>' + view.innerHTML;
        view.firstChild.style.backgroundColor = result.text;
        txt.value = "";

    } else {
        msg.style.display = "block";
    }
};
view is a <div> element in HTML file. The following line adds a new block into the view.
Collapse
view.innerHTML = [something] + view.innerHTML;
The inserted <div> elements will be displayed according to the CSS file, which is listed below:
Collapse
#view > div {
    width: 100px;
    height: 100px;
    margin: 5px;
    float: left;
    display: table;
    text-align: center;
    font-weight: bold;
    font-size: 16px;
    font-family: "Courier New";
}

.white {
    color: white;
}

.black {
    color: black;
    border: 1px solid #eee;
}

.inner {
    display: table-cell;
    vertical-align: middle;
}
To vertically center the text display, the outer <div> uses the style display: table;, and inner <div> uses the style display: table-cell; and vertical-align: middle;. This works for most browsers.

Points of Interest

The displayColor function has a lot of string plus operations. In the first draft, I used a string format function, which makes the code much cleaner. It works in most browsers. However, Internet Explorer just doesn't like it for some unknown reason. My string format function is listed here:
Collapse
String.prototype.format = function() {
    var result = this;
    for(arg in arguments) {
        result = result.replace("{" + arg + "}", arguments[arg]);
    }
    return result;
};

Article Source: http://www.codeproject.com/KB/HTML/JavaScriptColorViewer.aspx

Sunday, May 22, 2011

Managing Your JavaScript Library in ASP.NET

How To Manage JavaScript Poorly

Introduction

It is common for ASP.NET developers to adopt lax practices in their management of JavaScript. I believe this is because there is not a lot of reliable information online for how to properly deal with JavaScript in an ASP.NET application. The purpose of this article is to present an optimal technique to manage your JavaScript in your ASP.NET applications. The following issues will be addressed:
  • Inline JS. Page bloat caused by placing JavaScript directly in the page.
  • Deploying JS. Forgetting to deploy JavaScript files.
  • Bad References. Links to JavaScript not working when used in another web application.
  • Dependencies. Needing to remember dependencies between JavaScript files.
  • Unused JS. Referencing JavaScript on pages it is not used.
  • HTTP / HTTPS. Referencing JavaScript over HTTP from an HTTPS page.
  • Refactoring. Refactoring for a new version can take some time.
  • Redundancy. Including a JavaScript file more than once.

Contents

Prerequisites

Make sure you have Visual Studio 2010. Some concepts presented in this article may not work with the Express editions.

Overview

Most of the above problems are caused by placing JavaScript or references to JavaScript files directly in the ASPX page. The solution to almost all of the above problems is to use ASP.NET's built-in capability to embed JavaScript files into a DLL and then reference those files dynamically. This article will present those capabilities, as well as some techniques to take full advantage of them. A tutorial format will be used to explain how each step is done.

Getting Started

First things first. Start up Visual Studio 2010 and create a new empty web application called ParchmentPurveyor (we are making a website for somebody who wants to sell fancy paper):
New Empty Web Application (ParchmentPurveyor) Now, add a new web form called "Default.aspx", and add some simple HTML to it. It should look something like this:
Collapse
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
    Inherits="ParchmentPurveyor.Default" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Parchment Purveyor</title>
</head>
<body>
    <form id="form1" runat="server">
        <h1>Parchment Purveyor</h1>
        <p>Paper for printers, painting, publication,
            paper planes, and plenty of other plebeian projects!</p>
    </form>
</body>
</html>

Adding JavaScript

Now that we have a fully functional website that is sure to get the attention of a plethora of people, we can focus on the JavaScript coding. Rather than add a JavaScript file our main project, however, we will do things a little differently. We are going to create a new project to hold all of our JavaScript files. Start by adding a new class library project, called JavaScriptLibrary, to the solution:
Add Class Library (JavaScriptLibrary) When you added that project, a file called "Class1.cs" was added for you. We don't need that, so delete it. Add a folder to JavaScriptLibrary called "JavaScript". You will also add two JavaScript files to that folder. Call them "ShowMessage.js" and "GreetUser.js". Next, create a new class called JavaScriptHelper (do not place this in the "JavaScript" folder... it will go at the root level of the JavaScriptLibrary project). By now, your solution structure should look something like the following:
Solution Structure (2 Projects, 2 JS Files, 1 Code File, and 1 Webpage) A couple of empty JavaScript files aren't going to do us any good, so let's put something in them. For starters, "ShowMessage.js" will hold a function called ShowMessage():
Collapse
function ShowMessage(msg) {
    alert("Message From Website: " + msg);
}
The "GreetUser.js" file will have its own function, GreetUser():
Collapse
function GreetUser() {
    ShowMessage("Greetings and Salutations!");
}
Notice that GreetUser() is dependent upon ShowMessage(). We will be handling that later.

Embedding the JavaScript Files

Rather than have to deploy our JavaScript files to our website, we'd like them to be embedded into the DLL. That way, if the DLL is deployed to the website, all JavaScript files are also automatically deployed. Doing this is very simple; all we need to do is go to the properties for each JavaScript file and change the "build action" from "content" to "embedded resource":
Set Build Action To Embedded Resource While that will ensure the files get embedded into the DLL, you must still make them available to the web client. Before you do that, the JavaScriptLibrary project needs to reference System.Web:
Add Reference To System.Web Once you have added that reference, edit "JavaScriptHelper.cs" by adding the following using statement and assembly attributes:
Collapse
using System.Web.UI;

[assembly: WebResource("JavaScriptLibrary.JavaScript.ShowMessage.js", "application/x-javascript")]
[assembly: WebResource("JavaScriptLibrary.JavaScript.GreetUser.js", "application/x-javascript")]
That will enable your embedded JavaScript files to be accessible from the client computer.

Including the Embedded JavaScript Files

Now that you have embedded the JavaScript files and made them accessible via the client computer, you must actually reference them from the pages they are used on. To facilitate this, we will fill in our JavaScriptHelper class:
Collapse
using System;
using System.Web.UI;

[assembly: WebResource("JavaScriptLibrary.JavaScript.ShowMessage.js", "application/x-javascript")]
[assembly: WebResource("JavaScriptLibrary.JavaScript.GreetUser.js", "application/x-javascript")]

namespace JavaScriptLibrary
{

    /// <summary>
    /// Helps include embedded JavaScript files in pages.
    /// </summary>
    public class JavaScriptHelper
    {

        #region Constants

        private const string NAME_SHOW_MESSAGE = "JavaScriptLibrary.JavaScript.ShowMessage.js";
        private const string NAME_GREET_USER = "JavaScriptLibrary.JavaScript.GreetUser.js";

        #endregion

        #region Public Methods

        /// <summary>
        /// Includes ShowMessage.js in the page.
        /// </summary>
        /// <param name="manager">Accessible via Page.ClientScript.</param>
        public static void Include_ShowMessage(ClientScriptManager manager)
        {
            IncludeJavaScript(manager, NAME_SHOW_MESSAGE);
        }

        /// <summary>
        /// Includes GreetUser.js (and all dependencies) in the page.
        /// </summary>
        /// <param name="manager">Accessible via Page.ClientScript.</param>
        public static void Include_GreetUser(ClientScriptManager manager)
        {

            // Dependency (ShowMessage.js).
            Include_ShowMessage(manager);

            // Include GreetUser.js.
            IncludeJavaScript(manager, NAME_GREET_USER);

        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Includes the specified embedded JavaScript file in the page.
        /// </summary>
        /// <param name="manager">Accessible via Page.ClientScript.</param>
        /// <param name="resourceName">The name used to identify the embedded JavaScript file.</param>
        private static void IncludeJavaScript(ClientScriptManager manager, string resourceName)
        {
            var type = typeof(JavaScriptLibrary.JavaScriptHelper);
            manager.RegisterClientScriptResource(type, resourceName);
        }

        #endregion

    }

}
The IncludeJavaScript() function is what does all the magic. It ensures a script tag gets inserted for an embedded JavaScript file, which it does by calling RegisterClientScriptResource(). IncludeJavaScript() is called by Include_GreetUser(). Notice also that Include_GreetUser() calls Include_ShowMessage(), which means it handles dependencies for the user of the class. Any page that includes the GreetUser() function will also include the ShowMessage() function.
Now that we have that class available for our use, let's put it to use on the "Default.aspx" page. You can start by making sure ParchmentPurveyor has a reference to JavaScriptLibrary:
Add Reference To JavaScriptLibrary Next, we'll need to modify the code behind to include the JavaScript on the page.
Collapse
using System;
using System.Web.UI;

namespace ParchmentPurveyor
{
    public partial class Default : System.Web.UI.Page
    {
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            JavaScriptLibrary.JavaScriptHelper.Include_GreetUser(Page.ClientScript);
        }
    }
}
Finally, we just have one thing left to do -- call the GreetUser() function from the page. To do this, all we need to do is add the following JavaScript to the page (I chose to add it in the head tag):
Collapse
<head runat="server">
    <title>Parchment Purveyor</title>
    <script type="text/javascript">
        window.onload = function () { GreetUser(); };
    </script>
</head>
That's it! You are done! Well, mostly. There are a few more niggling cases to handle. Before we get to those, however, let's look at the fruits of our labor:
It Works! Here is what your HTML might look like when you view the source of the page (I shortened and removed some values):
Collapse
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
 Parchment Purveyor
</title>
    <script type="text/javascript">
        window.onload = function () { GreetUser(); };
    </script>
</head>
<body>
    <form method="post" action="Default.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />
</div>

<script src="http://www.codeproject.com/WebResource.axd?d=fslk3GLsk3Slek&amp;t=1234" type="text/javascript"></script>
<script src="http://www.codeproject.com/WebResource.axd?d=fglk3kSl3LS5&amp;t=5678" type="text/javascript"></script>
        <h1>Parchment Purveyor</h1>
        <p>Paper for printers, painting, publication,
            paper planes, and plenty of other plebeian projects!</p>
    </form>
</body>
</html>
Notice there are two script tags that reference something called "WebResource.axd". That is basically a service which serves embedded information to the client. You can read more about "WebResource.axd" here. The important thing to note is that the first script tag is serving up the ShowMessage() function and the second script tag is serving up the GreetUser() function. Both of those script tags were included in the page when you called the Include_GreetUser() function in your JavaScript library.

Late Includes

Sometimes, the above technique does not include the JavaScript file. For example, I work with a third party tool that prevents me from calling .Net code before the render stage. When you call the include functions above during the render stage, the script tags do not get inserted into the page. This is because the beginning of the page has already been rendered to HTML. My solution to this problem is to create an alternate form of the function that inserts the script tag near the bottom of the HTML. I call this a "late include". We can support this technique with a few changes to JavaScriptHelper:
Collapse
using System;
using System.Web;
using System.Web.UI;

[assembly: WebResource("JavaScriptLibrary.JavaScript.ShowMessage.js", "application/x-javascript")]
[assembly: WebResource("JavaScriptLibrary.JavaScript.GreetUser.js", "application/x-javascript")]

namespace JavaScriptLibrary
{

    /// <summary>
    /// Helps include embedded JavaScript files in pages.
    /// </summary>
    public class JavaScriptHelper
    {

        #region Constants

        private const string TEMPLATE_SCRIPT = "<script type=\"text/javascript\" src=\"{0}\"></script>\r\n";
        private const string NAME_SHOW_MESSAGE = "JavaScriptLibrary.JavaScript.ShowMessage.js";
        private const string NAME_GREET_USER = "JavaScriptLibrary.JavaScript.GreetUser.js";

        #endregion

        #region Public Methods

        /// <summary>
        /// Includes ShowMessage.js in the page.
        /// </summary>
        /// <param name="manager">Accessible via Page.ClientScript.</param>
        /// <param name="late">Include the JavaScript at the bottom of the HTML?</param>
        public static void Include_ShowMessage(ClientScriptManager manager, bool late = false)
        {
            IncludeJavaScript(manager, NAME_SHOW_MESSAGE, late);
        }

        /// <summary>
        /// Includes GreetUser.js (and all dependencies) in the page.
        /// </summary>
        /// <param name="manager">Accessible via Page.ClientScript.</param>
        /// <param name="late">Include the JavaScript at the bottom of the HTML?</param>
        public static void Include_GreetUser(ClientScriptManager manager, bool late = false)
        {

            // Dependency (ShowMessage.js).
            Include_ShowMessage(manager, late);

            // Include GreetUser.js.
            IncludeJavaScript(manager, NAME_GREET_USER, late);

        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Includes the specified embedded JavaScript file in the page.
        /// </summary>
        /// <param name="manager">Accessible via Page.ClientScript.</param>
        /// <param name="resourceName">The name used to identify the embedded JavaScript file.</param>
        /// <param name="late">Include the JavaScript at the bottom of the HTML?</param>
        private static void IncludeJavaScript(ClientScriptManager manager, string resourceName, bool late)
        {
            var type = typeof(JavaScriptLibrary.JavaScriptHelper);
            if (!manager.IsStartupScriptRegistered(type, resourceName))
            {
                if (late)
                {
                    var url = manager.GetWebResourceUrl(type, resourceName);
                    var scriptBlock = string.Format(TEMPLATE_SCRIPT, HttpUtility.HtmlEncode(url));
                    manager.RegisterStartupScript(type, resourceName, scriptBlock);
                }
                else
                {
                    manager.RegisterClientScriptResource(type, resourceName);
                    manager.RegisterStartupScript(type, resourceName, string.Empty);
                }
            }
        }

        #endregion

    }

}
I modified each method to accept an additional parameter, late. This defaults to false, so the methods can still be called the same way they used to be. A value of false will preserve the old behavior. A value of true will cause the script blocks to be included near the end of the HTML. Note also that in the case that late is false, I still call RegisterStartupScript(), but I pass it an empty string (so that function call does not actually insert anything into the HTML). This is done so IsStartupScriptRegistered() will return the correct value. That way, the JavaScript will never be included more than once, even if one of the functions is called with late set to false and then again with late set to true. If you want to see this in action, comment out the OnPreRender() in the code behind and modify the body of the page to look like this:
Collapse
<body>
    <form id="form1" runat="server">
        <h1>Parchment Purveyor</h1>
        <p>Paper for printers, painting, publication,
            paper planes, and plenty of other plebeian projects!</p>
        <%  // This gets called during the render stage.
            JavaScriptLibrary.JavaScriptHelper.Include_GreetUser(Page.ClientScript, true); %>
    </form>
</body>
That will call the version of the function that includes the script tags near the bottom of the HTML, which you can observe by viewing the source of the page when you run the application.

External JavaScript

So far, I've only demonstrated how to include embedded JavaScript. However, it is sometimes desirable to link to an external JavaScript file. To facilitate this, we need to add a new helper function in JavaScriptHelper:
Collapse
/// <summary>
/// Includes the specified external JavaScript file in the page.
/// </summary>
/// <param name="page">The current page.</param>
/// <param name="key">The name used to uniquely identify the external JavaScript file.</param>
/// <param name="httpUrl">The URL of the external JavaScript file.</param>
/// <param name="httpsUrl">The URL of the external JavaScript file when SSL is enabled.</param>
/// <param name="late">Include the JavaScript at the bottom of the HTML?</param>
private static void IncludeExternalJavaScript(Page page, string key, string httpUrl, string httpsUrl, bool late)
{
    var manager = page.ClientScript;
    var type = typeof(JavaScriptLibrary.JavaScriptHelper);
    bool isStartupRegistered = manager.IsStartupScriptRegistered(type, key);
    bool isScriptRegistered = manager.IsClientScriptIncludeRegistered(type, key);
    if (!(isStartupRegistered || isScriptRegistered))
    {
        string url;
        if (page.Request.Url.Scheme.ToLower() == "http")
        {
            url = httpUrl;
        }
        else
        {
            url = httpsUrl;
        }
        if (late)
        {
            manager.RegisterStartupScript(type, key, string.Format(TEMPLATE_SCRIPT, HttpUtility.HtmlEncode(url)));
        }
        else
        {
            manager.RegisterClientScriptInclude(type, key, url);
        }
    }
}
As an example of an external file you might include, I'll use the jQuery file hosted by Microsoft's CDN. Just like the other JavaScript files, you will create a function in JavaScriptHelper to include jQuery on the page:
Collapse
private const string NAME_JQUERY = "jQuery";
private const string URL_JQUERY = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js";
private const string URL_JQUERY_HTTPS = "https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js";

/// <summary>
/// Includes jQuery.js in the page.
/// </summary>
/// <param name="page">The current page. Pass in null to get the current page from the HTTP context.</param>
/// <param name="late">Include the JavaScript at the bottom of the HTML?</param>
public static void Include_jQuery(Page page, bool late = false)
{
    if (page == null)
    {
        page = (Page)HttpContext.Current.Handler;
    }
    IncludeExternalJavaScript(page, NAME_JQUERY, URL_JQUERY, URL_JQUERY_HTTPS, late);
}
Finally, you can include jQuery on your page by calling your function from the OnPreRender() function in your page:
Collapse
protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender(e);
    JavaScriptLibrary.JavaScriptHelper.Include_jQuery(Page);
    JavaScriptLibrary.JavaScriptHelper.Include_GreetUser(Page.ClientScript);
}
If you run your application and view the source of the page, you'll see that jQuery gets included:
Collapse
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js" type="text/javascript"></script>

Adding New JavaScript Files

Once you have everything setup, there are only a few steps you need to complete when adding new JavaScript files:
  • Add the ".js" file to the "JavaScript" folder. Skip this step for external JavaScript files.
  • Set the "build action" to "embedded resource". Skip this step for external JavaScript files.
  • Add the assembly attribute to indicate the JavaScript file is a web resource. Skip this step for external JavaScript files.
  • Create a function in JavaScriptHelper to include your JavaScript file.
  • Call the function you just created from a page, control, or masterpage.

What Did You Gain?

After all this work with the same apparent HTML output, you might be asking yourself, "what did I really gain by adding all this extra code?" Well, here are a few solutions presented by this approach:
  • Inline JS. You have reduced page bloat by avoiding putting your JavaScript library inline in the page.
  • Deploying JS. You do not need to include the ".js" files when you deploy your web application. Deploying the DLL will be enough.
  • Bad References. Even if you change the path of your application, you will not have to worry about changing your JavaScript paths.
  • Dependencies. Dependencies are managed automatically. If you included "GreetUser.js", "ShowMessage.js" will automatically be included.
  • Unused JS. No JavaScript is included on the page unless you call the function to include it. This will avoid having unused JavaScript on the page (potentially speeding up load times for users).
  • HTTP / HTTPS. The code outputs script tags that do not include the protocol, so the protocol should be the same as the current page (i.e., HTTP or HTTPS). 
Article Source: http://www.codeproject.com/KB/aspnet/Manage_JS_In_AspNet.aspx

Friday, May 20, 2011

ASP.NET MVC 3 and the @helper syntax within Razor

ASP.NET MVC 3 supports a new view-engine option called “Razor” (in addition to continuing to support/enhance the existing .aspx view engine).  Razor minimizes the number of characters and keystrokes required when writing a view template, and enables a fast, fluid coding workflow.
Unlike most template syntaxes, with Razor you do not need to interrupt your coding to explicitly denote the start and end of server blocks within your HTML. The Razor parser is smart enough to infer this from your code. This enables a compact and expressive syntax which is clean, fast and fun to type.
You can learn more about Razor from some of the blog posts I’ve done about it over the last last 9 months:
Today’s blog post covers a cool feature of Razor that a lot of people don’t know about – which is the ability to define re-usable helper methods using the @helper syntax.

Simple @helper method scenario

The @helper syntax within Razor enables you to easily create re-usable helper methods that can encapsulate output functionality within your view templates.  They enable better code reuse, and can also facilitate more readable code.  Let’s look at a super-simple scenario of how the @helper syntax can be used. 
Code before we define a @helper method
Let’s look at a simple product listing scenario where we list product details, and output either the price of the product – or the word “FREE!” if the item doesn’t cost anything:
image
The above code is fairly straight-forward, and Razor’s syntax makes it easy to integrate server-side C# code within the HTML. 
One place that is a little messy, though, is the if/else logic for the price.  We will likely output prices elsewhere within the site (or within the same page), and duplicating the above logic everywhere would be error-prone and hard to maintain.  Scenarios like this are prime candidates to extract and refactor into helper methods using the @helper syntax.
Refactoring the above sample using the @helper syntax
Let’s extract the price output logic, and encapsulate it within a helper method that we’ll name “DisplayPrice”.  We can do this by re-writing the sample to the code below:
image
We’ve used the @helper syntax above to define a reusable helper method named “DisplayPrice”.  Just like a standard C#/VB method, it can contain any number of arguments (you can also define the arguments to be either nullable or optional).  Unlike standard C#/VB methods, though, @helper methods can contain both content and code, and support the full Razor syntax within them – which makes it really easy to define and encapsulate rendering/formatting helper methods:
SNAGHTML20fae4df
You can invoke @helper methods just like you would a standard C# or VB method:
SNAGHTML20fcdc86
Visual Studio will provide code intellisense when invoking the method:
image

Reusing @helpers across multiple views

In the example above, we defined our @helper method within the same view template as the code that called it.  Alternatively, we can define the @helper method outside of our view template, and enable it to be re-used across all of the view templates in our project.
We can accomplish this by saving our @helper methods within .cshtml/.vbhtml files that are placed within a \App_Code directory that you create at the root of a project.  For example, below I created a “ScottGu.cshtml” file within the \App_Code folder, and defined two separate helper methods within the file (you can have any number of helper methods within each file):
SNAGHTML2107b6ae
Once our helpers are defined at the app level, we can use them within any view template of our application. 
The ScottGu.cshtml template in the \App_Code folder above will logically compile down to a class called “ScottGu” with static members of “DisplayPrice” and “AnotherHelper” within it.  We can re-write our previous sample to call it using the code below:
SNAGHTML210d65c1
Visual Studio will provide code intellisense when calling app-level helpers like this:
image
May 15th Update: One issue that a few people have pointed out is that when a @helper is saved within the \app_code directory, you don’t by default get access to the ASP.NET MVC Html helper methods within it (e.g. Html.ActionLink(), Html.TextBox(), etc).  You do get access to the built-in HTML helper methods when they are defined in the same file as your views.  This is not supported out of the box, though, when the helpers are within the \app_code directory - we’ll add this in the next release.  Paul Stovall has a nice helper class that you can use in the meantime to access and use the built-in Html helper methods within @helper methods you define in the \app_code directory.  You can learn how to use it here.

Summary

Razor’s @helper syntax provides a convenient way to encapsulate rendering functionality into helper methods that you can re-use within individual view templates, or across all view templates within a project. 
You can use this functionality to write code that is even cleaner and more maintainable. 

Article Source: http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor.aspx

Thursday, May 19, 2011

Introduction to ASP.NET MVC 3

Introduction

ASP.NET MVC framework follows the well-defined MVC pattern to create a web application. MVC design pattern is used to separate the different parts of the application for more scalability, extensibility and testability purpose.
One of the major challenges with normal web forms is the testability of the business logic. Unit test of code-behind logic is very complex. Also, the extensibility of the application required lot of re-work on the application. ASP.NET MVC addresses the pain points associated with the traditional web form applications.
In this article, we will discuss about how to create an MVC application and understand the Controller, Views & Models.

MVC

MVC means Model View Controller. Controller takes care of the overall execution of a request. Controller receives the request from the web server and identifies the data requirements. Depends on the data requirements, Controller contact the corresponding Model. Model will supply the required data, which will be rendered to the UI using a View.
1.png
For working with ASP.NET MVC, we can install the Web Platform Installer, which consists of Visual Studio 2010 Express for Coding the MVC application, SQL Server Express for storing the data and IIS Express for hosting the application. We can download the Web Platform Installer from Microsoft Web Platform Installer 3.0.

How to Create an ASP.NET MVC application

Let us start our discussion by creating the first MVC application. File-> New Project and select the ASP.NET MVC 3 Web Application template.
2.png
This will open the New ASP.NET MVC 3 Project window.
3.png
Select either Empty or Internet Application. Empty will create a blank application. Internet application will create an application with few default pages. For our sample, I will select the Internet Application option.
We can choose to create a test project along with our MVC application from the same window. Also, we can choose the View Engine as ASPX or Razor. ASPX is for backward compatibility.
Our new Solution will look like
4.png
We have different folders to hold the Controllers, Views and Models. As we selected Internet Application, our application is a fully functional application. We can run it and see the pages.
5.png
It opens a small application with two tabs Home and about. Also, we have the option to Log On, from where we can register a new User.
When you select the About tab, it goes to the HomeController and returns a View using the About() method. About() is not specified any View name, so the controller will goes to the Views and find the directory corresponding to the HomeController. Here also it uses the name of the controller to find the corresponding directory. Then the controller checks whether it contains any view with the name About.
6.png
We can specify a View name in the About() method like
Collapse
public ActionResult About()
{
    return View("Index");
}
Now, both Home and About display the same content.

Data Passing from Controller to View

Now, let us see, how we can pass some information to the View from Controller. There are two ways to pass data from Controller to View.

Using ViewBag

ViewBag is a dynamic object, where we can add any properties dynamically.
For example, if I want to pass some contact information like Name and Contact number to About View from the Home controller, we can define it using the ViewBag as
Collapse
public ActionResult About()
{
    ViewBag.ContactPerson = "George MAthew";
    ViewBag.ContactNumber = "91-99444444000";
    return View();
}
This data will be accessed in about.cshtml as
Collapse
@{    
   ViewBag.Title = "About Us";
}
<h2>About</h2>
<div>    
      Contact person : @ViewBag.ContactPerson 
      Contact Number : @ViewBag.Contactnumber
</div>
Note, that the dynamic properties added are not case sensitive. Also, it won’t throw any exception, in case of a wrong dynamic property reference.
Now, our About tab looks like
7.png

Using Model

Now, let us see how we can pass data using a Model. Define a Model class and Specify required properties. Our sample Model class looks like
Collapse
namespace SampleApp.Models
{
    public class ContactAddress   
    {
       public string Address { get; set; }
       public string City { get; <br />set; }
       public string Country { get; set; }
    }
}
Now, let us construct the Model in Controller and Pass the same to our View
Collapse
public ActionResult About()
{
    var address = new ContactAddress()
    {
        Address = "Lane 21, Gachibowli",
        City = "Hyderabad",
        Country = "India"
    };
    
    return View(address);
}
Now, we will use the same in our View. In View, we have another object called Model, which holds the dynamic properties like ViewBag. We can extract the model properties using Model.
Collapse
@{
    ViewBag.Title = "About Us";
}
<h2>About</h2>
<div>
  Contact Address: @Model.Address, @Model.City, @Model.Country
</div>
Now, our About tab look like
8.png
Notice that there is no intellisense support for the Model properties. We can define the type of the expected model on top of the View, which will gives the Intellisense support for the Model object.
9.png

Conclusion

In this article we discussed about the ASP.NET MVC framework, how to create a basic MVC application and discussed about the Controller to View communication. We have lot more to discuss in MVC like the Content folder holding all images and styles, Scripts folder with jQuery scripts and MVC detail. We will discuss the topics in details latter.

Article Source: http://www.codeproject.com/KB/aspnet/ASP_Net_MVC_3.aspx