AJAX Live Binding in .NET 3.5

One of the seminars at TechEd this year was on the new Live Binding method that Microsoft announced for pure AJAX applications. In the past working with pure AJAX applications (not using the update panel, think of XMLHTTP), required that you do a lot of DOM manipulations, or have a server side controller that generates the HTML which is then plugged into the client HTML stream. The first option becomes extremely tedious, hard to manage and is very error prone. The latter method works, but requires that you mix your logic and UI. While it may be possible to separate the two, it still does not make sense why the server has to take the load of structuring HTML documents when it can be busy doing far more important things. So neither option is geared toward businesses. Which is why Microsoft implemented the new Live Binding technique.

Live Binding works by binding a regular HTML page to a web service using jQuery, and the Microsoft AJAX Framework. Let’s look at an example:

The first step is to create a HTML template page, which is nothing but a regular HTML page with special markup where the active binding data is going to change, in this case {{Username}}, {{Title}}, and {{GroupMemberships}}

HTML Template

<table border="1" class="template-table" cellpadding="5">
	<thead>
		<tr>
			<th>Username</th>
			<th>Title</th>
			<th>Description</th>
		</tr>
	</thead>
	<tbody id="template" class="sys-template">
		<tr class="{{$index%2?'odd':'even'}}">
			<td>{{ Username }}</td>
			<td>{{ Title }}</td>
			<td>{{ GroupMemberships }}</td>
		</tr>
	</tbody>
</table>

Secondly, we need a web service that will return the data to the template. In this case I am querying our ActiveDirectory using the ActiveDirectory data access layer for all users in the Test OU.

Web Service

[ScriptService]
public class Service1: WebService
{

	[WebMethod]
	public List<Law.Entity.User> HelloWorld() {
		Law.Dal.ActiveDirectoryDal ad = new Law.Dal.ActiveDirectoryDal();
		List<Law.Entity.User> users = ad.GetUsersByOrganizationalUnit( Law.Utils.Enumeration.ADConnections.Test );
		return users;
	}
}

Okay, now that we have the template and data service provider, we are ready to plug the template with the web service. With just few more lines of jQuery, and Microsoft AJAX JavaScript code we can accomplish that:

Actual Binding using jQuery and Microsoft AJAX

$(document).ready(function() {
	var dataContext = $create(Sys.Data.DataContext,
	{
		serviceUri: "/ajax/service/service1.asmx"
	});

	var template = $create(Sys.UI.DataView,
	{
		autoFetch: true,
		dataProvider: dataContext,
		fetchOperation: "HelloWorld",
		fetchParameters: {}
	},
	null,
	null,
	$get("template"))
});

Let’s talk through this, to see what is going on. First notice we are using the standard jQuery document ready notation $(document).ready to run some javascript when the document is ready. The first thing is to create a DataContext, a DataContext is basically an object that talks to a web service, in this case I’ve set the serviceUri to the web service we discussed earlier.

The second and the last step is to create a DataView. A DataView uses a DataContext to populate a template – that’s it. Setting the autoFetch to true just says that whenever we hit that line of code start fetching the data, the dataProvider, simply points to the dataContext object and the fetchOperation basically says which web service method to call in the dataContext. And finally, the last statement $get(“template”) is a shorter form of document.getElementById which returns a JavaScript DOM object to the Id.

With that in place, we can run the code and it should display users from the ActiveDirectory, using a web services and live binding.

May 25th, 2009 (Updates)

One of the questions that I have seen come up often is what JavaScript libraries are required in order for this to work. Here’s a list of all the JS files and where you can download them from:

MicrosoftAjax.debug.js
MicrosoftAjaxAdoNet.debug.js
MicrosoftAjaxTemplates.debug.js
jquery-1.3.2.min.js

jQuery can be download from jQuery.com. The MicrosoftAjax libraries can be downloaded from CodePlex

Rendering Step 1 of … (ASP.NET)

The MultiView control, Wizard control or even a custom panel-based control is very useful to collect large sets of data in wizard form; and it’s often useful to give visual ques to the user as to which step he/she is in. Something similar to:

StepMaker-Screenshot

The following ASP.NET code/C# allows us to build a dynamic step control which grows or shrinks automatically given the number of views you have in a MultiView control, or the number of steps in a wizard control.

ASPX

        <asp:Repeater ID="StepMarker" runat="server">
            <headerTemplate>
                <div class="steps">
                    <h2>Step</h2>
                    <ol>
            </headerTemplate>
            <itemTemplate>
                <li<%#ReportingPanel.ActiveViewIndex==Int16.Parse(DataBinder.Eval(Container, "ItemIndex").ToString())?" class=\"active\"":""%>><%#Int16.Parse(DataBinder.Eval(Container, "ItemIndex").ToString())+1%></li>
            </itemTemplate>
            <footerTemplate>
                </ol>
                </div>
                <br style="clear:both" />
            </footerTemplate>
        </asp:Repeater>

