<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Steve Wellens </title><link>https://weblogs.asp.net:443/stevewellens/</link><description>Programming in the .Net environment</description><item><title>SignalR is Magic</title><link>https://weblogs.asp.net:443/stevewellens/signalr-is-magic</link><description>&lt;p&gt;Recently, I attended a Twin Cities .NET User Group presentation on SignalR.&amp;nbsp; I had heard about SignalR several times and was curious.&amp;nbsp;&amp;nbsp; Plus there was free pizza&amp;hellip;&amp;lt;burp&amp;gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SignalR has revamped the way I think about web sites.&lt;/strong&gt;&amp;nbsp;&amp;nbsp; Normally, a browser requests some data and the server sends it.&amp;nbsp; Ajax allows discreet calls to avoid full post-backs and full page rendering&amp;hellip;but it is still a &amp;ldquo;request and wait&amp;rdquo; protocol.&amp;nbsp; A web client can also poll a web server which allows the server to choose when and what to send to the clients.&amp;nbsp; But that is a kind of &amp;lsquo;duct-tape&amp;rsquo; programming.&amp;nbsp;&amp;nbsp; It is interesting to note that internally SignalR will fall back to polling protocols if a more modern transport isn&amp;rsquo;t supported by the browser.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;In a nutshell:&amp;nbsp; SignalR allows the server to actively push data to clients. &amp;nbsp;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I decide to try writing my own SignalR Application:&amp;nbsp; A Live Golf Scoring system.&amp;nbsp;&amp;nbsp;&amp;nbsp; Here is a link to a live demo of the final application:&amp;nbsp; &lt;a href="http://www.stevewellens.com/LiveGolfScores/" target="_blank"&gt;http://www.stevewellens.com/LiveGolfScores/&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Here is what the final product looks like, note there are three browsers, IE, Chrome and FF all showing the exact same data:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://aspblogs.blob.core.windows.net:443/media/stevewellens/2014/ThreeBrowsers.png" height="911" width="854" /&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how I did it.&lt;/p&gt;
&lt;p&gt;1) In Visual Studio, select File, New Web Site&amp;hellip;, Asp.Net Empty Web Site (.Net Framework 4.5 is the default).&lt;/p&gt;
&lt;p&gt;2) Add a default.aspx page.&amp;nbsp;&amp;nbsp; Right click the project and select Add, Add New Item, Web Form.&amp;nbsp;&amp;nbsp; You might want to type something on the form and run the program&amp;hellip;just to make sure things are OK.&lt;/p&gt;
&lt;p&gt;3) Use Nuget to add Micosoft ASP.NET SignalR.&amp;nbsp;&amp;nbsp; If you&amp;rsquo;ve never used Nuget, it is like a sous-chef for programmers:&amp;nbsp; It does the dirty, tedious work.&amp;nbsp; It adds SignalR and all the dependent libraries automatically:&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;img alt="" src="https://aspblogs.blob.core.windows.net:443/media/stevewellens/2014/NugetPackages.png" height="556" width="814" /&gt;&lt;/p&gt;
&lt;p&gt;Holy Crap!&amp;nbsp;&amp;nbsp; That&amp;rsquo;s a lot of stuff.&amp;nbsp;&amp;nbsp; It also added jQuery library files.&amp;nbsp; I swallowed the bile that was rising in my throat and bravely moved on.&lt;br /&gt;&lt;br /&gt;4) Next I had to add an OWIN Startup class.&amp;nbsp; This was new to me.&amp;nbsp;&amp;nbsp; I didn&amp;rsquo;t want to spend hours studying what all those libraries do.&amp;nbsp;&amp;nbsp; That would defeat the reason for using third-party tools.&amp;nbsp; So I just followed the instructions in the readme.txt file that was installed.&amp;nbsp;&amp;nbsp; You can also right click the project and select Add OWIN Startup Class.&lt;br /&gt;&lt;br /&gt;The final Startup.cs code should look like this:&lt;/p&gt;
&lt;pre class="prettyprint"&gt; // Startup.cs&lt;br /&gt;using System;&lt;br /&gt;using System.Threading.Tasks;&lt;br /&gt;using Microsoft.Owin;&lt;br /&gt;using Owin;&lt;br /&gt;&lt;br /&gt;[assembly: OwinStartup(typeof(Startup))]&lt;br /&gt;&lt;br /&gt;public class Startup&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Configuration(IAppBuilder app)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; app.MapSignalR();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;5) Put a breakpoint on app.MapSignalR(); and run the program. Make sure the breakpoint is hit. &lt;em&gt;There is no use proceeding until the startup code runs.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;6) Create a Datatable to hold the golf scores and bind it to a GridView to display them. Note the DataTable is stored in the Application object so all sessions have access to it. The SignalR code also has access to it.&lt;/p&gt;
&lt;p&gt;Notes: My initial attempt worked: 3 people could post scores and each would see the other scores. However, when a 4th person joined, they didn&amp;rsquo;t see the previously entered scores. I realized I needed to store the scores on the server. I ended up throwing away the html table I started with and used a DataTable to store the scores and a GridView to display them.&lt;/p&gt;
&lt;p&gt;For completeness, below is the entire code of default.aspx.cs:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Data;&lt;br /&gt;using System.Web;&lt;br /&gt;using System.Web.UI;&lt;br /&gt;&lt;br /&gt;public partial class _Default : System.Web.UI.Page&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ---- Page Load ------------------------&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // populate the listboxes&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DDLPlayer.Items.Add("Tiger");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DDLPlayer.Items.Add("Phil");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DDLPlayer.Items.Add("Rory");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DDLPlayer.Items.Add("Steve");&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int Hole = 1; Hole &amp;lt;= 18; Hole++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DDLHole.Items.Add(Hole.ToString());&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int Score = 1; Score &amp;lt; 10; Score++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DDLScore.Items.Add(Score.ToString());&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // populate the GridView&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GridViewScores.DataSource = GetScoresTable();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GridViewScores.DataBind();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ---- Get Scores Table ----------------------------------------------&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // if it doesn't exist yet, create it.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // it uses what ever players are in the DDLPlayer object&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private DataTable GetScoresTable()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataTable ScoresTable = Application["ScoresTable"] as DataTable;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ScoresTable == null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScoresTable = new DataTable();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScoresTable.Columns.Add(new DataColumn(@"Golfer\Hole", typeof(String)));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int HoleIndex = 1; HoleIndex &amp;lt;= 18; HoleIndex++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScoresTable.Columns.Add(new DataColumn(HoleIndex.ToString(), typeof(int)));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int PlayerCount = 0; PlayerCount &amp;lt; DDLPlayer.Items.Count; PlayerCount++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScoresTable.Rows.Add(ScoresTable.NewRow());&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int PlayerCount = 0; PlayerCount &amp;lt; DDLPlayer.Items.Count; PlayerCount++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScoresTable.Rows[PlayerCount][0] = DDLPlayer.Items[PlayerCount].Text;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // PrimaryKey is needed so we can find the player row to update&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScoresTable.PrimaryKey = new DataColumn[] { ScoresTable.Columns[0] };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application["ScoresTable"] = ScoresTable;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ScoresTable;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;7) Next we need a way for a client to call the server.&amp;nbsp;&amp;nbsp; &lt;strong&gt;This is SignalR stuff:&lt;/strong&gt;&amp;nbsp; Create a class derived from Microsoft.AspNet.SignalR.Hub and add the PostScoreToServer function to it.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;//ScoresHub.cs:
using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Web;&lt;br /&gt;using Microsoft.AspNet.SignalR;&lt;br /&gt;using System.Data;&lt;br /&gt;&lt;br /&gt;public class ScoresHub : Hub&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ---- Post Score To Server ------------------------------------------&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // called by clients&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // (this gets converted to a callable javaScript function called postScoreToServer &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; and is sent to the clients)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void PostScoreToServer(String Player, int Hole, int Score)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // send the new score to all the other clients&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Clients.All.SendMessageToClient(Player, Hole, Score);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // store the scores in a 'global' table so new clients get a complete list&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataTable ScoresTable = HttpContext.Current.Application["ScoresTable"] as DataTable;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataRow CurrentPlayer = ScoresTable.Rows.Find(Player);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CurrentPlayer[Hole] = Score;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Here is the first bit of magic:&amp;nbsp;&lt;/strong&gt; When SignalR starts up, it parses the ScoresHub code and creates JavaScript that gets sent to the clients when the client requests it.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;&lt;span style="font-family: courier new,courier,monospace;"&gt;&lt;strong&gt;Server&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Client&lt;/strong&gt; 
PostScoreToServer C# ----- &lt;span style="background-color: #ffff00;"&gt;SignalR Magic&lt;/span&gt; -----&amp;gt; postScoreToServer JS&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;8) Then we need a way for the Server call a client function.&amp;nbsp;&amp;nbsp; In other words, where did the SendMessageToClient function come from?&amp;nbsp; Rather than include it piecemeal, here is the entire Default.aspx file:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;lt;%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;head runat="server"&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;Live Golf Scores from Steve Wellens&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;script src="Scripts/jquery-1.10.2.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script src="Scripts/jquery.signalR-2.0.1.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script src='&amp;lt;%: ResolveClientUrl("~/signalr/hubs") %&amp;gt;' type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;script&amp;gt;&lt;br /&gt;        var scoresHub;&lt;br /&gt;&lt;br /&gt;        $(document).ready(DocReady);&lt;br /&gt;&lt;br /&gt;        // ---- Doc Ready -------------------------------------------&lt;br /&gt;&lt;br /&gt;        function DocReady()&lt;br /&gt;        {&lt;br /&gt;            $("#ButtonPostScore").click(PostScoreToServer);     // hook up button click&lt;br /&gt;&lt;br /&gt;            // use a global variable to reference the hub. &lt;br /&gt;            scoresHub = $.connection.scoresHub;&lt;br /&gt;&lt;br /&gt;            // supply the hub with a client function it can call&lt;br /&gt;            scoresHub.client.SendMessageToClient = HandleMessageFromServer;&lt;br /&gt;&lt;br /&gt;            $.connection.hub.start();   // start the local hub&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // ---- Post Score to Server ------------------------------------&lt;br /&gt;&lt;br /&gt;        function PostScoreToServer(Player, Hole, Score)&lt;br /&gt;        {&lt;br /&gt;            var Player = $("#DDLPlayer").val();&lt;br /&gt;            var Hole = $("#DDLHole").val();&lt;br /&gt;            var Score = $("#DDLScore").val();&lt;br /&gt;&lt;br /&gt;            scoresHub.server.postScoreToServer(Player, Hole, Score);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // ---- Handle Message From Server -------------------------------&lt;br /&gt;&lt;br /&gt;        function HandleMessageFromServer(Player, Hole, Score)&lt;br /&gt;        {&lt;br /&gt;            // get the correct table row&lt;br /&gt;            var tableRow = $("#GridViewScores td").filter(function ()&lt;br /&gt;            {&lt;br /&gt;                return $(this).text() == Player;&lt;br /&gt;            }).closest("tr");&lt;br /&gt;&lt;br /&gt;            // update the hole with the score&lt;br /&gt;            tableRow.find('td:eq(' + Hole + ')').html(Score);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;style&amp;gt;&lt;br /&gt;        table, th, td {&lt;br /&gt;            border: 1px solid black;&lt;br /&gt;            border-collapse: collapse;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        td {&lt;br /&gt;            width: 2em;&lt;br /&gt;        }&lt;br /&gt;    &amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;form id="form1" runat="server"&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;asp:GridView ID="GridViewScores" runat="server"&amp;gt;&lt;br /&gt;        &amp;lt;/asp:GridView&amp;gt;&lt;br /&gt;        &amp;lt;p&amp;gt;&lt;br /&gt;            Player: &amp;lt;asp:DropDownList ID="DDLPlayer" runat="server"&amp;gt;&amp;lt;/asp:DropDownList&amp;gt;&lt;br /&gt;            Hole:   &amp;lt;asp:DropDownList ID="DDLHole"   runat ="server"&amp;gt;&amp;lt;/asp:DropDownList&amp;gt;&lt;br /&gt;            Score:  &amp;lt;asp:DropDownList ID="DDLScore"  runat="server"&amp;gt;&amp;lt;/asp:DropDownList&amp;gt;&lt;br /&gt;&lt;br /&gt;            &amp;lt;input id="ButtonPostScore" type="button" value="Post Score" /&amp;gt;&lt;br /&gt;        &amp;lt;/p&amp;gt;&lt;br /&gt;        &amp;lt;h3&amp;gt;View this page with multiple browsers to see how SignalR works!&amp;lt;/h3&amp;gt;&lt;br /&gt;    &amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Here is the second bit of magic:&amp;nbsp;&lt;/strong&gt; Assigning* a function to the client Hub makes the function available to the server!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; scoresHub.client.SendMessageToClient = HandleMessageFromServer;&lt;br /&gt;&lt;br /&gt;*Remember, JavaScript allows you to attach new variables and function onto any object.&lt;/p&gt;
&lt;p&gt;When the client hub starts up, the attached function metadata gets sent to the server and converted to C# code&amp;hellip;.to be called by the server!&lt;/p&gt;
&lt;pre&gt;&lt;span style="font-family: courier new,courier,monospace;"&gt;&lt;strong&gt;Client&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;       &amp;nbsp;&amp;nbsp; Server&lt;/strong&gt;
HandleMessageFromServer JS ---- &lt;span style="background-color: #ffff00;"&gt;SignalR Magic &lt;/span&gt;-----&amp;gt; SendMessageToClient C#&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;Done.&amp;nbsp; That is it.&amp;nbsp; That is the magic of SignalR.&lt;/p&gt;
&lt;p&gt;Here is a link to a live demo:&amp;nbsp;&amp;nbsp; &lt;a href="http://www.stevewellens.com/LiveGolfScores/" target="_blank"&gt;http://www.stevewellens.com/LiveGolfScores/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bonus Note:&amp;nbsp; Almost every article on SignalR warns of the gotcha that when the server function is in Pascal case, it gets converted to Camel case:&amp;nbsp;&amp;nbsp; MyFunction -&amp;gt; myFunction.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Going from client to server doesn&amp;rsquo;t have that problem since you specify both the C# function name and the JavaScript function name:&amp;nbsp; scoresHub.client.SendMessageToClient=HandleMessageFromServer;&lt;/p&gt;
&lt;h3&gt;Finale&lt;/h3&gt;
&lt;p&gt;I wish that was the end of my epic tale&amp;hellip;.but it isn&amp;rsquo;t. Here is roughly how I spent my time:&lt;/p&gt;
&lt;table border="1" cellpadding="3" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Activity&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Developer Time&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;SignalR code&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&amp;nbsp;5 percent&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;DataTable, GridView, Html, CSS&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;30 percent&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;Deployment*&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;65 percent&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;*Deployment did not go smoothly.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When the SignalR server code runs, it prepares JavaScript code to be sent to the client. When I deployed the application, the client requested the code but it could not be found: There were runtime exceptions at the client.&lt;/p&gt;
&lt;p&gt;Doing online searches for SignalR help is tough. Much of the information is MVC specific which I wasn&amp;rsquo;t using (that architecture is not appropriate for every application). Much of the information I found was already out of date and obsolete. These are all suggestions I found researching my problem:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;lt;%--&amp;lt;script src="signalr/hubs/" &amp;gt;&amp;lt;/script&amp;gt;--%&amp;gt;&lt;br /&gt;&amp;lt;%--&amp;lt;script src="/signalr/signalr/hubs/" &amp;gt;&amp;lt;/script&amp;gt;--%&amp;gt;&lt;br /&gt;&amp;lt;%--&amp;lt;script src="/signalr/hubs/" &amp;gt;&amp;lt;/script&amp;gt;--%&amp;gt;&lt;br /&gt;&amp;lt;%--&amp;lt;script src="~/signalr/hubs"&amp;gt;&amp;lt;/script&amp;gt;--%&amp;gt;&lt;br /&gt;&amp;lt;%--&amp;lt;script src="Scripts/ScoresHub.js"&amp;gt;&amp;lt;/script&amp;gt; (hard copy of scripts)--%&amp;gt;&lt;br /&gt;&amp;lt;script src='&amp;lt;%: ResolveClientUrl("~/signalr/hubs") type="text/javascript" %&amp;gt;'&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Some posts suggested certain libraries needed to be on IIS so I contacted my hosting service and described my problem.&lt;/p&gt;
&lt;p&gt;They asked me to create a new sub-domain and try running my project from that. It worked! Whew, that meant the server and IIS was configured properly.&lt;/p&gt;
&lt;p&gt;I was&lt;em&gt; running the application from a subdirectory&lt;/em&gt; on my main domain and apparently SignalR doesn&amp;rsquo;t like that&amp;hellip;it gets confused.&lt;/p&gt;
&lt;p&gt;I contacted the hosting service again and said I didn&amp;rsquo;t want to use a sub-domain. They suggested using a virtual directory that pointed to the subdirectory. I tried it and it worked!&lt;/p&gt;
&lt;p&gt;I normally don&amp;rsquo;t do this, but I&amp;rsquo;ve got to plug my host provider:&amp;nbsp;&amp;nbsp; &lt;a href="http://www.arvixe.com/" target="_blank"&gt;http://www.arvixe.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arvixe is the best. I have had nothing but good experiences with them.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(Don&amp;rsquo;t ask me about my cell phone service provider support&amp;hellip;THAT was a totally different experience involving frustration, profanity and wasted time trying to communicate with incompetent boobs).&lt;/p&gt;
&lt;p&gt;I hope someone finds this useful.&lt;br /&gt;&lt;br /&gt;Steve Wellens&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a style="display: none;" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve Wellens" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Tue, 02 Sep 2014 20:46:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/signalr-is-magic</guid><category>Asp.Net</category><category>SignalR</category></item><item><title>Secret Covert Hush-Hush White Space in the DOM…EXPOSED!</title><link>https://weblogs.asp.net:443/stevewellens/secret-covert-hush-hush-white-space-in-the-dom-exposed</link><description>&lt;p&gt;Lurking in the shadows of the Stack Overflow website, selling aerosol cans of Bug-No-More to the rubes, I came across a question I thought I could answer. The OP (original poster) was using JavaScript to select and modify HTML elements without success.&lt;/p&gt;
&lt;p&gt;The HTML was simple:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;&amp;lt;a href="#" id="prev"&amp;gt;Prev&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;&amp;lt;a href="#" id="middle"&amp;gt;Middle&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;&amp;lt;a href="#" id="next"&amp;gt;Next&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;/pre&gt;
&lt;p&gt;First he created a simple function to make sure the basics were working (a very good practice). It colored the middle &lt;i&gt;li&lt;/i&gt; element and it worked fine:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;function middle()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("middle").parentNode.style.backgroundColor = "yellow";&lt;br /&gt;}&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;get the middle element using its id (an &lt;i&gt;a&lt;/i&gt; tag)&lt;/li&gt;
&lt;li&gt;move up one element via the parentnode (to the&lt;i&gt; li&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;color the&lt;i&gt; li &lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/MiddleColored.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/MiddleColored.png" /&gt;&lt;/p&gt;
&lt;p&gt;Next, he created a function to color the &lt;i&gt;siblings&lt;/i&gt; of the middle element.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;function prevNextSibling()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("middle").parentNode.previousSibling.style.backgroundColor = "pink";&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("middle").parentNode.nextSibling.style.backgroundColor = "cyan";&lt;br /&gt;}&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;get the middle element using it's id (an&lt;i&gt; a&lt;/i&gt; tag)&lt;/li&gt;
&lt;li&gt;move up one element via the parentnode (to the&lt;i&gt; li&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;get the previous/next sibling&lt;/li&gt;
&lt;li&gt;color the&lt;i&gt; li&amp;nbsp;&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It didn't work.&lt;/p&gt;
&lt;p&gt;When I debugged the code, I saw that nextSibling was returning an object that did not have a style property. What the heck was up with that?&lt;/p&gt;
&lt;p&gt;In FireFox the debugging window looked like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/FireFoxDebug.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/FireFoxDebug.png" /&gt;&lt;/p&gt;
&lt;p&gt;In Chrome the debugging window looked like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/ChromeDebug.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/ChromeDebug.png" /&gt;&lt;/p&gt;
&lt;p&gt;In Internet Explorer the debugging window looked like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/EE2Debug.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/EE2Debug.png" /&gt;&lt;/p&gt;
&lt;p&gt;Hey, what the heck are those "Text = Empty Text Nodes" in the Internet Explorer window? What they are, my curious friend is the cause of the problem: nextSibling and previousSibling are returning Empty Text Nodes which do not have a style attribute.&lt;/p&gt;
&lt;p&gt;To be perfectly clear:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ALL three browsers have Empty Text Nodes.&lt;/li&gt;
&lt;li&gt;ONLY Internet Explorer displays them in its debugger.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Internet Explorer is the best browser in this situation.&lt;/p&gt;
&lt;p&gt;So what are these Empty Text Nodes?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.w3.org/DOM/faq.html#emptytext" target="_blank" mce_href="http://www.w3.org/DOM/faq.html#emptytext"&gt;http://www.w3.org/DOM/faq.html#emptytext&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;And what is the fix?&lt;/p&gt;
&lt;p&gt;If the siblings are the same type, as they are in the original problem, use:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;previousElementSibling&lt;/p&gt;
&lt;p&gt;nextElementSibling&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Otherwise, move &lt;i&gt;two&lt;/i&gt; siblings to skip over the Empty Text Node sibling:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;previousSibling.previousSibling&lt;/p&gt;
&lt;p&gt;nextSibling.nextSibling&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;Either way, it works:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/SiblingsColored.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2014/SiblingsColored.png" /&gt;&lt;/p&gt;
&lt;p&gt;Oooh, pretty.&lt;/p&gt;
&lt;p&gt;So, in addition to learning about white space nodes in the DOM, we learned that having multiple browsers installed can be a good thing.&lt;/p&gt;
&lt;p&gt;I hope someone finds this useful.&lt;/p&gt;
&lt;p&gt;Steve Wellens&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="display: none;" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Sun, 05 Jan 2014 02:30:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/secret-covert-hush-hush-white-space-in-the-dom-exposed</guid><category>General Software Development</category><category>JavaScript</category></item><item><title>Code Builder for jQuery AJAX (Calling Web Services)</title><link>https://weblogs.asp.net:443/stevewellens/code-builder-for-jquery-ajax-calling-web-services</link><description>&lt;p&gt;Getting stuck in the cycle of code-build-test, code-build-test… can drain you physically, mentally, emotionally and spiritually.  In the back of your mind you know the clock is ticking and you are not making headway.  Of course the boss keeps sticking his sweaty head into your tiny cube and asking, "Any progress?"   What a jerk.  The intern who is &lt;i&gt;supposed&lt;/i&gt; to be helping you keeps asking stupid questions he could find on Google: the lazy meathead.   The department secretary just told you they lost your time sheet so you'll have to fill out another one:  Too bad you didn't make a copy.  Your waist is getting thicker and your hair is getting thinner.
&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Well I can't help you with any of that&lt;/i&gt;.
&lt;/p&gt;
&lt;p&gt;Except, maybe for the first problem; if you are using jQuery's AJAX function, perhaps I can offer relief from the dreaded code-build-test cycle.
&lt;/p&gt;
&lt;p&gt;To help figure out the myriad of options when using the jQuery AJAX function to access Web Services, I created a web page with the most useful (as far as I know) options in a table with check boxes, values and descriptions.   It builds the jQuery AJAX code automatically and you can execute it directly from the web page.   We &lt;i&gt;can&lt;/i&gt; break the cycle of code-build-test.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Here is a sample of the generated code: &lt;/b&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/AAJAXBuilder2.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/AAJAXBuilder2.png"&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Here is part of the Settings table:&lt;/b&gt; &lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/AAJAXBuilder1.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/AAJAXBuilder1.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Here are three divs I connected to three events to display the results: &lt;/b&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/AAJAXBuilder3.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/AAJAXBuilder3.png"&gt;&lt;/p&gt;
&lt;p&gt;So, as you enable options and change their values, the code is updated.  You click the Execute button and wait for the server to respond.
&lt;/p&gt;
&lt;p&gt;I managed to get the code (JavaScript, CSS and HTML) into one file.  Only the jQuery code is external.  So if you are developing calls into a local project, you could download (steal/borrow) the page and put it into your own directory for testing.
&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline"&gt;&lt;b&gt;Notes:
&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The HTML5 CSS property resize:both did not work correctly in all the browsers I tested (OK, it was IE) so I used the jQuery function resizeable.
&lt;/p&gt;
&lt;p&gt;I thought about putting up an hour glass cursor while waiting for the calls to finish or time out.  But the 'A' in AJAX stands for Asynchronous, the web page is not blocked waiting for the server.  An hour glass cursor would be inappropriate.
&lt;/p&gt;
&lt;p&gt;I put Save and Restore buttons in so if you get something that works, you can save it.   Then feel free to experiment knowing you can always go back to a known good set of options.  Typically most people will use this to find the minimum set of options.  To remember the settings, I use &lt;b&gt;localStorage&lt;/b&gt;, an HTML 5 feature.
&lt;/p&gt;
&lt;p&gt;Here are a few free public web services I tested the page with:
&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%2248907%22&amp;amp;format=json
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;span style="font-family:Courier New; font-size:10pt"&gt;http://api.geonames.org/postalCodeLookupJSON?postalcode=55427&amp;amp;country=US&amp;amp;username=demo
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I linked the jQuery libraries locally.  In theory, CDN's are a great idea.  In reality, they can paralyze sites.  The next time you see a web page that is stuck loading, look at the status bar.  Chances are it's loading from an external site.
&lt;/p&gt;
&lt;p&gt;I'm not an expert at jQuery AJAX by any means.  If you see something I missed, or something useful that could be added to the page, please contact me.
&lt;/p&gt;
&lt;p&gt;And, before I forget, a link to the web page:   &lt;a href="http://stevewellens.com/jQueryAJAXBuilder.html" mce_href="http://stevewellens.com/jQueryAJAXBuilder.html"&gt;jQuery AJAX Code Builder&lt;/a&gt;
	&lt;/p&gt;
&lt;p&gt;This was a fun project.  I hope someone finds it useful.
&lt;/p&gt;
&lt;p&gt;Steve Wellens
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Sun, 04 Aug 2013 00:30:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/code-builder-for-jquery-ajax-calling-web-services</guid><category>AJAX</category><category>JavaScript</category><category>JQuery</category><category>Web Services</category></item><item><title>Calling WCF Services with jQuery…Stripped Down</title><link>https://weblogs.asp.net:443/stevewellens/calling-wcf-services-with-jquery-stripped-down</link><description>&lt;p&gt;Years ago, when I created my first ASMX Web Service and called it from an application, it was easy and it was fun. I was able to call functions on a server, from a client, with little effort. What a great and powerful tool!&lt;/p&gt;
&lt;p&gt;Then WCF came out and was deemed the 'best practice' and the 'preferred' method. Developers were encouraged to use it. Sadly, it was a nightmare of complexity. &lt;a href="http://en.wikipedia.org/wiki/Rube_Goldberg" mce_href="http://en.wikipedia.org/wiki/Rube_Goldberg"&gt;Rube Goldberg&lt;/a&gt; would have been proud.&lt;/p&gt;
&lt;p&gt;I recently began investigating calling WCF Services with jQuery. There aren't many articles or working samples that are simple enough to be a good starting point for development or proof of concept. I gathered what I learned and decided to cut out as much superfluous details from the paradigm as possible: I tried to make it palatable.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;This is the smallest working example of jQuery calling a WCF Service anywhere&lt;/i&gt; (as far as I know).&lt;/p&gt;
&lt;h2&gt;Caveats:&lt;/h2&gt;
&lt;p&gt;WCF services are fragile. Use a good source control system or some substitute. If you make a change and everything is still working, check it in and label it. That way, when you break your code (and you will) and can't figure out what happened, you can revert to a known good version.&lt;/p&gt;
&lt;p&gt;Normally the cache is your friend. When developing, the cache is your enemy. When your code changes don't seem to be having any effect, clear the cache and/or restart the web server. Sometimes I put message boxes or log strings in the code to see if it actually being executed.&lt;/p&gt;
&lt;h2&gt;We Don't Need No Stinking Interface:&lt;/h2&gt;
&lt;p&gt;I've got nothing against interfaces; I even blogged about them &lt;a href="http://weblogs.asp.net/stevewellens/archive/2009/07/17/what-s-the-deal-with-interfaces.aspx" mce_href="http://weblogs.asp.net/stevewellens/archive/2009/07/17/what-s-the-deal-with-interfaces.aspx"&gt;here&lt;/a&gt;. But I'm going to guess that less than one percent of web services require the use of an interface&amp;mdash;maybe less than one in a thousand&amp;mdash;maybe less than that.&lt;/p&gt;
&lt;p&gt;The default template for WCF services uses an interface for a contract&amp;mdash;an inexplicably stupid decision.&lt;/p&gt;
&lt;p&gt;Here is how I removed the unneeded complexity.&lt;/p&gt;
&lt;p&gt;In the interface file, the generated class looks something like this:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;[ServiceContract]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;IService1&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [OperationContract]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; GetData(&lt;span style="color: blue;"&gt;int&lt;/span&gt; value);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I moved the contract attributes into the implementation class.&lt;/li&gt;
&lt;li&gt;I added a WebInvoke attribute to the functions.&lt;/li&gt;
&lt;li&gt;I removed the interface inheritance from the service implementation class.&lt;/li&gt;
&lt;li&gt;I deleted (yes deleted!) the interface file.&lt;/li&gt;
&lt;li&gt;In the config file, I changed the contract to be the implementation class, NOT the interface class.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then I deleted all but one function in the implementation class&amp;hellip;to get it really lean and mean.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Here is the final WCF Service CS code: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.ServiceModel.Activation;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.ServiceModel.Web;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;[ServiceContract]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MyService&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [OperationContract]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WebInvoke(Method = &lt;span style="color: #a31515;"&gt;"POST"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; BodyStyle = WebMessageBodyStyle.Wrapped,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; ResponseFormat = WebMessageFormat.Json)]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; MyFunction(&lt;span style="color: blue;"&gt;string&lt;/span&gt; Count)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: #a31515;"&gt;"The Count you passed in is: "&lt;/span&gt; + Count.ToString();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Here is the HTML/JavaScript/jQuery code file. &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #a31515;"&gt;DOCTYPE&lt;/span&gt; &lt;span style="color: red;"&gt;html&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;html&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;head&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Call WCF&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;src&lt;/span&gt;&lt;span style="color: blue;"&gt;="Scripts/jquery.js"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; counter = 0;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; CallMyService()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; counter++;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $.ajax({&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; type: &lt;span style="color: #a31515;"&gt;"POST"&lt;/span&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; url: &lt;span style="color: #a31515;"&gt;"MyService.svc/MyFunction"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; data: &lt;span style="color: #a31515;"&gt;'{"Count": "'&lt;/span&gt; + counter + &lt;span style="color: #a31515;"&gt;'"}'&lt;/span&gt;, &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; contentType: &lt;span style="color: #a31515;"&gt;"application/json"&lt;/span&gt;, &lt;span style="color: green;"&gt;// content type sent to server&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; success: ServiceSucceeded,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; error: ServiceFailed&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// ---- WCF Service call backs -------------------&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; ServiceFailed(result)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Log(&lt;span style="color: #a31515;"&gt;'Service call failed: '&lt;/span&gt; + result.status + &lt;span style="color: #a31515;"&gt;'&amp;nbsp; '&lt;/span&gt; + result.statusText);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; ServiceSucceeded(result)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var &lt;/span&gt;resultObject = result.MyFunctionResult;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Log(&lt;span style="color: #a31515;"&gt;"Success: "&lt;/span&gt; + resultObject);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// ---- Log ----------------------------------------&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// utility function to output messages&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Log(msg)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: #a31515;"&gt;"#logdiv"&lt;/span&gt;).append(msg + &lt;span style="color: #a31515;"&gt;"&amp;lt;br /&amp;gt;"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;head&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;body&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;input&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="Button1"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="button"&lt;/span&gt; &lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;="Execute"&lt;/span&gt; &lt;span style="color: red;"&gt;onclick&lt;/span&gt;&lt;span style="color: blue;"&gt;="CallMyService();"&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="logdiv"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp; &lt;span style="color: green;"&gt;&amp;lt;!--For messages--&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;body&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;html&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note I am using a simple HTML page to call the service. It's my way of showing, "There's nothing up my sleeve." You can download the full project &lt;a href="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/JQUERYCALLWCF.zip" mce_href="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/JQUERYCALLWCF.zip"&gt;here&lt;/a&gt;. I recompiled it to .NET 4.5.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is no project or solution file, open it as a Web Site.&lt;/li&gt;
&lt;li&gt;Run/Browse the &lt;b&gt;CallWCF.html&lt;/b&gt; file.&lt;/li&gt;
&lt;li&gt;Click the Execute button.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You should see this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/jjQueryCallWCF.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/jjQueryCallWCF.png" /&gt;&lt;/p&gt;
&lt;p&gt;I hope someone finds this useful.&lt;/p&gt;
&lt;p&gt;Steve Wellens&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="display: none;" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Mon, 04 Feb 2013 04:50:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/calling-wcf-services-with-jquery-stripped-down</guid><category>.NET</category><category>JQuery</category><category>WCF</category></item><item><title>CSS3 box-shadow and Visual Studio Features</title><link>https://weblogs.asp.net:443/stevewellens/css3-box-shadow-and-visual-studio-features</link><description>&lt;p&gt;A few years ago, while creating an ASP.NET web site, I decided to add a gradient border to "sex up" the look of the site. Using a sophisticated image editing program, I created a small gradient image. I made sure the ending color of the gradient matched the color of the body in the target page. Here it is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BlendLeft.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BlendLeft.png" /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I added CSS to display it like this:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;background-image: url(BlendLeft.ico);
background-repeat: repeat-y;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;The CSS replicated the image up and down the left side of the browser window:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/WebSiteSample.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/WebSiteSample.png" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pretty cool, eh? I decided it would be even cooler to have the gradient &lt;i&gt;on all four sides of the window&lt;/i&gt;. My goal was to make it look like a soft picture frame.&lt;/p&gt;
&lt;p&gt;I spent hours and hours trying to create and use the eight images required.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Top Left Corner&lt;/li&gt;
&lt;li&gt;Top&lt;/li&gt;
&lt;li&gt;Top Right Corner&lt;/li&gt;
&lt;li&gt;Right&lt;/li&gt;
&lt;li&gt;Bottom Right Corner&lt;/li&gt;
&lt;li&gt;Bottom&lt;/li&gt;
&lt;li&gt;Bottom Left Corner&lt;/li&gt;
&lt;li&gt;Left&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I planned and created, sliced and diced, snipped and stitched, hundreds of different gradient images trying to keep the pixel dimensions and color transitions straight. I created several versions of web pages that displayed the images. I tried doing it programmatically where you could enter the start and end colors and the width of the border &amp;mdash; the program generated and saved the eight pre-named images. However, I had no control over the gradient algorithms. I never could get smooth transitions between the images. I started to investigate writing my own gradient algorithms but ran out of time. Alas, I failed like a kite in a hurricane, like a fat kid in gym class, like a poodle in a shark tank.&lt;/p&gt;
&lt;h2&gt;Then CSS3 came out.&lt;/h2&gt;
&lt;p&gt;Two of the interesting new features in CSS3 are text-shadow and box-shadow. Shadows are traditionally used to give a three-dimensional effect to visual elements. While studying and playing with these new features, I was surprised to find the shadows could be placed anywhere and the box-shadow property had an inset tag&amp;hellip;.hmmm.&lt;/p&gt;
&lt;p&gt;I used this on an html body element:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;box-shadow&lt;/span&gt;: &lt;span style="color: blue;"&gt;0&lt;/span&gt; &lt;span style="color: blue;"&gt;0&lt;/span&gt; &lt;span style="color: blue;"&gt;50px&lt;/span&gt; &lt;span style="color: blue;"&gt;green&lt;/span&gt; &lt;span style="color: blue;"&gt;inset&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;hellip;and got this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/FullPage.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/FullPage.png" height="281" width="443" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Yippee ki-yay!!! &lt;/b&gt; This is EXACTLY what I spent hours trying to do&amp;hellip;in one line of code.&lt;/p&gt;
&lt;p&gt;Here is the full CSS for the body tag:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;body
{
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    position: absolute;
    box-shadow: 0 0 50px green inset;
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My holy grail has been found.&lt;/p&gt;
&lt;p&gt;By the way, you can apply the box-shadow to other elements...like this div:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/DivSample.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/DivSample.png" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While playing and experimenting with the new CSS3 features, I came across a few helpful Visual Studio features you may not know about.&lt;/p&gt;
&lt;h2&gt;CSS Color Picker&lt;/h2&gt;
&lt;p&gt;In the CSS editor, when a color is expected, you are given a list of predefined colors to pick from:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/ColorPicker0.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/ColorPicker0.png" height="302" width="313" /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The result looks like this:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;color&lt;/span&gt;: &lt;span style="color: blue;"&gt;red&lt;/span&gt;; &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That's nice, I like seeing the word &lt;b&gt;red&lt;/b&gt; instead of &lt;b&gt;#ff0000&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;If you type '#' to enter a color, you get the following pop-up window:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/ColorPicker1.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/ColorPicker1.png" height="145" width="417" /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That's nice, you can click a color and it will supply the hexadecimal value:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;color&lt;/span&gt;:&lt;span style="color: blue;"&gt;#f00&lt;/span&gt;; &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That's nice too. If you click the double down arrow on the right side of the pop-up and you get this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/ColorPicker2.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/ColorPicker2.png" height="347" width="417" /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can select any color and it will insert the hex values.&lt;/p&gt;
&lt;p&gt;And, you can use the eye dropper to select &lt;i&gt;any color&lt;/i&gt; from &lt;i&gt;any window &lt;/i&gt;showing on your PC.&lt;/p&gt;
&lt;p&gt;And, try moving the Opacity slider. Then you get values that include the alpha component like this:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;color&lt;/span&gt;:&lt;span style="color: blue;"&gt;rgba(255, 216, 0, 0.74)&lt;/span&gt;; &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It's useful AND fun.&lt;/p&gt;
&lt;h2&gt;Multiple Browser Launch&lt;/h2&gt;
&lt;p&gt;First, if your project requirements include targeting multiple browsers, my sincere condolences. It is tedious and painful work.&lt;/p&gt;
&lt;p&gt;But you do get some help from Visual Studio. In the following pull-down select "Browse With&amp;hellip;"&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BrowserSelect0.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BrowserSelect0.png" height="218" width="261" /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unsurprisingly, you get the "Browse With" window:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BrowserSelect1.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BrowserSelect1.png" height="332" width="426" /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As you can see, you can select multiple browsers. Hold down the Control Key and click the browsers you want.&lt;/p&gt;
&lt;p&gt;Then click the 'Set as Default' button.&lt;/p&gt;
&lt;p&gt;You can hit Cancel to exit the window, the settings are remembered.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BrowserSelect2.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2013/BrowserSelect2.png" height="110" width="255" /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now the selection says "Multiple Browsers" and when you start the web site, &lt;i&gt;all the browsers you selected will be launched&lt;/i&gt;. It really speeds things up when you are in tweak-check-tweak-check-tweak-check mode. I wish there was a setting to automatically save all changes before launching the browsers.&lt;/p&gt;
&lt;p&gt;I hope some finds this useful.&lt;/p&gt;
&lt;p&gt;Steve Wellens&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="display: none;" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Wed, 16 Jan 2013 21:30:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/css3-box-shadow-and-visual-studio-features</guid><category>CSS</category><category>Visual Studio</category></item><item><title>Google and Bing Map APIs Compared</title><link>https://weblogs.asp.net:443/stevewellens/google-and-bing-map-apis-compared</link><description>&lt;p&gt;At one of the local golf courses I frequent, there is an open grass field next to the course. It is about eight acres in size and mowed regularly. It is permissible to hit golf balls there&amp;mdash;you bring and shag our own balls. My golf colleagues and I spend hours there practicing, chatting and in general just wasting time.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Ginger.png" style="padding-left: 1em; padding-right: 1em; float: left;" /&gt;&lt;/p&gt;
&lt;p&gt;One of the guys brings Ginger, the amazing, incredible, wonder dog.&lt;/p&gt;
&lt;p&gt;Ginger is a Hungarian Vizlas (or Hungarian pointer). She chases squirrels, begs for snacks and supervises us closely to make sure we don't misbehave.&lt;/p&gt;
&lt;div style="clear: both;"&gt;
&lt;p&gt;&lt;b&gt;Anyway&lt;/b&gt;, I decided to make a dedicated web page to measure distances on the field in yards using online mapping services. I started with Google maps and then did the same application with Bing maps. It is a good way to become familiar with the APIs.&lt;/p&gt;
&lt;p&gt;Here are images of the final two maps:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stevewellens.com/GoogleMapsDemo.html" mce_href="http://stevewellens.com/GoogleMapsDemo.html"&gt;&lt;b&gt;Google:&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/GoogleMapDemo.png" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://stevewellens.com/BingMapsDemo.html" mce_href="http://stevewellens.com/BingMapsDemo.html"&gt;&lt;b&gt;Bing:&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/BingMapDemo.png" /&gt;&lt;/p&gt;
&lt;p&gt;To start with online mapping services, you need to visit the respective websites and get a developers key.&lt;/p&gt;
&lt;p&gt;I pared the code down to the minimum to make it easier to compare the APIs. Google maps required these CSS styles (or it wouldn't work):&lt;/p&gt;
&lt;pre class="prettyprint"&gt;html &lt;br /&gt;{&lt;br /&gt;    height: 100%;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;body &lt;br /&gt;{&lt;br /&gt;    height: 100%;&lt;br /&gt;    margin: 0;&lt;br /&gt;    padding: 0;&lt;br /&gt;}

&lt;/pre&gt;
&lt;p&gt;Here is how the map scripts are included. Google requires the developer Key when loading the JavaScript, Bing requires it when the map object is created:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt; Google: &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;lt;script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=XXXXXXX&amp;amp;libraries=geometry&amp;amp;sensor=false" &amp;gt; &amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;Bing: &lt;/span&gt;&lt;/b&gt;
&lt;pre class="prettyprint"&gt;&amp;lt;script&amp;nbsp; type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"&amp;gt; &amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; I use jQuery to manipulate the DOM elements which may be overkill, but I may add more stuff to this application and I didn't want to have to add it later. Plus, I really like jQuery.&lt;/p&gt;
&lt;p&gt;Here is how the maps are created:&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Common Code (the same for both Google and Bing Maps): &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; gTheMap;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; gMarker1;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; gMarker2;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $(document).ready(DocLoaded);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; DocLoaded()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// golf course coordinates&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; StartLat = 44.924254;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; StartLng = -93.366859;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// what element to display the map in&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; mapdiv = $(&lt;span style="color: #a31515;"&gt;"#map_div"&lt;/span&gt;)[0];&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Google:&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// where on earth the map should display&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; StartPoint = &lt;span style="color: blue;"&gt;new&lt;/span&gt; google.maps.LatLng(StartLat, StartLng);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// create the map&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; gTheMap = &lt;span style="color: blue;"&gt;new&lt;/span&gt; google.maps.Map(mapdiv, &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; center: StartPoint,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; zoom: 18,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; mapTypeId: google.maps.MapTypeId.SATELLITE&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// place two markers&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; marker1 = PlaceMarker(&lt;span style="color: blue;"&gt;new&lt;/span&gt; google.maps.LatLng(StartLat, StartLng + .0001));&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; marker2 = PlaceMarker(&lt;span style="color: blue;"&gt;new&lt;/span&gt; google.maps.LatLng(StartLat, StartLng - .0001));&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DragEnd(&lt;span style="color: blue;"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Bing:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// where on earth the map should display&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; StartPoint = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp; Microsoft.Maps.Location(StartLat, StartLng);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// create the map&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; gTheMap = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Microsoft.Maps.Map(mapdiv,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; credentials: &lt;span style="color: #a31515;"&gt;'XXXXXXXXXXXXXXXXXXX'&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; center: StartPoint,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; zoom: 18,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; mapTypeId: Microsoft.Maps.MapTypeId.aerial&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// place two markers&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; marker1 = PlaceMarker(&lt;span style="color: blue;"&gt;new&lt;/span&gt; Microsoft.Maps.Location(StartLat, StartLng + .0001));&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; marker2 = PlaceMarker(&lt;span style="color: blue;"&gt;new&lt;/span&gt; Microsoft.Maps.Location(StartLat, StartLng - .0001));&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DragEnd(&lt;span style="color: blue;"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; In the Bing documentation, &lt;b&gt;mapTypeId&lt;/b&gt;: was missing from the list of options even though the sample code included it.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; When creating the Bing map, use the developer Key for the credentials property.&lt;/p&gt;
&lt;p&gt;I immediately place two markers/pins on the map which is simpler that creating them on the fly with mouse clicks (as I first tried). The markers/pins are draggable and I capture the DragEnd event to calculate and display the distance in yards and draw a line when the user finishes dragging.&lt;/p&gt;
&lt;p&gt;Here is the code to place a marker:&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Google: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;// ---- PlaceMarker ------------------------------------&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt; PlaceMarker(location)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; marker = &lt;span style="color: blue;"&gt;new&lt;/span&gt; google.maps.Marker(&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; position: location,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; map: gTheMap,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; draggable: &lt;span style="color: blue;"&gt;true&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marker.addListener(&lt;span style="color: #a31515;"&gt;'dragend'&lt;/span&gt;, DragEnd);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; marker;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Bing: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;// ---- PlaceMarker ------------------------------------&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt; PlaceMarker(location)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; marker = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Microsoft.Maps.Pushpin(location,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; draggable : &lt;span style="color: blue;"&gt;true&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Maps.Events.addHandler(marker, &lt;span style="color: #a31515;"&gt;'dragend'&lt;/span&gt;, DragEnd);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; gTheMap.entities.push(marker);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; marker;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here is the code than runs when the user stops dragging a marker:&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Google: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;// ---- DragEnd -------------------------------------------&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; gLine = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt; DragEnd(Event)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; meters = google.maps.geometry.spherical.computeDistanceBetween(marker1.position, marker2.position);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; yards = meters * 1.0936133;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: #a31515;"&gt;"#message"&lt;/span&gt;).text(yards.toFixed(1) + &lt;span style="color: #a31515;"&gt;' yards'&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;   &amp;nbsp;&lt;span style="color: green;"&gt;// draw a line connecting the points&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; Endpoints = [marker1.position, marker2.position];&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (gLine == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; gLine = &lt;span style="color: blue;"&gt;new&lt;/span&gt; google.maps.Polyline({&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; path: Endpoints,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; strokeColor: &lt;span style="color: #a31515;"&gt;"#FFFF00"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; strokeOpacity: 1.0,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; strokeWeight: 2,&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; map: gTheMap&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; gLine.setPath(Endpoints);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;Bing:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;// ---- DragEnd -------------------------------------------&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; gLine = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt; DragEnd(Args)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; Distance =&amp;nbsp; CalculateDistance(marker1._location, marker2._location);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: #a31515;"&gt;"#message"&lt;/span&gt;).text(Distance.toFixed(1) + &lt;span style="color: #a31515;"&gt;' yards'&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// draw a line connecting the points&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; Endpoints = [marker1._location, marker2._location];&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (gLine == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; gLine = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Microsoft.Maps.Polyline(Endpoints, &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; strokeColor: &lt;span style="color: blue;"&gt;new&lt;/span&gt; Microsoft.Maps.Color(0xFF, 0xFF, 0xFF, 0),&amp;nbsp; &lt;span style="color: green;"&gt;// aRGB&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; strokeThickness : 2&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; gTheMap.entities.push(gLine);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; gLine.setLocations(Endpoints);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;I couldn't find a function to calculate the distance between points in the Bing API, so I wrote my own (CalculateDistance). If you want to see the source for it, you can pick it off the web page.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; I was able to verify the accuracy of the measurements by using the golf hole next to the field. I put a pin/marker on the center of the green, and then by zooming in, I was able to see the 150 markers on the fairway and put the other pin/marker on one of them.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Final Notes: &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;All in all, the APIs are very similar. Both made it easy to accomplish a lot with a minimum amount of code.&lt;/p&gt;
&lt;p&gt;In one aerial view, there are leaves on the tree, in the other, the trees are bare. I don't know which service has the newer data.&lt;/p&gt;
&lt;p&gt;Here are links to working pages:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stevewellens.com/BingMapsDemo.html" mce_href="http://stevewellens.com/BingMapsDemo.html"&gt;Bing Map Demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stevewellens.com/GoogleMapsDemo.html" mce_href="http://stevewellens.com/GoogleMapsDemo.html"&gt;Google Map Demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I hope someone finds this useful.&lt;/p&gt;
&lt;p&gt;Steve Wellens&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="display: none;" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;</description><pubDate>Mon, 10 Dec 2012 01:00:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/google-and-bing-map-apis-compared</guid><category>.NET</category><category>General Software Development</category><category>Web Services</category></item><item><title>Favorite Programmer Quotes…</title><link>https://weblogs.asp.net:443/stevewellens/favorite-programmer-quotes</link><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"A computer once beat me at chess, but it was no match for me at kick boxing." — Emo Philips
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"There are only 10 types of people in the world, those who understand binary and those who don't. " – Unknown.
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"Premature optimization is the root of all evil."  — Donald Knuth
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"I should have become a doctor; then I could bury my mistakes." — Unknown
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"Code softly and carry a large backup thumb drive." — Me
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." — Martin Golding
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"DDE…the protocol from hell"— Charles Petzold
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"Just because a thing is new don't mean that it's better" — Will Rogers
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"The mark of a mature programmer is willingness to throw out code you spent time on when you realize it's pointless." — Bram Cohen
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"A good programmer is someone who looks both ways before crossing a one-way street."  — Doug Linder
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;"The early bird may get the worm but it's the second mouse that gets the cheese."  — Unknown 
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope someone finds this amusing.
&lt;/p&gt;
&lt;p&gt;Steve Wellens
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" mce_href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Wed, 28 Nov 2012 18:24:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/favorite-programmer-quotes</guid><category>General Software Development</category></item><item><title>The Low Down Dirty Azure Blues</title><link>https://weblogs.asp.net:443/stevewellens/the-low-down-dirty-azure-blues</link><description>&lt;p&gt;Remember the &lt;a href="http://setiathome.berkeley.edu/index.php" mce_href="http://setiathome.berkeley.edu/index.php"&gt;SETI &lt;/a&gt;screen savers that used to be on everyone's computer?  As far I as know, it was the first bona-fide use of "Cloud" computing…albeit an ad hoc cloud.  I still think it was a brilliant leveraging of computing power.
&lt;/p&gt;

&lt;p&gt;My interest in clouds was re-piqued when I went to a technical seminar at the local .Net User Group.  The speaker was &lt;a href="http://www.benkotips.com/default.aspx" mce_href="http://www.benkotips.com/default.aspx"&gt;Mike Benkovitch&lt;/a&gt; and he expounded magnificently on the virtues of the Azure platform.  Mike always does a good job.  One killer reason he gave for cloud computing is instant scalability.  Not applicable for most applications, but it is there if needed.
&lt;/p&gt;

&lt;p&gt;I have a bunch of files stored on Microsoft's SkyDrive platform which is cloud storage.  It is painfully slow.  Accessing a file means going through layers and layers of software, redirections and security.  Am I complaining?  Hell no!  It's free!
&lt;/p&gt;

&lt;p&gt;So my opinions of Cloud Computing are both skeptical and appreciative.
&lt;/p&gt;

&lt;p&gt;What intrigued me at the seminar, in addition to its other features, is that Azure can serve as a web hosting platform.  I have a client with an Asp.Net web site I developed who is not happy with the performance of their current hosting service.  I checked the cost of Azure and since the site has low bandwidth/space requirements the cost would be competitive with the existing host provider:  &lt;a href="https://www.windowsazure.com/en-us/pricing/calculator/" mce_href="https://www.windowsazure.com/en-us/pricing/calculator/"&gt;Azure Pricing Calculator&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;And, Azure has a three month free trial.   Perfect!  I could try moving the website and see how it works for free.   
&lt;/p&gt;

&lt;p&gt;I went through the signup process.  Everything was proceeding fine until I went to the MS SQL database management screen.  A popup window informed me that I needed to install Silverlight on my machine.
&lt;/p&gt;

&lt;p&gt;Silverlight?  No thanks. Buh-Bye.
&lt;/p&gt;

&lt;p&gt;I half-heartedly found the Azure support button and logged a ticket telling them I didn't want Silverlight on my machine.  Within 4 to 6 hours (and a myriad (5) of automated support emails) they sent me a link to a database management page that did not require Silverlight.
&lt;/p&gt;

&lt;p&gt;Thanks!
&lt;/p&gt;

&lt;p&gt;I was able to create a database immediately.  One really nice feature was that after creating the database, I was given a list of connection strings.  I went to the current host provider, made a backup of the database and saved it to my machine.  I attached to the remote database using SQL Server Studio 2012 and looked for the Restore menu item.  It was missing.  So I tried using the SQL command:
&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family:Consolas"&gt;&lt;span style="color:blue"&gt;RESTORE&lt;/span&gt;
			&lt;span style="color:blue"&gt;DATABASE&lt;/span&gt;
			&lt;span style="color:teal"&gt;MyDatabase&lt;/span&gt;
		&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family:Consolas"&gt;
			&lt;span style="color:blue"&gt;FROM&lt;/span&gt;
			&lt;span style="color:blue"&gt;DISK&lt;/span&gt;
			&lt;span style="color:gray"&gt;=&lt;/span&gt;&lt;span style="color:red"&gt;'C:\temp\MyBackup.bak'
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family:Courier New"&gt;Msg 40510, Level 16, State 1, Line 1
&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family:Courier New"&gt;Statement 'RESTORE DATABASE' is not supported in this version of SQL Server.
&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Are you kidding me?  Why on earth…?  This can't be happening!
&lt;/p&gt;

&lt;p&gt;I opened both the source database and destination database in SQL Management Studio.  I right clicked the source database, selected "Tasks" and noticed a menu selection called "Deploy Database to SQL Azure"
&lt;/p&gt;

&lt;p&gt;Are you kidding me?  Could it be?  Oh yes, it be!
&lt;/p&gt;

&lt;p&gt;There was a small problem because the database already existed on the Azure machine, I deployed to a new name, deleted the existing database and renamed the deployed database to what I needed. &lt;b&gt; It was ridiculously easy.
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Being able to attach SQL Management Studio to remote databases is an awesome but scary feature.  You can limit the IP addresses that can access the database which enhances security but when you give people, any people, &lt;b&gt;me included&lt;/b&gt;, that much power, one errant mouse click could bring a live system down.  My Advice: &lt;i&gt;Code softly and carry a large backup thumb-drive.&lt;/i&gt;
	&lt;/p&gt;

&lt;p&gt;Then I created a web site, the URL it returned look something like this: &lt;b&gt; http://MyWebSite.azurewebsites.net/
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Azure supports FTP, but I couldn't figure out the settings until I downloaded the publishing profile.  It was an XML file that contained the needed information.
&lt;/p&gt;

&lt;p&gt;I still couldn't connect with my FTP client (&lt;a href="http://filezilla-project.org/" mce_href="http://filezilla-project.org/"&gt;FileZilla&lt;/a&gt;).  After about an hour of messing around, &lt;b&gt;I deleted the port number from the FileZilla setup page&lt;/b&gt;….and voila, I was in like Flynn.
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/FileZilla.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/FileZilla.png"&gt;&lt;/p&gt;

&lt;p&gt;There are other options of deploying directly from Visual Studio, TFS, etc. but I do not like integrated tools that do things without my asking:  It's usually hard to figure out what they did and how to undo it.
&lt;/p&gt;

&lt;p&gt;I uploaded the aspx , cs , webconfig, etc. files.
&lt;/p&gt;

&lt;p&gt;Bu it didn't run.  The site I ported was in .NET 3.5.  The Azure website configuration page gave me a choice between .NET 2.0 and 4.0.  So, I switched to Visual Studio 2010, chose .NET 4.0 and upgraded the site.  Of course I have the original version completely backed up and stored in a granite cave beneath the Nevada desert.  And I have a backup CD under my pillow.
&lt;/p&gt;

&lt;p&gt;The site uses ReportViewer to generate PDF documents.  Of course it was the wrong version.  I removed the old references to version 9 and added new references to version 10 (*see note below).  Since the DLLs were not on the Azure Server, I uploaded them to the bin directory, crossed my fingers, burned some incense and gave it a try.  After some fiddling around it ran.  I don't know if I did anything particular to make it work or it just needed time to sort things out.
&lt;/p&gt;

&lt;p&gt;However, one critical feature didn't work: ReportViewer could not programmatically generate PDF documents.   I was getting this exception:  &lt;b&gt;"An error occurred during local report processing.  Parameter is not valid."
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Rats.
&lt;/p&gt;

&lt;p&gt;I did some searching and found other people were having the same problem, so I added a post saying I was having the same problem:  &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/windowsazurewebsitespreview/thread/b4a6eb43-0013-435f-9d11-00ee26a8d017" mce_href="http://social.msdn.microsoft.com/Forums/en-US/windowsazurewebsitespreview/thread/b4a6eb43-0013-435f-9d11-00ee26a8d017"&gt;http://social.msdn.microsoft.com/Forums/en-US/windowsazurewebsitespreview/thread/b4a6eb43-0013-435f-9d11-00ee26a8d017&lt;/a&gt;
	&lt;/p&gt;

&lt;p&gt;Currently they are looking into this problem and I am waiting for the results.  Hence I had the time to write this BLOG entry.  How lucky you are. 
&lt;/p&gt;

&lt;p&gt;This was the last message I got from the Microsoft person:
&lt;/p&gt;

&lt;p style="margin-left: 36pt"&gt;Hi Steve,
&lt;/p&gt;

&lt;p style="margin-left: 36pt"&gt;Windows Azure Web Sites is a multi-tenant environment. For security issue, we limited some API calls. Unfortunately, some GDI APIS required by the PDF converting function are in this list.
&lt;/p&gt;

&lt;p style="margin-left: 36pt"&gt;We have noticed this issue, and still investigation the best way to go. At this moment, there is no news to share. Sorry about this.
&lt;/p&gt;

&lt;p style="margin-left: 36pt"&gt;Will keep you posted.&lt;/p&gt;

&lt;p&gt;If I had to guess, I would say they are concerned with people uploading images and doing intensive graphics programming which would hog CPU time.&amp;nbsp; But that is just a guess.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="text-decoration:underline"&gt;&lt;b&gt;Another problem.
&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;While trying to resolve the ReportViewer problem, I tried to write a file to the PDF directory to see if there was a permissions problem with some test code:
&lt;/p&gt;

&lt;p style="background: white"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;&lt;span style="color:black"&gt; MyPath = MapPath(&lt;/span&gt;&lt;span style="color:#a31515"&gt;@"~\PDFs\Test.txt"&lt;/span&gt;&lt;span style="color:black"&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p style="background: white"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:black"&gt;File.WriteAllText(MyPath, &lt;/span&gt;&lt;span style="color:#a31515"&gt;"Hello Azure"&lt;/span&gt;&lt;span style="color:black"&gt;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I got this message:  &lt;b&gt;Access to the path &amp;lt;my path&amp;gt; is denied. 
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;After some research, I understood that since Azure is a cloud based platform, it can't allow web applications to save files to local directories.  The application could be moved or replicated as scaling occurs and trying to manage local files would be problematic to say the least.
&lt;/p&gt;

&lt;p&gt;There are other options:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Use the Azure APIs to get a path.  That way the location of the storage is separated from the application.  However, the web site is then tied Azure and can't be moved to another hosting platform.
&lt;/li&gt;

&lt;li&gt;Use the ApplicationData folder (not recommended).
&lt;/li&gt;

&lt;li&gt; Write to BLOB storage.&lt;/li&gt;
&lt;li&gt;Or, I could try and stream the PDF output directly to the email and not save a file.&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;I'm not going to work on a final solution until the ReportViewer is fixed.  I am just sharing some of the things you need to be aware of if you decide to use Azure.  I got this information from &lt;a href="http://blog.codingoutloud.com/2011/06/12/azure-faq-can-i-write-to-the-file-system-on-windows-azure/" mce_href="http://blog.codingoutloud.com/2011/06/12/azure-faq-can-i-write-to-the-file-system-on-windows-azure/"&gt;here&lt;/a&gt;. (Note the author of the BLOG added a comment saying he has updated his entry).&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="text-decoration:underline"&gt;&lt;b&gt;Is my memory faulty?
&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;While getting this BLOG ready, I tried to write the test file again.  And it worked.  My memory is incorrect, or much more likely, something changed on the server…perhaps while they are trying to get ReportViewer to work.  (Anyway, that's my story and I'm sticking to it).
&lt;/p&gt;

&lt;p&gt;*Note:  Since Visual Studio 2010 Express doesn't include a Report Editor, I downloaded and installed &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&amp;amp;id=24085" mce_href="http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&amp;amp;id=24085"&gt;SQL Server Report Builder 2.0&lt;/a&gt;.  It is a standalone Report Editor to replace the one not in Visual Studio 2010 Express.
&lt;/p&gt;

&lt;p&gt;I hope someone finds this useful.
&lt;/p&gt;

&lt;p&gt;Steve Wellens
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
</description><pubDate>Sat, 13 Oct 2012 01:30:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/the-low-down-dirty-azure-blues</guid><category>ASP.NET</category><category>Azure</category><category>ReportViewer</category></item><item><title>Elegance, thy Name is jQuery</title><link>https://weblogs.asp.net:443/stevewellens/elegance-thy-name-is-jquery</link><description>&lt;p&gt;So, I'm browsing though some questions over on the &lt;a href="http://stackoverflow.com/" mce_href="http://stackoverflow.com/"&gt;Stack Overflow&lt;/a&gt; website and I found a good jQuery question just a few minutes old.  &lt;a href="http://stackoverflow.com/questions/9984869/using-jquery-to-generate-wrapping-divs-once-page-is-loaded" mce_href="http://stackoverflow.com/questions/9984869/using-jquery-to-generate-wrapping-divs-once-page-is-loaded"&gt;Here&lt;/a&gt; is a link to it.  It was a &lt;b&gt;tough&lt;/b&gt; question; I knew that by answering it, I could learn new stuff and reinforce what I already knew:  &lt;i&gt;Reading is good, doing is better&lt;/i&gt;.  Maybe I could help someone in the process too.
&lt;/p&gt;

&lt;p&gt;I cut and pasted the HTML from the question into my Visual Studio IDE and went back to Stack Overflow to reread the question.  Dang, someone had already answered it!  And it was a great answer.   I never even had a chance to start analyzing the issue.  
&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Now I know what a one-legged man feels like in an ass-kicking contest.
&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Nevertheless, since the question and answer were so interesting, I decided to dissect them and learn as much as possible.
&lt;/p&gt;

&lt;p&gt;The HTML consisted of some &lt;b&gt;divs &lt;/b&gt;separated by &lt;b&gt;h3 &lt;/b&gt;headings.&amp;nbsp; Note the elements are laid out sequentially with no programmatic grouping: &lt;br&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="heading"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Heading 1&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;More content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Even more content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="heading"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Heading 2&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;some content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;some more content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="heading"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Heading 3&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;other content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;form&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;The requirement was to wrap a div around each &lt;b&gt;h3&lt;/b&gt; heading and the subsequent &lt;b&gt;divs&lt;/b&gt; grouping them into sections.  Why?  I don't know, I suppose if you screen-scrapped some HTML from another site, you might want to reformat it before displaying it on your own.  Anyways…
&lt;/div&gt;

&lt;p&gt;Here is the marvelously, succinct posted answer:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;$(&lt;span style="color: #006080;"&gt;'.heading'&lt;/span&gt;).each(&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;(){&lt;br&gt;    $(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;).nextUntil(&lt;span style="color: #006080;"&gt;'.heading'&lt;/span&gt;).andSelf().wrapAll(&lt;span style="color: #006080;"&gt;'&amp;lt;div class="section"&amp;gt;'&lt;/span&gt;);&lt;br&gt;}); &lt;/pre&gt;&lt;br&gt;&lt;/div&gt;

&lt;p&gt;I was familiar with all the parts except for &lt;b&gt;nextUntil&lt;/b&gt; and &lt;b&gt;andSelf&lt;/b&gt;.  But, I'll analyze the whole answer for completeness.  I'll do this by rewriting the posted answer in a different style and adding a boat-load of comments:
&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; Test()&lt;br&gt;{&lt;br&gt;    &lt;span style="color: #008000;"&gt;// $Sections is a jQuery object and it will contain three elements&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; $Sections = $(&lt;span style="color: #006080;"&gt;'.heading'&lt;/span&gt;);&lt;br&gt;&lt;br&gt;    &lt;span style="color: #008000;"&gt;// use each to iterate over each of the three elements&lt;/span&gt;&lt;br&gt;    $Sections.each(&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; ()&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: #008000;"&gt;// $this is a jquery object containing the current element&lt;/span&gt;&lt;br&gt;        &lt;span style="color: #008000;"&gt;// being iterated&lt;/span&gt;&lt;br&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; $&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; = $(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;);&lt;br&gt;       &lt;br&gt;        &lt;span style="color: #008000;"&gt;// nextUntil gets the following sibling elements until it reaches&lt;/span&gt;&lt;br&gt;        &lt;span style="color: #008000;"&gt;// an element with the CSS class 'heading'&lt;/span&gt;&lt;br&gt;        &lt;span style="color: #008000;"&gt;// andSelf adds in the source element (this) to the collection&lt;/span&gt;&lt;br&gt;        $&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; = $&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.nextUntil(&lt;span style="color: #006080;"&gt;'.heading'&lt;/span&gt;).andSelf();&lt;br&gt;       &lt;br&gt;        &lt;span style="color: #008000;"&gt;// wrap the elements with a div&lt;/span&gt;&lt;br&gt;        $&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.wrapAll(&lt;span style="color: #006080;"&gt;'&amp;lt;div class="section" &amp;gt;'&lt;/span&gt;);&lt;br&gt;    });&lt;br&gt;} &lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;The code here doesn't look nearly as concise and elegant as the original answer.  However, unless you and your staff are jQuery masters, during development it really helps to work through algorithms step by step.  You can step through this code in the debugger and examine the jQuery objects to make sure one step is working before proceeding on to the next.  It's much easier to debug and troubleshoot when each logical coding step is a separate line of code.
&lt;/div&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You may think the original code runs much faster than this version.  However, the time difference is trivial: Not enough to worry about:  Less than 1 millisecond (tested in IE and FF).
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note: &lt;/b&gt; You may want to jam everything into one line because it results in less traffic being sent to the client.  That is true.  However, most Internet servers now compress HTML and JavaScript by stripping out comments and white space (go to Bing or Google and view the source).  This feature should be enabled on your server:  Let the server compress your code, you don't need to do it.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Free Career Advice:&lt;/b&gt;  Creating maintainable code is Job One—Maximum Priority—The Prime Directive.  If you find yourself suddenly transferred to customer support, it may be that the code you are writing is not as readable as it could be and not as readable as it should be.   Moving on…
&lt;/p&gt;

&lt;p&gt;I created a CSS class to enhance the results: &lt;br&gt;&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #cc6633;"&gt;.section&lt;/span&gt;&lt;br&gt;{&lt;br&gt;    &lt;span style="color: #0000ff;"&gt;background-color&lt;/span&gt;: &lt;span style="color: #006080;"&gt;yellow;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff;"&gt;border&lt;/span&gt;: &lt;span style="color: #006080;"&gt;2px solid black;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff;"&gt;margin&lt;/span&gt;: &lt;span style="color: #006080;"&gt;5px;&lt;/span&gt;&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;Here is the rendered output before:
&lt;/div&gt;


&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Before1.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Before1.png" height="265" width="166"&gt;&lt;/p&gt;

&lt;p&gt;…and after the jQuery code runs.
&lt;/p&gt;

&lt;p&gt;
&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/After1.png" &lt;p=""&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Pretty Cool!  But, while playing with this code, the logic of &lt;b&gt;nextUntil&lt;/b&gt; began to bother me:  What happens in the last section?  What stops elements from being collected since there are no more elements with the .heading class?  The answer is nothing.&amp;nbsp; In this case it stopped collecting elements because it was at the end of the page.&amp;nbsp; But what if there were additional HTML elements?&lt;br&gt;&lt;/p&gt;

&lt;p&gt;I added an anchor tag and another div to the HTML:
&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="heading"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Heading 1&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;More content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Even more content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="heading"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Heading 2&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;some content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;some more content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="heading"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Heading 3&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;h3&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;other content&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;this is a link&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;unrelated div&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;form&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;br&gt;&lt;/div&gt;

&lt;p&gt;The code as-is will include both the anchor and the unrelated div.  This isn't what we want.
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/After2.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/After2.png"&gt;&lt;/p&gt;

&lt;p&gt;My first attempt to correct this used the filter parameter of the &lt;b&gt;nextUntil&lt;/b&gt; function:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;nextUntil(&lt;span style="color: #006080;"&gt;'.heading'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'div'&lt;/span&gt;) &lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;This will only collect div elements.  But it merely skipped the anchor tag and&lt;i&gt; it still collected the unrelated div:
&lt;/i&gt;&lt;/div&gt;


&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/After3.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/After3.png"&gt;&lt;/p&gt;

&lt;p&gt;The problem is we need a way to tell the &lt;b&gt;nextUntil&lt;/b&gt; function when to stop.  CSS selectors to the rescue!
&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;nextUntil(&lt;span style="color: #006080;"&gt;'.heading, a'&lt;/span&gt;) &lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;This tells &lt;b&gt;nextUntil&lt;/b&gt; to stop collecting elements when it gets to an element with a .heading class &lt;b&gt;OR&lt;/b&gt; when it gets to an anchor tag.  In this case it solved the problem.  FYI:  The comma operator in a CSS selector allows multiple criteria.  
&lt;/div&gt;


&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/After4.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/After4.png"&gt;&lt;/p&gt;

&lt;p&gt;Bingo!  
&lt;/p&gt;

&lt;p&gt;One final note, we could have broken the code down even more:
&lt;/p&gt;

&lt;p&gt;We could have replaced the &lt;b&gt;andSelf&lt;/b&gt; function here:
&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;$&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; = $&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.nextUntil(&lt;span style="color: #006080;"&gt;'.heading, a'&lt;/span&gt;).andSelf();&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #008000;"&gt;// get all the following siblings and then add the current item&lt;/span&gt;&lt;br&gt;$&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; = $&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.nextUntil(&lt;span style="color: #006080;"&gt;'.heading, a'&lt;/span&gt;);&lt;br&gt;$&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.add(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;); &lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;But in this case, the &lt;b&gt;andSelf&lt;/b&gt; function reads real nice. In my opinion.&lt;br&gt;&lt;/div&gt;


&lt;p&gt;Here's a &lt;a href="http://jsfiddle.net/Steve_Wellens/Drd5b/" mce_href="http://jsfiddle.net/Steve_Wellens/Drd5b/"&gt;link&lt;/a&gt; to a jsFiddle if you want to play with it.
&lt;/p&gt;

&lt;p&gt;I hope someone finds this useful
&lt;/p&gt;

&lt;p&gt;Steve Wellens
&lt;/p&gt;


&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="display: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Sun, 08 Apr 2012 13:15:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/elegance-thy-name-is-jquery</guid><category>General Software Development</category><category>JQuery</category></item><item><title>Cool CSS 4 Feature: pointer-events</title><link>https://weblogs.asp.net:443/stevewellens/cool-css-4-feature-pointer-events</link><description>&lt;p&gt;CSS 4? Really? CSS 3 isn't fully released yet! What on earth is going on here?&lt;/p&gt;
&lt;p&gt;It all started when I was fooling around with &lt;a href="http://www.gimp.org/" mce_href="http://www.gimp.org/"&gt;GIMP&lt;/a&gt;, the extremely powerful free graphics editor. I took a public domain image, re-sized it, gave it a transparent background and then added a perspective shadow.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It is beautiful.&lt;/p&gt;
&lt;p&gt;I wanted to see the image in "action" so I put it on a web page. But because of the way HTML elements are rendered, there was nothing behind my gorgeous image to demonstrate the transparency. I could have used a background color but instead I gave the image an absolute position and positioned it over a button:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/CherryScreenShot2.png" height="176" width="196" /&gt;&lt;/p&gt;
&lt;p&gt;It looks 3-dimensional but you can't click on the button with the mouse. The transparent part of the image is like having a sheet of glass over the button. You can tab to it and use the space bar but it's really not useable as it is.&lt;/p&gt;
&lt;p&gt;I recalled reading about the CSS &lt;b&gt;pointer-events&lt;/b&gt; property. I assigned it to the image and voila! It worked&amp;hellip;at least on FireFox. IE hasn't implemented this feature yet.&lt;/p&gt;
&lt;p&gt;Here is a jsFiddle that shows it in action.&amp;nbsp; If your browser supports&lt;b&gt; pointer-events&lt;/b&gt;, you will be able to click the button:&lt;/p&gt;
&lt;p&gt;&lt;iframe src="http://jsfiddle.net/Steve_Wellens/6GbwK/37/embedded/" allowfullscreen="allowfullscreen" frameborder="0" height="300" width="100%"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Here is a direct link to the jsFiddle (just in case iframes aren't allowed here):&amp;nbsp;&lt;a href="http://jsfiddle.net/Steve_Wellens/6GbwK/37/" target="_blank"&gt;http://jsfiddle.net/Steve_Wellens/6GbwK/37/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When I did a bit of research on the &lt;b&gt;pointer-events&lt;/b&gt; property, I found it had been pushed into CSS4 because it had "issues". Here is a link that documents re-assigning this feature from CSS3 to CSS4: &lt;a href="http://wiki.csswg.org/spec/css4-ui#pointer-events" mce_href="http://wiki.csswg.org/spec/css4-ui#pointer-events"&gt; http://wiki.csswg.org/spec/css4-ui#pointer-events&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here's a table showing what browsers/versions currently support it: &lt;a href="http://caniuse.com/pointer-events" mce_href="http://caniuse.com/pointer-events"&gt;http://caniuse.com/pointer-events&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The big question is how do you rationalize this to your boss? Here is a list of business justifications:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I hope someone finds this useful.&lt;/p&gt;
&lt;p&gt;Steve Wellens&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="display: none;" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Fri, 24 Feb 2012 17:40:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/cool-css-4-feature-pointer-events</guid><category>CSS</category><category>General Software Development</category><category>JQuery</category></item><item><title>Log4net: Log to a JavaScript Console</title><link>https://weblogs.asp.net:443/stevewellens/log4net-log-to-a-javascript-console</link><description>&lt;p&gt;While lurking and skulking in the shadows of various technical .Net sites, I've noticed many developers discussing &lt;a href="http://logging.apache.org/log4net/" mce_href="http://logging.apache.org/log4net/"&gt;log4net &lt;/a&gt;in their blogs and posts; log4net is an extremely popular tool for logging .Net Applications. So, I decided to try it out. After the initial complexities of getting it up and running, I was suitably impressed. Could it be…logging is fun? Well, I don't know if I'd go &lt;b&gt;that &lt;/b&gt;far…at least I'd never admit it. &lt;/p&gt;

&lt;p&gt;One of the great features of log4net is how easy it is to route the logs to multiple outputs. Here is an &lt;b&gt;&lt;i&gt;incomplete&lt;/i&gt;&lt;/b&gt; list of outputs…or '&lt;i&gt;Appenders&lt;/i&gt;' in the log4net vernacular: &lt;/p&gt;

&lt;div style="MARGIN: 0.5in"&gt;
&lt;table style="border-collapse: collapse;" border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AdoNetAppender&lt;/td&gt;

&lt;td&gt;Logs to databases&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;ConsoleAppender&lt;/td&gt;

&lt;td&gt;Logs to a console window&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;EventLogAppender&lt;/td&gt;

&lt;td&gt;Logs to Windows event log&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;FileAppender&lt;/td&gt;

&lt;td&gt;Logs to a file&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;RollingFileAppender&lt;/td&gt;

&lt;td&gt;Logs to multiple files&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;SmtpAppender&lt;/td&gt;

&lt;td&gt;Logs to an email address&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;TraceAppender&lt;/td&gt;

&lt;td&gt;Logs to the .Net trace system&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;AspNetTraceAppender&lt;/td&gt;

&lt;td&gt;Logs to the Asp.Net page trace&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;MemoryAppender&lt;/td&gt;

&lt;td&gt;Logs to a memory buffer&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Etc., etc., etc.&lt;/td&gt;

&lt;td&gt;&lt;br&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Wow. &lt;/p&gt;

&lt;p&gt;I've been doing a lot of work with jQuery/JavaScript and it dawned on me that seeing server side logging strings in a JavaScript Console could be useful. &lt;/p&gt;

&lt;p&gt;So I wrote a log4net JavaScript Console Appender. Strings logged at the server will show up in the browser's console window. &lt;b&gt;Note&lt;/b&gt;: For IE, you need to have the "Developer Tools" window active. &lt;/p&gt;

&lt;p&gt;I'm not going to describe how to setup log4net in an Asp.Net web site; there are many step-by-step tutorials around. But I'll give you some hints: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each step must be followed or it will not work (duh). &lt;/li&gt;

&lt;li&gt;Putting the log4net settings in a separate configuration file is more complicated than having the settings in web.config: Start with the settings in web.config. &lt;/li&gt;

&lt;li&gt;The name in this line of code:&lt;b&gt; LogManager.GetLogger("MyLogger"); &lt;/b&gt;&lt;br&gt;...refers to this section in the configuration file: &lt;b&gt;&amp;lt;logger name="MyLogger"&amp;gt; &lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built the Appender and a test Asp.Net site in .Net Framework 4.0.&amp;nbsp; Here's the &lt;b&gt;jsConsoleAppender.cs&lt;/b&gt; file: &lt;/p&gt;

&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; log4net;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; log4net.Core;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; log4net.Appender;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; log4net.Layout;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Web;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Web.UI;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; log4net.Appender&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// log4net JSConsoleAppender&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Writes log strings to client's javascript console if available&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;JSConsoleAppender&lt;/span&gt; : AppenderSkeleton&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// each JavaScript emitted requires a unique id, this counter provides it&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; m_IDCounter = 0;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// what to do if no HttpContext is found&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; m_ExceptionOnNoHttpContext = &lt;span style="color: blue;"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; ExceptionOnNoHttpContext&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; m_ExceptionOnNoHttpContext; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt; { m_ExceptionOnNoHttpContext = &lt;span style="color: blue;"&gt;value&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// The meat of the Appender&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Append(LoggingEvent loggingEvent)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// optional test for HttpContext, set in config file.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// default is true&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (ExceptionOnNoHttpContext == &lt;span style="color: blue;"&gt;true&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;HttpContext&lt;/span&gt;.Current == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ErrorHandler.Error(&lt;span style="color: #a31515;"&gt;"JSConsoleAppender: No HttpContext to write javascript to."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// newlines mess up JavaScript...check for them in the pattern&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PatternLayout Layout = &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Layout &lt;span style="color: blue;"&gt;as&lt;/span&gt; PatternLayout;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (Layout.ConversionPattern.Contains(&lt;span style="color: #a31515;"&gt;"%newline"&lt;/span&gt;))&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ErrorHandler.Error(&lt;span style="color: #a31515;"&gt;"JSConsoleAppender: Pattern may not contain %newline."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// format the Log string&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt; LogStr = &lt;span style="color: blue;"&gt;this&lt;/span&gt;.RenderLoggingEvent(loggingEvent);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// single quotes in the log message will mess up our JavaScript&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; LogStr = LogStr.Replace(&lt;span style="color: #a31515;"&gt;"'"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"\\'"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Check if console exists before writing to it&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt; OutputScript = &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515;"&gt;"if (window.console) console.log('{0}');"&lt;/span&gt;, LogStr);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// This sends the script to the bottom of the page&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Page&lt;/span&gt; page = &lt;span style="color: #2b91af;"&gt;HttpContext&lt;/span&gt;.Current.CurrentHandler &lt;span style="color: blue;"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Page&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; page.ClientScript.RegisterStartupScript(page.GetType(), m_IDCounter++.ToString(), OutputScript, &lt;span style="color: blue;"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// There is no default layout&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; RequiresLayout&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;true&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

From the Asp.Net test application, here's the &lt;b&gt;web.config&lt;/b&gt; file. In the pattern for the JSConsoleAppender, I added the word SERVER: to differentiate the lines from client logging. Note there are two other Appenders in the log…just for fun! &lt;br&gt;&lt;/p&gt;

&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515;"&gt;xml&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;version&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;1.0&lt;/span&gt;"&lt;span style="color: blue;"&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green;"&gt;BEGIN log4net configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configSections&lt;/span&gt;&lt;span style="color: blue;"&gt; &amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;section&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net&lt;/span&gt;"&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net.Config.Log4NetConfigurationSectionHandler, log4net&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configSections&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;log4net&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;LogFileAppender&lt;/span&gt;"&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net.Appender.FileAppender&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;param&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;File&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;C:\Log4Net.log&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;layout&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net.Layout.PatternLayout&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;param&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;ConversionPattern&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;%d %-5p %c %m%n&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;layout&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;TraceAppender&lt;/span&gt;"&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net.Appender.TraceAppender&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;layout&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net.Layout.PatternLayout&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;conversionPattern&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;%date&amp;nbsp; %-5level [%property{NDC}] - %message%newline&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;layout&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;JSConsoleAppender&lt;/span&gt;"&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net.Appender.JSConsoleAppender&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;layout&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;log4net.Layout.PatternLayout&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green;"&gt;Note JSConsoleAppender cannot have %newline&lt;/span&gt;&lt;span style="color: blue;"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;conversionPattern&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;SERVER: %date %-5level %logger:&amp;nbsp; %message&amp;nbsp; SRC: %location&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;layout&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;logger&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;MyLogger&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;level&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;ALL&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender-ref&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;ref&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;LogFileAppender&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender-ref&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;ref&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;TraceAppender&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;appender-ref&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;ref&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;JSConsoleAppender&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;logger&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;log4net&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green;"&gt;END log4net configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.web&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;compilation&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;debug&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;true&lt;/span&gt;"&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red;"&gt;targetFramework&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;4.0&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.web&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Here's the &lt;b&gt;default.aspx&lt;/b&gt; file from the test program, I added a bit of JavaScript and jQuery: &lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="COLOR: blue"&gt;@&lt;/span&gt; &lt;span style="COLOR: #a31515"&gt;Page&lt;/span&gt; &lt;span style="COLOR: red"&gt;Language&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="C#"&lt;/span&gt; &lt;span style="COLOR: red"&gt;AutoEventWireup&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="true"&lt;/span&gt; &lt;span style="COLOR: red"&gt;CodeFile&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Default.aspx.cs"&lt;/span&gt; &lt;span style="COLOR: red"&gt;Inherits&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="_Default"&lt;/span&gt; &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;DOCTYPE&lt;/span&gt; &lt;span style="COLOR: red"&gt;html&lt;/span&gt; &lt;span style="COLOR: red"&gt;PUBLIC&lt;/span&gt; &lt;span style="COLOR: blue"&gt;"-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;/span&gt; &lt;span style="COLOR: blue"&gt;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;html&lt;/span&gt; &lt;span style="COLOR: red"&gt;xmlns&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="http://www.w3.org/1999/xhtml"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;head&lt;/span&gt; &lt;span style="COLOR: red"&gt;id&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Head1"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;title&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;Log4Net Test&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;title&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt; &lt;span style="COLOR: red"&gt;src&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Scripts/jquery-1.7.js"&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="text/javascript"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $(document).ready(DocReady);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; DocReady()&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (window.console) &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; console.log(&lt;span style="COLOR: #a31515"&gt;"CLIENT: Doc Ready!"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;head&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;body&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;form&lt;/span&gt; &lt;span style="COLOR: red"&gt;id&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="form1"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;div&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;h5&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;Log4Net Test&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;h5&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Button&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ButtonLog"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&lt;/span&gt; &lt;span style="COLOR: red"&gt;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Do Some Logging!"&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;onclick&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ButtonLog_Click"&lt;/span&gt; &lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;div&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;form&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;body&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;html&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;
&lt;p&gt;Here's the &lt;span style="font-weight: bold;"&gt;default.cs&lt;/span&gt; file from the test program with some logging strings: &lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Web;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Web.UI;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Web.UI.WebControls;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; log4net;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;partial&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;_Default&lt;/span&gt; : System.Web.UI.&lt;span style="COLOR: #2b91af"&gt;Page&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;{&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; ILog log = LogManager.GetLogger(&lt;span style="COLOR: #a31515"&gt;"MyLogger"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Page_Load(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; sender, &lt;span style="COLOR: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; log.Info(&lt;span style="COLOR: #a31515"&gt;"Page_Load!"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; ButtonLog_Click(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; sender, &lt;span style="COLOR: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; log.Info(&lt;span style="COLOR: #a31515"&gt;"Soft kitty, warm kitty"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; log.Warn(&lt;span style="COLOR: #a31515"&gt;"Little ball of fur"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; log.Error(&lt;span style="COLOR: #a31515"&gt;"Happy kitty, sleepy kitty"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; log.Fatal(&lt;span style="COLOR: #a31515"&gt;"Purr, purr, purr."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;
&lt;p&gt;And finally, here are the three output logs: &lt;/p&gt;

&lt;p&gt;From the &lt;b&gt;JSConsoleAppender&lt;/b&gt; (IE Developer Tools), it includes a client log call with the server log calls: &lt;/p&gt;

&lt;p mce_keep="true"&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/IE_Log.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/IE_Log.png"&gt;&lt;/p&gt;

&lt;p&gt;From the &lt;b&gt;TraceAppender&lt;/b&gt;, the Visual Studio Output window: &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Debug_Log.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Debug_Log.png"&gt;&lt;/p&gt;

&lt;p&gt;From the &lt;b&gt;LogFileAppender&lt;/b&gt; (using Notepad): &lt;/p&gt;

&lt;p mce_keep="true"&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Notepad_Log.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Notepad_Log.png"&gt;&lt;/p&gt;

&lt;p&gt;You can download the solution/projects/code&amp;nbsp; &lt;a href="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Logger.zip" mce_href="https://aspblogs.blob.core.windows.net/media/stevewellens/2012/Logger.zip"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I hope someone finds this useful. &lt;/p&gt;

&lt;p&gt;Steve Wellens &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Mon, 23 Jan 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/log4net-log-to-a-javascript-console</guid><category>ASP.NET</category><category>JavaScript</category><category>log4net</category></item><item><title>Goodby jQuery Templates, Hello JsRender</title><link>https://weblogs.asp.net:443/stevewellens/goodby-jquery-templates-hello-jsrender</link><description>&lt;p&gt;A funny thing happened on my way to the jQuery website, I blinked and a feature was dropped:  jQuery Templates have been discontinued.  The new pretender to the throne is &lt;a href="https://github.com/BorisMoore/jsrender" mce_href="https://github.com/BorisMoore/jsrender"&gt;JsRender&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;jQuery Templates looked pretty useful when they first came out.  Several articles were written about them but I stayed away because being on the bleeding edge of technology is not a productive place to be.  I wanted to wait until it stabilized…in retrospect, it was a serendipitous decision. 
&lt;/p&gt;

&lt;p&gt;This time however, I threw all caution to the wind and took a close look at JSRender.  Why?  Maybe I'm having a midlife crisis; I'll go motorcycle shopping tomorrow.
&lt;/p&gt;

&lt;p&gt;Caveat, here is a message from the site:  &lt;span style="background-color:yellow"&gt;&lt;b&gt;Warning:&lt;/b&gt; JsRender is not yet Beta, and there may be frequent changes to APIs and features in the coming period.&lt;/span&gt;
	&lt;/p&gt;

&lt;p&gt;Fair enough, we've been warned.
&lt;/p&gt;

&lt;p&gt;The first thing we need is some data to render.  Below is some JSON formatted data.  Typically this will come from an asynchronous call to a web service.  For simplicity, I hard coded a variable: &lt;br&gt;&lt;/p&gt;

&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; Golfers = [&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; { ID: &lt;span style="color: #a31515;"&gt;"1"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"Name"&lt;/span&gt;: &lt;span style="color: #a31515;"&gt;"Bobby Jones"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"Birthday"&lt;/span&gt;: &lt;span style="color: #a31515;"&gt;"1902-03-17"&lt;/span&gt; },&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; { ID: &lt;span style="color: #a31515;"&gt;"2"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"Name"&lt;/span&gt;: &lt;span style="color: #a31515;"&gt;"Sam Snead"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"Birthday"&lt;/span&gt;: &lt;span style="color: #a31515;"&gt;"1912-05-27"&lt;/span&gt; },&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; { ID: &lt;span style="color: #a31515;"&gt;"3"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"Name"&lt;/span&gt;: &lt;span style="color: #a31515;"&gt;"Tiger Woods"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"Birthday"&lt;/span&gt;: &lt;span style="color: #a31515;"&gt;"1975-12-30"&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ];&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We also need some templates, I created two.  Note: The script blocks have the &lt;b&gt;id &lt;/b&gt;property set.  They are needed so JsRender can locate them.
&lt;/p&gt;

&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="GolferTemplate1"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/html"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {{=ID}}: &amp;lt;b&amp;gt;{{=Name}}&amp;lt;/b&amp;gt; &amp;lt;i&amp;gt;{{=Birthday}}&amp;lt;/i&amp;gt; &amp;lt;br /&amp;gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="GolferTemplate2"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/html"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;{{=ID}}&amp;lt;/td&amp;gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;{{=Name}}&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&amp;lt;i&amp;gt;{{=Birthday}}&amp;lt;/i&amp;gt; &amp;lt;/td&amp;gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Including the correct JavaScript files is trivial:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;src&lt;/span&gt;&lt;span style="color: blue;"&gt;="Scripts/jquery-1.7.js"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/&lt;/span&gt;&lt;span style="color: blue;"&gt;javascript&lt;/span&gt;&lt;span style="color: blue;"&gt;"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;src&lt;/span&gt;&lt;span style="color: blue;"&gt;="Scripts/jsrender.js"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Of course we need some place to render the output:
&lt;/p&gt;

&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="GolferDiv"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;br&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;table&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="GolferTable"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;table&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The code is also trivial:
&lt;/p&gt;

&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Test()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: #a31515;"&gt;"#GolferDiv"&lt;/span&gt;).html($(&lt;span style="color: #a31515;"&gt;"#GolferTemplate1"&lt;/span&gt;).render(Golfers));&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: #a31515;"&gt;"#GolferTable"&lt;/span&gt;).html($(&lt;span style="color: #a31515;"&gt;"#GolferTemplate2"&lt;/span&gt;).render(Golfers));&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// you can inspect the rendered html if there are poblems.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// var html = $("#GolferTemplate2").render(Golfers);&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And here's what it looks like with some random CSS formatting that I had laying around.
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/GolfersJsRender.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/GolfersJsRender.png"&gt;&lt;/p&gt;



&lt;p&gt;&amp;nbsp;Not bad, I hope JsRender lasts longer than jQuery Templates.
&lt;/p&gt;

&lt;p&gt;One final warning, a lot of jQuery code is ugly, butt-ugly.  If you do look inside the jQuery files, you may want to cover your keyboard with some plastic in case you get vertigo and blow chunks.&lt;/p&gt;&lt;p&gt;[Edit]&lt;/p&gt;&lt;p&gt;Someone asked me if it was possible to include the templates in an external file.&amp;nbsp; This seemed to work:&amp;nbsp;
&lt;/p&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;&amp;lt;!--#include virtual="Scripts/RenderTemplates.js" --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;I hope someone finds this useful.
&lt;/p&gt;

&lt;p&gt;Steve Wellens
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Thu, 01 Dec 2011 13:30:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/goodby-jquery-templates-hello-jsrender</guid><category>General Software Development</category><category>JQuery</category><category>jsRender</category></item><item><title>HTML 5 and jQuery – A Match Made in Heaven</title><link>https://weblogs.asp.net:443/stevewellens/html-5-and-jquery-a-match-made-in-heaven</link><description>&lt;p&gt;I recently attended an ASP.NET MVC seminar hosted by the Twin Cities .Net User Group. The speaker was K. Scott Allen. Scott is a charismatic, gifted speaker and did a great job. You can always pick up useful items when watching an expert write a program from scratch. &lt;/p&gt;

&lt;p&gt;When I saw what he did with jQuery and HTML 5 Custom Data Attributes, I got so excited I ran around the room squealing like a little girl and wetting my pants until someone threw an unopened can of pop at my head and knocked me out cold. Well, that didn't happen, but what Scott did was interesting enough to compel me to write this post. &lt;/p&gt;

&lt;p&gt;What are HTML 5 &lt;a href="http://dev.w3.org/html5/spec/elements.html" mce_href="http://dev.w3.org/html5/spec/elements.html"&gt;Custom Data Attributes&lt;/a&gt;? &lt;/p&gt;

&lt;p&gt;They are attributes that YOU create for an HTML element that starts with "data-" &lt;/p&gt;

&lt;p&gt;Here's an example: &lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextBox1"&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;CssClass&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextEntry"&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red; BACKGROUND-COLOR: yellow"&gt;data-entryType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Date"&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;

&lt;p&gt;&lt;b&gt;data-entryType="Date"&lt;/b&gt; is a Custom Data Attribute. Note that asp:TextBox will render as an input element in the browser. &lt;/p&gt;

&lt;p&gt;What is incredibly useful, is that jQuery can select elements by Custom Data Attributes. This is better than using CSS class names because CSS is for visual appearance and the CSS classes may be applied to elements you do NOT want to select with jQuery. &lt;/p&gt;

&lt;p&gt;In the following example, I have three text boxes for entering data. They all share the same CSS class. Two of the textboxes are marked with a Custom Data Attribute to specify a date type of input. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;u&gt;Page Includes:&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt; &lt;span style="COLOR: red"&gt;src&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Scripts/jquery-1.6.1.js"&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt; &lt;span style="COLOR: red"&gt;src&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Scripts/jquery-ui-1.8.15.custom/development-bundle/ui/jquery-ui-1.8.15.custom.js"&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;link&lt;/span&gt; &lt;span style="COLOR: red"&gt;href&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Scripts/jquery-ui-1.8.15.custom/css/smoothness/jquery-ui-1.8.15.custom.css"&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;rel&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="stylesheet"&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="text/css"&lt;/span&gt; &lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style="TEXT-DECORATION: underline"&gt;&lt;b&gt;CSS: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;.TextEntry&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;background-color&lt;/span&gt;: &lt;span style="COLOR: blue"&gt;Cyan&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;
&lt;p&gt;&lt;span style="TEXT-DECORATION: underline"&gt;&lt;b&gt;jQuery: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="text/javascript"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(document).ready(DocReady);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; DocReady()&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="COLOR: #a31515"&gt;"input[data-entryType = 'Date']"&lt;/span&gt;).datepicker();&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;
&lt;p&gt;&lt;span style="TEXT-DECORATION: underline"&gt;&lt;b&gt;HTML: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;table&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;tr&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Company Name:&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextBoxCompanyName"&lt;/span&gt; &lt;span style="COLOR: red"&gt;CssClass&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextEntry"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;tr&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;tr&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Start Date:&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextBoxStartDate"&lt;/span&gt; &lt;span style="COLOR: red"&gt;CssClass&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextEntry"&lt;/span&gt; &lt;span style="COLOR: red"&gt;data-entryType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Date"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;tr&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;tr&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; End Date:&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextBoxEndDate"&lt;/span&gt; &lt;span style="COLOR: red"&gt;CssClass&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextEntry"&lt;/span&gt; &lt;span style="COLOR: red"&gt;data-entryType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Date"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;td&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;tr&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;table&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;!--EndFragment--&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this code, the jQuery DatePicker is effortlessly (in a manner of speaking) attached to the correct HTML elements. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/Html5_jQuery.png" style="width: 438px; height: 384px;" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/Html5_jQuery.png"&gt;&lt;/p&gt;

&lt;p&gt;There were other slick things demonstrated at the seminar and although it was a seminar on MVC, most of the features demonstrated were applicable to ASP.NET forms. &lt;/p&gt;

&lt;p&gt;I have an open mind about MVC…if it allows me to satisfy my client's needs in a more timely fashion than ASP.NET forms, then bring it on. &lt;/p&gt;

&lt;p&gt;However, when I see source code mixed in with HTML markup, it looks like a giant step backwards towards classic ASP. I understand the frustration of dealing with the HTML output from the ASP.NET controls. Oh, yes, I do. But you don't have to use every control and there are controls that do give you 100% control over the HTML. So, I will continue to proceed with caution.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;I hope someone finds this helpful. &lt;/p&gt;

&lt;p&gt;Steve Wellens &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Sat, 20 Aug 2011 02:00:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/html-5-and-jquery-a-match-made-in-heaven</guid><category>ASP.NET</category><category>HTML 5</category><category>JQuery</category></item><item><title>Five Phases of Developer Maturity</title><link>https://weblogs.asp.net:443/stevewellens/five-phases-of-developer-maturity</link><description>
&lt;p&gt;I generally don't post stuff like this but…what the hell…
&lt;/p&gt;
&lt;p&gt;Are you a good developer?  A great developer?  A World Class developer?  Perhaps you only &lt;i&gt;think&lt;/i&gt; you are a good developer.  Maybe you are a terrible developer and don't even know it.  The only way to know for sure is to get feedback from other developers and the users of your software. 
&lt;/p&gt;
&lt;p&gt;I believe developers go through several learning phases on their way to becoming World Class developers.   There are no short cuts…the dues must be paid.  Here are five phases I have observed…as they relate to the code produced:
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="text-decoration:underline"&gt;Phase I:  It Works. &lt;/span&gt;
		&lt;/b&gt; The first time you get a program to work is immensely rewarding:  You have mastered the computer.  It was tough…but patience and persistence paid off.  Not everyone can do what you just did.  Not everyone can make a program work.   You are special.  You have experienced the magic of&lt;i&gt; bending a machine to your will&lt;/i&gt;.  
&lt;/p&gt;
&lt;p&gt;However, sometimes your program crashes.  Sometimes it gives unexpected results.  How were you to know those pesky users would type in letters when digits were expected?  Sadly, some developers never get beyond this phase.  Some begin to see themselves as 'creative visionaries':  their code is 'proof of concept' and wasn't designed for actual use (so they say).  Implementation details are left to others.  Often these people are arrogant and fool managers into believing they are gifted.  It is a sad programming shop where this occurs.
&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline"&gt;&lt;b&gt;Phase II: It Works Good. &lt;/b&gt;&lt;/span&gt;  At this phase, the developer has learned to really test the code.   They test every input and account for every output.   They check the return value of every function.  They installed exception handlers and deal with the exceptions raised in testing. The program is now bullet-proof, tsunami-proof and even pointy-haired manager proof.  It took extra work but now it is &lt;i&gt;rock solid&lt;/i&gt;.  No more embarrassing crashes.  
&lt;/p&gt;
&lt;p&gt;But there is a slight problem; the code is a pile of convoluted spaghetti with deeply nested if-else clauses and case statements.  It's disgusting to look at and it's embarrassing to admit you can't maintain your own code.   When someone asks for a new feature, you take a sick day and update your resume.
&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline"&gt;&lt;b&gt;Phase III:  It is Good.&lt;/b&gt;&lt;/span&gt;  The code works well and it's solid. But, you rewrite it anyway—sometimes several times.   You re-organize it so it is clear to read and easy to understand.  The code is logically separated into functions, classes and modules.  There are concise helpful comments in the code.  An intern may view the code and sneer, "What's the big deal, that's simple, I could have written that".  No, he couldn't.  He has no idea what it took to get the code to that state.  &lt;i&gt;Simplifying complexity is an art that cannot be taught&lt;/i&gt;.
&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline"&gt;&lt;b&gt;Phase IV:  It has Added Value.&lt;/b&gt;&lt;/span&gt;  While working on the code, you created several functions and classes that can be reused in other projects.  It takes more work to make a module reusable...three times as much work is the general consensus.   The reusable modules help other projects get a head start.  Other developers trust you and, more importantly, they trust your code.  You recognize when to consider 'outside' code and understand the risk/reward of doing so.  Leveraging the work of skilled developers is not a short cut, it's smart.
&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline"&gt;&lt;b&gt;Phase V:  It is Delivered Early.&lt;/b&gt;&lt;/span&gt;  After mastering code, design and system architecture, there is only one frontier left to keep the job interesting…beat the schedule.  Statistically, 30 to 50 percent of software projects fail.  Even more are late.  When you can deliver on-time solid code that is &lt;i&gt;easy to maintain&lt;/i&gt;, you are gold.   Caveat:  Schedules are calculated guesses.  You can plan all you want but as Mike Tyson succinctly put it:  "&lt;i&gt;Everyone has a plan, until they get hit.&lt;/i&gt;"
&lt;/p&gt;
&lt;p&gt;So, there it is—my two ¢ents.
&lt;/p&gt;
&lt;p&gt;Steve Wellens
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note to Professional Editors:&lt;/b&gt;  I'm aware the text vacillates between second and third person form…but it seemed to work that way so I broke the rules.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Fri, 15 Jul 2011 16:30:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/five-phases-of-developer-maturity</guid><category>General Software Development</category></item><item><title>Learning to Like Linq or, Loving the Linq Loquacious</title><link>https://weblogs.asp.net:443/stevewellens/learning-to-like-linq-or-loving-the-linq-loquacious</link><description>
&lt;p&gt;Once upon a time, long, long ago, I was working at a company that gave their engineers some shiny, state-of-the-art, new-fangled HP calculators.  They were awesome; instead of battery-draining LEDs for display, they used something called an LCD.  And, they had buttons galore: more buttons than any other calculator at that time.  We positively drooled at their appearance.  They looked something like this:
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/HP_11c.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/HP_11c.png" height="298" width="442"&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;But when it came time to do something useful, like adding two numbers, instead of entering: 
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3 + 5 
&lt;/p&gt;

&lt;p&gt;You had to enter:
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3 5 + 
&lt;/p&gt;

&lt;p&gt;What the heck?  Crazy!  It's all mixed up!  It was using something called:  &lt;a href="http://en.wikipedia.org/wiki/Reverse_Polish_notation" mce_href="http://en.wikipedia.org/wiki/Reverse_Polish_notation"&gt;Reverse Polish Notation&lt;/a&gt; (postfix instead of infix notation). 
&lt;/p&gt;

&lt;p&gt;A small number of people used their calculators for a few weeks but eventually everyone retired them to a bottom desk drawer.  After spending our entire lives with infix notation, no one wanted to change: &lt;i&gt; Learning something new is hard; unlearning something old is harder.&lt;/i&gt;
	&lt;/p&gt;

&lt;p&gt;Years later, while I was becoming a software engineer by going to school at night, we studied designing calculator software.  Then it made sense: Pushing and popping operators and operands on and off a stack is very efficient for the developer and the computer.  Sadly, it is unfriendly for the user.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;i&gt;I believe Linq suffers from the same malady.
&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Here is a pseudo SQL statement: &lt;br&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;    select &lt;/span&gt;MyNumber &lt;span style="color: blue;"&gt;from &lt;/span&gt;MyTable &lt;span style="color: blue;"&gt;where &lt;/span&gt;MyNumber &amp;gt; 1 &lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;nbsp;Here is a similar Linq query: &lt;br&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;    from &lt;/span&gt;MyNumber &lt;span style="color: blue;"&gt;in &lt;/span&gt;MyList &lt;span style="color: blue;"&gt;where &lt;/span&gt;MyNumber &amp;gt; 1 &lt;span style="color: blue;"&gt;select &lt;/span&gt;MyNumber&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;What the heck?  Crazy!  It's all mixed up!   
&lt;/p&gt;

&lt;p&gt;It's &lt;b&gt;Reverse Polish SQL!&lt;/b&gt;
	&lt;/p&gt;

&lt;p&gt;How many developers have looked at Linq the first time and said, "No thanks, please go away"?  A plethora, I'm sure.  
&lt;/p&gt;

&lt;p&gt;Recently however, I took on a contract that required Linq knowledge.  Guess what?  You can use the Linq library functions, which are extension methods, without having to delve into the abomination of Reverse Polish SQL.
&lt;/p&gt;

&lt;p&gt;Here's an example, create a new array that contains the elements common to two other arrays:
&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt;[] MyList1 = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt;[] { 1, 2, 3, 4 };&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt;[] MyList2 = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt;[] { 1, 7, 3, 12 };&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt;[] MyList3 = MyList1.Intersect(MyList2).ToArray();&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;One line of code!  The Intersect method is a Linq extension method. Being able to accomplish a complex task with one line of code is exhilarating and empowering.   Did I really say exhilarating?  I've got to get out more.
&lt;/p&gt;

&lt;p&gt;Here are a few more Linq extension method examples: &lt;br&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;double&lt;/span&gt; Average = MyList1.Average();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; Sum = MyList1.Sum();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyList3 = MyList1.Where(x =&amp;gt; x &amp;gt; 2).ToArray();&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;nbsp;OK, Linq is awesome.  I am sold.  To get a list of available functions, right-click on a Linq Extension method and select "Go To Definition".  There are too many functions and overloads to list here.  The functions above are in the System.Linq namespace in the static Enumerable class.  There are other classes in the namespace but Enumerable is the easiest one to jump into.  Here are the others: &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.linq.aspx"&gt;Linq Namespace&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;I hope someone finds this useful.
&lt;/p&gt;

&lt;p&gt;Steve Wellens
&lt;/p&gt;

&lt;p&gt;BTW, I have gotten used to the abomination of Reverse Polish SQL.  Hmmm, I wonder where that old HP calculator went to.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Sat, 28 May 2011 16:05:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/learning-to-like-linq-or-loving-the-linq-loquacious</guid><category>.NET</category><category>C#</category><category>Linq</category></item><item><title>Five Bucks says you’ll Bookmark this Site:  jsFiddle.net</title><link>https://weblogs.asp.net:443/stevewellens/five-bucks-says-you-ll-bookmark-this-site-jsfiddle-net</link><description>&lt;p&gt;In my never-ending wandering of technical web sites, I've been encountering links to &lt;a href="http://jsfiddle.net/" target="_blank" mce_href="http://jsfiddle.net/"&gt;jsFiddle.net&lt;/a&gt; more and more. Why? Because it is an incredibly useful site: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It is a great 'sandbox' to play in. You can test, modify and retest HTML, CSS, and JavaScript code. &lt;/li&gt;
&lt;li&gt;It is a great way to communicate technical issues and share code samples. &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;There are four screen areas: Three inputs* and one output: &lt;/p&gt;
&lt;p&gt;The three inputs are: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTML &lt;/li&gt;
&lt;li&gt;CSS &lt;/li&gt;
&lt;li&gt;JavaScript &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The output is: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The rendered result &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Here's a cropped screen shot: &lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/jsFiddle.png" style="WIDTH: 677px; HEIGHT: 255px" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/jsFiddle.png" height="325" width="1114"&gt;&lt;/p&gt;
&lt;p&gt;What am I thinking? Here's the actual page: &lt;a href="http://jsfiddle.net/Steve_Wellens/pBtQf/1/" target="_blank" mce_href="http://jsfiddle.net/Steve_Wellens/pBtQf/1/"&gt;Demo&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;*There are other inputs. You can select the level of HTML you want to run against (HTM5, HTML4.01 Strict, etc). You can add various versions of JavaScript libraries (jQuery, MooTools, YUI, etc.). Many other options are available. &lt;/p&gt;
&lt;p&gt;If I wanted to share this code with someone manually, they would have to copy and paste three separate code chunks into their development environment. And maybe load some external libraries. Not many people are willing to make such an effort. Instead, with jsFiddler, they can just go to the link and click Run. Awesome. &lt;/p&gt;
&lt;p&gt;I hope someone finds this useful (and I was kidding about the&amp;nbsp;five bucks).&lt;/p&gt;
&lt;p&gt;Steve Wellens&lt;/p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt; </description><pubDate>Wed, 02 Mar 2011 23:15:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/five-bucks-says-you-ll-bookmark-this-site-jsfiddle-net</guid><category>General Software Development</category><category>jsfiddle</category></item><item><title>jQuery Selector Tester and Cheat Sheet</title><link>https://weblogs.asp.net:443/stevewellens/jquery-selector-tester-and-cheat-sheet</link><description>&lt;p&gt;I've always appreciated these tools: &lt;a href="http://www.ultrapico.com/" target="_blank" mce_href="http://www.ultrapico.com/"&gt;Expresso &lt;/a&gt;and &lt;a href="http://www.bubasoft.net/" target="_blank" mce_href="http://www.bubasoft.net/"&gt;XPath Builder&lt;/a&gt;. They make designing regular expressions and XPath selectors almost fun! Did I say fun? I meant less painful. Being able to paste/load text and then interactively play with the search criteria is infinitely better than the code/compile/run/test cycle. It's faster and you get a much better feel for how the expressions work. &lt;/p&gt;

&lt;p&gt;So, I decided to make my own interactive tool to test jQuery selectors:&amp;nbsp;&lt;b&gt; &lt;/b&gt;&lt;a href="http://stevewellens.com/jQuerySelectorTester.htm" target="_blank" mce_href="http://stevewellens.com/jQuerySelectorTester.htm"&gt;&lt;b&gt;jQuery Selector Tester&lt;/b&gt;&lt;/a&gt;&lt;b&gt;.&amp;nbsp;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Here's a sneak peek:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/jQuerySearchTool.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/jQuerySearchTool.png"&gt;&lt;/p&gt;

&lt;p&gt;Note: There are some existing tools you may like better: &lt;/p&gt;

&lt;p style="MARGIN-LEFT: 36pt"&gt;&lt;a href="http://www.woods.iki.fi/interactive-jquery-tester.html" target="_blank" mce_href="http://www.woods.iki.fi/interactive-jquery-tester.html"&gt;http://www.woods.iki.fi/interactive-jquery-tester.html&lt;/a&gt; &lt;/p&gt;

&lt;p style="MARGIN-LEFT: 36pt"&gt;&lt;a href="http://www.w3schools.com/jquery/trysel.asp?filename=trysel_basic&amp;amp;jqsel=p.intro,%23choose" target="_blank" mce_href="http://www.w3schools.com/jquery/trysel.asp?filename=trysel_basic&amp;amp;jqsel=p.intro,%23choose"&gt;http://www.w3schools.com/jquery/trysel.asp?filename=trysel_basic&amp;amp;jqsel=p.intro,%23choose&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;My tool is different: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is one page. You can save it and run it locally without a Web Server. &lt;/li&gt;

&lt;li&gt;It shows the results as a list of iterated objects instead of highlighted html. &lt;/li&gt;

&lt;li&gt;A cheat sheet is on the same page as the tester which is handy. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I couldn't upload an .htm or .html file to &lt;i&gt;this&lt;/i&gt; site so I hosted it on my personal site here:&lt;b&gt; &lt;a href="http://stevewellens.xtreemhost.com/jQuerySelectorTester.htm" target="_blank" mce_href="http://stevewellens.xtreemhost.com/jQuerySelectorTester.htm"&gt;jQuery Selector Tester&lt;/a&gt;. &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="TEXT-DECORATION: underline"&gt;&lt;b&gt;Design Highlights: &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;To make the interactive search work, I added a hidden div to the page: &lt;/p&gt;

&lt;blockquote&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;&amp;lt;!--Hidden div holds DOM elements for jQuery to search--&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;div&lt;/span&gt; &lt;span style="COLOR: red"&gt;id&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="HiddenDiv"&lt;/span&gt; &lt;span style="COLOR: red"&gt;style&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="&lt;/span&gt;&lt;span style="COLOR: red"&gt;display&lt;/span&gt;: &lt;span style="COLOR: blue"&gt;none"&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;div&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;When ready to search, the searchable html text is copied into the hidden div…this renders the DOM tree in the hidden div: &lt;/p&gt;

&lt;blockquote&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// get the html to search, insert it to the hidden div&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; Html = $(&lt;span style="COLOR: #a31515"&gt;"#TextAreaHTML"&lt;/span&gt;).val();&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;$(&lt;span style="COLOR: #a31515"&gt;"#HiddenDiv"&lt;/span&gt;).html(Html);&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;!--EndFragment--&gt;

When doing a search, I modify the search pattern to look &lt;b&gt;only&lt;/b&gt; in the HiddenDiv. To do that, I&amp;nbsp;put a &lt;i&gt;space&lt;/i&gt; between the patterns.&amp;nbsp; The space is the Ancestor operator (see the Cheat Sheet): &lt;/p&gt;

&lt;blockquote&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// modify search string to only search in our&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// hidden div and do the search&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; SearchString = &lt;span style="COLOR: #a31515"&gt;"#HiddenDiv "&lt;/span&gt; + SearchPattern;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;try&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;{&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; $FoundItems = $(SearchString);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;}&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;!--EndFragment--&gt;&lt;b&gt;&lt;u&gt;Big Fat Stinking Faux Pas: &lt;/u&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;I was about to publish this article when I made a big mistake: I tested the tool with Mozilla FireFox. It blowed up…it blowed up &lt;i&gt;real&lt;/i&gt; good. In the past I’ve only had to target IE so this was quite a revelation. 
&lt;/p&gt;
&lt;p&gt;When I started to learn JavaScript, I was disgusted to see all the browser dependent code. Who wants to spend their time testing against different browsers and versions of browsers? Adding a bunch of ‘if-else’ code is a tedious and thankless task. I avoided client code as much as I could. 
&lt;/p&gt;
&lt;p&gt;Then jQuery came along and all was good. It was browser independent and freed us from the tedium of worrying about version N of the Acme browser. 
&lt;/p&gt;
&lt;p&gt;Right? Wrong! 
&lt;/p&gt;
&lt;p&gt;I had used outerHTML to display the selected elements. The problem is Mozilla FireFox doesn’t implement outerHTML. 
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I replaced this: 
&lt;/p&gt;
&lt;blockquote&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// encode the html markup&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; OuterHtml = $(&lt;span style="COLOR: #a31515"&gt;'&amp;lt;div/&amp;gt;'&lt;/span&gt;).text(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.outerHTML).html();&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;With this: 
&lt;/p&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// encode the html markup&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; Html = $(&lt;span style="COLOR: #a31515"&gt;'&amp;lt;div&amp;gt;'&lt;/span&gt;).append(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;).html();&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; OuterHtml = $(&lt;span style="COLOR: #a31515"&gt;'&amp;lt;div&amp;gt;'&lt;/span&gt;).text(Html).html();&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div&gt;Another problem was that Mozilla FireFox doesn’t implement srcElement. &lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;I replaced this: &lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; Row = e.srcElement.parentNode;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;div&gt;With this: &lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; Row = e.target.parentNode;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;div&gt;Another problem was the indexing. The browsers have different ways of indexing.&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;I replaced this: &lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// this cell has the search pattern&amp;nbsp; &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; Cell = Row.childNodes[1];&amp;nbsp; &lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// put the pattern in the search box and search&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;$(&lt;span style="COLOR: #a31515"&gt;"#TextSearchPattern"&lt;/span&gt;).val(Cell.innerText);&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;!--EndFragment--&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;With this: &lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// get the correct cell and the text in the cell&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: green"&gt;// place the text in the seach box and serach&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; Cell = $(Row).find(&lt;span style="COLOR: #a31515"&gt;"TD:nth-child(2)"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; CellText = Cell.text();&lt;/pre&gt;
&lt;pre style="MARGIN: 0px"&gt;$(&lt;span style="COLOR: #a31515"&gt;"#TextSearchPattern"&lt;/span&gt;).val(CellText);&lt;/pre&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;So much for the myth of browser independence. Was I overly optimistic and gullible? I don’t think so. And when I get my millions from the deposed Nigerian prince I sent money to, you’ll see that&amp;nbsp;having faith is not futile. &lt;/div&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;Notes:&lt;/b&gt; &lt;/u&gt;&lt;/p&gt;

&lt;p&gt;My goal was to have a single standalone file. I tried to keep the features and CSS to a minimum–adding only enough to make it useful and visually pleasing. &lt;/p&gt;

&lt;p&gt;When testing, I often thought there was a problem with the jQuery selector. Invariable it was invalid html code. If your results aren't what you expect, don't assume it's the jQuery selector pattern: The html may be invalid. &lt;/p&gt;

&lt;p&gt;To help in development and testing, I added a double-click handler to the rows in the Cheat Sheet table. If you double-click a row, the search pattern is put in the search box, a search is performed and the page is scrolled so you can see the results. I left the test html and code in the page. &lt;/p&gt;

&lt;p&gt;If you are using a CDN (non-local) version of the jQuery libraray, the designer in Visual Studio becomes extremely slow.&amp;nbsp; That's why there are two version of the library in the header and one is commented out.&lt;/p&gt;

&lt;p&gt;For reference, here is the jQuery documentation on selectors: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://api.jquery.com/category/selectors/" mce_href="http://api.jquery.com/category/selectors/"&gt;http://api.jquery.com/category/selectors/&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is a much more comprehensive list of CSS selectors (which jQuery uses): &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://www.w3.org/TR/CSS2/selector.html" mce_href="http://www.w3.org/TR/CSS2/selector.html"&gt;http://www.w3.org/TR/CSS2/selector.html&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hope someone finds this useful. &lt;/p&gt;

&lt;p&gt;Steve Wellens&lt;/p&gt;
&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;</description><pubDate>Sun, 13 Feb 2011 19:00:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/jquery-selector-tester-and-cheat-sheet</guid><category>ASP.NET</category><category>JQuery</category></item><item><title>Create Image Maps with GIMP</title><link>https://weblogs.asp.net:443/stevewellens/create-image-maps-with-gimp</link><description>&lt;P&gt;Having a clickable image in a web page is not a big deal. Having an image in a web page with clickable hotspots is a big deal. The powerful GIMP editor has a tool to make creating clickable hotspots much easier. &lt;/P&gt;
&lt;P&gt;GIMP stands for GNU Image Manipulation Program. Its home page and download links are here: &lt;A href="http://www.gimp.org/" mce_href="http://www.gimp.org/"&gt;http://www.gimp.org/&lt;/A&gt; (it is completely free). &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Beware&lt;/EM&gt;: GIMP is an extraordinarily advanced and powerful image editor. If you wish to use it for general image editing tasks, you have a steep learning curve to climb. FYI: I used it to create the shadows you see on the images below. Fortunately, the tool to make Image Maps is separate from the main program. &lt;/P&gt;
&lt;P&gt;To start, open an image with GIMP or, drag and drop an image onto the GIMP main window. I'm using the image of a bar graph. &lt;/P&gt;
&lt;P&gt;Next, we have to find the Image Map tool and launch it (Filters-&amp;gt;Web-&amp;gt;Image Map…): &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/StartImageMapShadow.png" width=589 height=409 mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/StartImageMapShadow.png"&gt;&lt;/P&gt;
&lt;P&gt;Why is the Image Map tool under Filters and not Tools? I don't know. It's mystery—much like the Loch Ness Monster, the Bermuda Triangle, or why my socks keep disappearing when I do laundry. I swear I've got twenty single unmatched socks. But I digress… &lt;/P&gt;
&lt;P&gt;Here is what the Image Map tool looks like: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 665px; HEIGHT: 423px" src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/ImageMapToolShadow.png" width=767 height=495 mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/ImageMapToolShadow.png"&gt;&lt;/P&gt;
&lt;P&gt;If we click the blue 'I' button, we can add information to the Image Map: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/MapFileInfoShadow.png" mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/MapFileInfoShadow.png"&gt;&lt;/P&gt;
&lt;P&gt;Now we'll use the rectangle tool to create some clickable hotspots. Select the Blue Rectangle tool, drag a rectangle, click when done and you'll get something like this: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/Area1Shadow.png" width=663 height=374 mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/Area1Shadow.png"&gt;&lt;/P&gt;
&lt;P&gt;You can also make circle/oval and polygon areas. You can edit all the parameters of an image map area after drawing it. &lt;/P&gt;
&lt;P&gt;Rectangle settings (for fine tweaking): &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 361px; HEIGHT: 395px" src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/RectangleSettingsShadow.png" width=420 height=448 mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/RectangleSettingsShadow.png"&gt;&lt;/P&gt;
&lt;P&gt;JavaScript functions (it's up to you to write them): &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 366px; HEIGHT: 409px" src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/JavaScriptShadow.png" width=420 height=448 mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/JavaScriptShadow.png"&gt;&lt;/P&gt;
&lt;P&gt;Here is a setup with two rectangles and one polygon area: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 692px; HEIGHT: 451px" src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/ThreeRegionsShadow.png" width=782 height=495 mce_src="https://aspblogs.blob.core.windows.net/media/stevewellens/2011/ThreeRegionsShadow.png"&gt;&lt;/P&gt;
&lt;P&gt;When you hit save a map file is generated that looks something like this: &lt;/P&gt;&lt;PRE style="FONT-FAMILY: Courier New; FONT-SIZE: 8pt"&gt;&amp;lt;img src="BarGraphImage.png" width="326" height="306" border="0" usemap="#BarGraphImageMap"&amp;gt;

&amp;lt;map name="BarGraphImageMap"&amp;gt;
  &amp;lt;!-- #$-:Image map file created by GIMP Image Map plug-in --&amp;gt;
  &amp;lt;!-- #$-:GIMP Image Map plug-in by Maurits Rijk --&amp;gt;
  &amp;lt;!-- #$-:Please do not edit lines starting with "#$" --&amp;gt;
  &amp;lt;!-- #$VERSION:2.3 --&amp;gt;
  &amp;lt;!-- #$AUTHOR:Steve Wellens --&amp;gt;
  &amp;lt;!-- #$DESCRIPTION:A bar graph with  no instrinsic value --&amp;gt;
  &amp;lt;area shape="rect" coords="213,62,253,269" onmouseover="ImageMapMouseHover(&amp;amp;apos;Biggest Bar&amp;amp;apos;)" onmouseout="ImageMapMouseHover(&amp;amp;apos;&amp;amp;apos;)"  nohref="nohref"&amp;gt;&amp;lt;/area&amp;gt;
  &amp;lt;area shape="rect" coords="114,131,158,267" href="~/Details2.aspx"&amp;gt;&amp;lt;/area&amp;gt;
  &amp;lt;area shape="poly" coords="57,44,76,100,181,102,183,62,142,34" href="http://www.microsoft.com"&amp;gt;&amp;lt;/area&amp;gt;
&amp;lt;/map&amp;gt;
&lt;/PRE&gt;
&lt;P&gt;Paste the contents into a web page and you are almost there. I made some tweaks before it became usable: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Replaced &amp;amp;apos; with apostrophes in the javascript functions. &lt;/LI&gt;
&lt;LI&gt;Changed the image path so it would find the image in my images directory &lt;/LI&gt;
&lt;LI&gt;Tweaked the href urls. &lt;/LI&gt;
&lt;LI&gt;Added Title="Some Text" to get tool tips. &lt;/LI&gt;
&lt;LI&gt;Cleaned out the comments. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Result: &lt;/P&gt;
&lt;P&gt;The final markup (with JavaScript function): &lt;/P&gt;&lt;PRE style="FONT-FAMILY: Courier New; FONT-SIZE: 8pt"&gt;&amp;lt;script type="text/javascript" language="javascript"&amp;gt;

    function ImageMapMouseHover(Msg)
    {
         $("#Label1").html(Msg);
    }

&amp;lt;img src="Images\BarGraphImage.png" width="326" height="306" border="0" usemap="#BarGraphImageMap"&amp;gt;

&amp;lt;map name="BarGraphImageMap"&amp;gt;
  &amp;lt;area shape="rect" coords="213,62,253,269" onmouseover="ImageMapMouseHover('Biggest Bar')" onmouseout="ImageMapMouseHover('')"  nohref="nohref"&amp;gt;&amp;lt;/area&amp;gt;
  &amp;lt;area shape="rect" coords="114,131,158,267" href="Details2.aspx" title="Details 2"&amp;gt;&amp;lt;/area&amp;gt;
  &amp;lt;area shape="poly" coords="57,44,76,100,181,102,183,62,142,34" href="http://www.microsoft.com"&amp;gt;&amp;lt;/area&amp;gt;
&amp;lt;/map&amp;gt;

&lt;/PRE&gt;
&lt;P&gt;It may seem like a lot of bother but, the tool does the heavy lifting: i.e. the coordinates. Getting the regions positioned and sized is easy using a visual tool…much better than doing it by hand. &lt;/P&gt;
&lt;P&gt;This, of course, isn't a full treatise on the tool but it should give you enough information to decide if it's helpful. &lt;/P&gt;
&lt;P&gt;I hope someone finds this useful. &lt;/P&gt;
&lt;P&gt;Steve Wellens&lt;/P&gt;
&lt;P&gt;&lt;A style="DISPLAY: none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve Wellens" rel=tag&gt;CodeProject&lt;/A&gt;&lt;/P&gt;</description><pubDate>Thu, 03 Feb 2011 03:45:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/create-image-maps-with-gimp</guid><category>ASP.NET</category><category>Image Map</category></item><item><title>The jQuery ‘live(…)’ Function</title><link>https://weblogs.asp.net:443/stevewellens/the-jquery-live-function</link><description>&lt;p&gt;[UPDATE]&lt;/p&gt;&lt;p&gt;The live function has been deprecated: "As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers."&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=" http://api.jquery.com/live/" mce_href=" http://api.jquery.com/live/"&gt;&amp;nbsp;http://api.jquery.com/live/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;On the Asp.Net forums where I am a moderator, a developer was having a problem hooking up click events to the rows of a dynamically created html table. He didn't want to embed the onclick handler in the table rows as each row was created so he tried using jQuery. The problem was he was trying to hook up the click event before the table was created. How to help him? &lt;/p&gt;
&lt;p&gt;The jQuery &lt;b&gt;live(…)&lt;/b&gt; function comes to the rescue! &lt;/p&gt;
&lt;p&gt;What can I say about jQuery and the &lt;b&gt;live(…)&lt;/b&gt; function? It's like falling in love with a beautiful woman, who is kind, can cook and keeps a tidy house. So you marry her and then you find out that she's heiress to a trust fund worth millions! &lt;/p&gt;
&lt;p&gt;The jQuery &lt;b&gt;live(…)&lt;/b&gt; function is an esoteric function; in fact, you may never find cause to use it in your entire career. But if you do use it, it can solve some problems very elegantly. &lt;/p&gt;
&lt;p&gt;To put it succinctly, instead of this: &lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="COLOR: #a31515"&gt;'#MyTable tr'&lt;/span&gt;).click(&lt;span style="COLOR: blue"&gt;function&lt;/span&gt;()&lt;/pre&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; alert(&lt;span style="COLOR: #a31515"&gt;"Table row clicked"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; })&lt;/pre&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;
&lt;p&gt;Use this: &lt;/p&gt;
&lt;div style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="COLOR: #a31515"&gt;'#MyTable tr'&lt;/span&gt;).live(&lt;span style="COLOR: #a31515"&gt;'click'&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;function&lt;/span&gt;()&lt;/pre&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; alert(&lt;span style="COLOR: #a31515"&gt;"Table row clicked"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; })&lt;/pre&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;
&lt;p&gt;The &lt;b&gt;live(…) &lt;/b&gt;function causes the event handler to be automatically assigned to elements matching the selector…&lt;i&gt;including elements that haven't been created yet.&lt;/i&gt; You heard that correctly. It assigns events to elements that don't exist. &lt;/p&gt;
&lt;p&gt;As rows are created and added to the table element in question, they automatically get the event handler assigned. &lt;/p&gt;
&lt;p&gt;While working on this I became curious and looked at the source code for the jQuery &lt;b&gt;live(…) &lt;/b&gt;function. That was a mistake. A big mistake. There is a quote from Otto von Bismark that goes something like, "…two things you don't want to see made are sausage and legislation." I think we can add the jQuery source code to that list.&amp;nbsp; To be fair, I understand that jquery code runs on millions of browsers daily.&amp;nbsp; Sacrificing some readability and maintainability for performance is perfectly reasonable under these circumstances.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Fortunately, the online documentation provides a good description of how the function works: &lt;a href="http://api.jquery.com/live/" mce_href="http://api.jquery.com/live/"&gt;http://api.jquery.com/live/&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="TEXT-DECORATION: underline"&gt;&lt;b&gt;Bonus Information:&lt;/b&gt;&lt;/span&gt; While I was poking around in the jQuery source code (with a safety rope, hard hat and air-sickness bag) I happened across some lines like these: &lt;/p&gt;&lt;pre&gt;    if ( name === "find" ) 
    if ( arguments.length === 2 )
&lt;/pre&gt;
&lt;p&gt;I'd never seen this before and it's not even mentioned in a book called &lt;i&gt;The JavaScript Bible&lt;/i&gt;. It's called the Identity Equal Operator (there is also an Identity Not Equal operator !==). &lt;b&gt;It checks both type and value. &lt;/b&gt;In other words, it does not do a type conversion before checking for equality. Here's an illustration of how it works compared to the equality operator: &lt;/p&gt;&lt;pre&gt;    var x = 3;

    // equality
    x == 3 is true
    x == '3' is true
    x == "3" is true

    // identity equality
    x === 3 is true
    x === '3' is false
    x === "3" is false&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;[Edit/Update]&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;It has been pointed out to me that&amp;nbsp;jQuery 1.4 introduced the delegate(...) function which does the same thing as the live(...) function but inserts the&amp;nbsp;event handler closer to the&amp;nbsp;selected elements&amp;nbsp;rather than at the root of the DOM so it's performance is better.&amp;nbsp; However, another person pointed out if you are attaching events to dozens of elements (say anchors) it's better to have a single handler at the top of the DOM.&amp;nbsp; Here is the best article I found discussing the differences: &lt;a href="http://test.kingdesk.com/jquery/bind_live_delegate.php"&gt;http://test.kingdesk.com/jquery/bind_live_delegate.php&lt;/a&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope someone finds this useful. &lt;/p&gt;
&lt;p&gt;Steve Wellens. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve%20Wellens" style="DISPLAY: none" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;</description><pubDate>Mon, 24 Jan 2011 18:40:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/the-jquery-live-function</guid><category>ASP.NET</category><category>JQuery</category></item><item><title>Web.Config is Cached</title><link>https://weblogs.asp.net:443/stevewellens/web-config-is-cached</link><description>&lt;P&gt;There was a question from a student over on the Asp.Net forums about improving site performance. The concern was that every time an app setting was read from the Web.Config file, the disk would be accessed. With many app settings and many users, it was believed performance would suffer. &lt;/P&gt;
&lt;P&gt;Their intent was to create a class to hold all the settings, instantiate it and fill it from the Web.Config file on startup. Then, all the settings would be in RAM. I knew this was not correct and didn't want to just say so without any corroboration, so I did some searching. &lt;/P&gt;
&lt;P&gt;Surprisingly, this is a common misconception. I found other code postings that cached the app settings from Web.Config. Many people even thanked the posters for the code. &lt;/P&gt;
&lt;P&gt;In a later post, the student said&lt;EM&gt; their text book recommended caching the Web.Config file&lt;/EM&gt;. &lt;/P&gt;
&lt;P&gt;OK, here's the deal. &lt;STRONG&gt;The Web.Config file is already cached.&lt;/STRONG&gt; You do not need to re-cache it. &lt;/P&gt;
&lt;P&gt;From this article &lt;A href="http://msdn.microsoft.com/en-us/library/aa478432.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa478432.aspx"&gt;http://msdn.microsoft.com/en-us/library/aa478432.aspx&lt;/A&gt; &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;It is important to realize that the entire &amp;lt;appSettings&amp;gt; section is read, parsed, and cached the first time we retrieve a setting value. From that point forward, all requests for setting values come from an in-memory cache, so access is quite fast and doesn't incur any subsequent overhead for accessing the file or parsing the XML. &lt;/P&gt;
&lt;P&gt;The reason the misconception is prevalent may be because it's hard to search for Web.Config and cache without getting a lot of hits on how to setup caching in the Web.Config file. &lt;/P&gt;
&lt;P&gt;So here's a string for search engines to index on: "Is the Web.Config file Cached?" &lt;/P&gt;
&lt;P&gt;A follow up question was, are the connection strings cached? &lt;/P&gt;
&lt;P&gt;Yes. &lt;A href="http://msdn.microsoft.com/en-us/library/ms178683.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms178683.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms178683.aspx&lt;/A&gt; &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;At run time, ASP.NET uses the Web.Config files to hierarchically compute a unique collection of configuration settings for each incoming URL request. These settings are calculated only once and then cached on the server. &lt;/P&gt;
&lt;P&gt;And, as everyone should know, if you modify the Web.Config file, the web application will restart. &lt;/P&gt;
&lt;P&gt;I hope this helps people to NOT write code! &amp;nbsp;&lt;/P&gt;
&lt;P&gt;Steve Wellens&lt;/P&gt;&lt;A style="DISPLAY: none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=Steve Wellens" rel=tag&gt;CodeProject&lt;/A&gt; </description><pubDate>Sat, 15 Jan 2011 16:21:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/stevewellens/web-config-is-cached</guid><category>ASP.NET</category><category>Cache</category><category>Steve Wellens</category><category>web.config</category></item></channel></rss>