Code Behind

/* if we have arrived at the last step we no longer need to display the step markers */
if (ReportingPanel.ActiveViewIndex + 1 == ReportingPanel.Views.Count) {
	StepMarker.Visible = false;
}
else {
	StepMarker.Visible = true;
	int[] i = new int[ReportingPanel.Views.Count - 1];
	StepMarker.DataSource = i;
	StepMarker.DataBind();
}

CSS

.steps ol {
	margin:0px;
	padding:0px;
	font-family:'arial narrow',sans-serif;
}
.steps h2 {
	font-size:19pt;
	font-weight:normal;
	color:#0066cc;
	float:left;
	padding-right:20px;
}
.steps ol li {
	float:left;
	list-style-type:none;
	font-size:19pt;
	color:White;
	background:url(../images/step-shadow.gif);
	background-repeat:no-repeat;
	background-position:left top;
	padding:0px 0px 0px 10px;
	width:43px;
	height:40px;
}
.steps ol li.active {
	font-weight:bold;
	background-image:url(../images/step-glow.gif);
}

Images

Presentation on jQuery

I presented a topic on jQuery at our campus web publishers meeting. Here are the sample pages and the PowerPoint presentation. I will talk more discussions on jQuery and how it has helped us to build a powerful web-application next week.

Automatic Documentation

Generally all programmers are lazy–and specially when it comes to documentation because it takes so much time and doesn’t necessarily produce any material benefit. GhostDoc1, designed by Roland Weigelt, is a plugin for Visual Studio 2005 that automates the generation of XML comments. For example if you have the following C#1 function:

public User GetByUserName(string userName);

GhostDoc will automatically generate:

/// <summary>
/// Gets the name of the by user.
/// </summary>
/// <param name="userName">Name of the user.</param>
/// <returns></returns>
public User GetByUserName(string userName);</code>

That’s pretty amazing. Notice how GhostDoc recognizes Camel and Pascal case variables names. And best of all once the basic structure of the comment is prepared it’s actually not very difficult to type in few words that essentially sums up what the function does if GhostDoc hasn’t already done it.

Finally, since GhostDoc integrates directly with Visual Studio all you have to do is right click the function signature and click on: “Document this” and done! GhostDoc also supports: enums, getters and setters, inheritance, interfaces and so on…

[1] GhostDoc currently only suports C#

Using SSIS to Access Network Resources

SSIS (SQL Server Integration Services) is the replacement for DTS in SQL 2005. One of the more deceitful concepts in SSIS is it’s security context. When you run a SSIS package form your Visual Studio Environment, it obviously runs under a different security context (most possibly as you–the developer) than it would run if it was run as a scheduled service on the SQL server itself. So let’s say you’ve developed a SSIS package that uses resources within your domain, such as accessing a network drive. How will SSIS access such a resource? As you may know, SSIS packages are executed by the SQL server agent, which by default uses the native [NT AUTHORITY\SYSTEM] account1 to execute your packages. Since this is a local account you cannot use it when you need access to resources external to the SQL server box.

In order to access domain level resources, you need to use a domain proxy. A domain proxy allows the SQL agent to proxy on an existing domain account when it executes a package.

The first step is to create a credential. Connect to your SQL server, expand security, right click credentials and new credential. Fill-in the dialog box to something like this:

SQL 2005 - Credentials

The second step is to create a domain proxy, expand SQL Server Agent, right click proxies and click new proxy. Fill in the dialog box something similar to the image shown on the left. Identity is the domain account you are going to use and the password to the domain account.


SQL 2005 - Proxy Accounts

Once this is done, expand SQL Server Agent, right click Proxies and click on New Proxy. The resulting dialog box should look something like the image on the left. For the credential name use the credential you just made.



SQL 2005 - SSIS Run As

Now the last step is to modify the SSIS package to use this proxy account. So right click Jobs under SQL Server Agent, right click the job that you want to run using this proxy account, click properties, go to the steps tab, click on edit at the bottom of the screen. Change Run As to the new proxy account you just created. The resulting dialog box should look something like the image on the left. Make sure the domain account, which you are using during the step when you created the credential, has access to all the network resources this package needs access to.


[1] SQL Agent actually does not use the system account but runs in the context of the SQLAgentUser group on the local machine, the [NT AUTHORITY\SYSTEM] account is by default part of the SQLAgentUser group.

Script Task reading/returning data

When you are using the Script Task in SSIS it’s often useful to have the script task return data, and also at times useful to have access to external data.

Once you drop a Script Task onto the designer and go to it’s editor, under the script tab you’ll find two attributes:
ReadOnlyVariables, ReadWriteVariables. The first allows the script to access external user variables for reading, while the latter allows write access. It’s important to realize that we are talking about user variables which is usually under the User:: namespace. So every variable you list must be prefixed by: User::. If you don’t the script assumes System::.

So here’s a screen shot of what a script task might look like:

Script Task (Variables)

Once you click on the design script you get an editor where you are allowed to type VB.NET code. At this point SSIS script tasks do not support C#. Here’s a sample of how you can access a user variable and set a value to it. As you can see from the sample code below, SSIS variables are not typed:

Public Class ScriptMain
	Public Sub Main()
		Dim Var As Variable = Dts.Variables("User::DataFiles")
		Var.Value = Table
		Dts.TaskResult = Dts.Results.Success
		...
	end Sub
end Class

Variables are read the same way:

Dts.Variables("User::LoadedFiles").Value

If you find yourself using the script task often then you might consider other ways of transforming and manipulating your data, as they can get extremely difficult to debug.

Google Analytics

The new version of Google Analytics is surprisingly good. It produces crisp, exportable, printable reports that friendly to send out to executives but at the same time allows you to drill down enough that it becomes useful for the most technical. Some of the landing pages preset information so beautifully that I simply haven’t seen in any other products (including commercial ones).

If you haven’t signed up already you should! You have no idea what you are missing out.

Reverse a linked list recursively

A question came up the other day while I was helping a friend of mine about recursively reversing a singly linked list. The moment I heard about it I came up with a solution, but turns out the solution requires the function to accept the following signature:

List* reverseList(List *l);

This actually poses a problem because there’s no way to keep track of the head, or maintain any back pointers which could’ve been done if the function accepted a second parameter. Anyway, so I thought about it and initially started with some of the base cases:

List* reverseList(List *l) {
	if(l==NULL) return NULL;
	if(l->next==NULL) return l;
	???

Now comes the tricky part. What do you do in the general case? If you think of two nodes, you realize that you have to change the next->next pointer to the current node, change the next pointer of the current node to the previous node (null if it’s the last node) and you are done! The idea is the same with nodes more than two, the only thing you have to be careful about is when you make the recursive call. One way to grasp the idea is to realize that you have to force the stack to get as deep as possible (get to the next to last node) and set it’s next node to null and then work yourself backwards.

With that thought, I came up with this:

List* reverseList(List *l) {
	if(l==NULL) return NULL;
	if(l->next==NULL) return l;
	reverseList(l->next);

Finally, I needed to reorder the next links as the stack returns back:

List* reverseList(List *l) {
	if(l==NULL) return NULL;
	if(l->next==NULL) return l;
	reverseList(l->next);

	l->next->next = l;
	l->next = null;
	return l;
}

There it was that was the solution. Notice I ignore the return statement in the recursive call. This perhaps isn’t very intuitive but since I am looking ahead one I don’t necessarily need a pointer to the last element, only until n-1.

Google launches: Universal Search

When you search for Steve Jobs, notice the result page contains, regular page results, image results, video results from YouTube, past and current news. Google is coining this new results page as Google Universal. Although this might seem like a natural extension to Google’s search engine, the development of Google Universal took almost two years with a team of hundred engineers.

One of the main reasons for Google’s success is they are able to present complex software behavior very simply so that it can be used by the general public.

Legacy code

I manage a good portion of legacy code, written by so called consultants, and I can’t believe how many places I have seen code like this:

bool flag;
if(x==y) {
	flag=true;
}
else {
	flag=false;
}

Or a variation of this

bool flag=false;

if(x==y) {
	flag=true;
}

Although the latter is better, you can write an equivalent statement as follows:

bool flag = (x==y);

How much easier is that to read? In my opinion a lot! I’ve seen arguments against that however, suggesting that it’s hard to read and not “extensible”. Meaning, if your if clause contains more than one action then my proposed statement wouldn’t work and would need to be rewritten. First of all, how’s that not readable? In fact, I feel it’s more readable than the other statements mainly because in a single line you see that flag is true if x equals y.

If you have more than one action under your if clause then you can’t use this method, but we are not talking about if clauses with more than one action, we are talking about if clauses with a single action; and if during your maintenance you realize you need to add a second action simply convert that statement to an expanded if, else clause and you are done!

Page 2 of 181234510...Last »