<CharlieDigital/> Programming, Politics, and uhh…pineapples

26Feb/08Off

SharePoint Layout Pages With CodeBehind And Prototype

Posted by Charles Chen

Let it be known that I hate out of the box ASP.NET.  Hate it, hate it, hate it, hate it.  I detest it.  The simplicity with which it allows the average developer to create applications leads to applications designed for RAD and not for scalability and it does not encourage good decoupling of business logic from UI logic.  Certainly, there are a number of frameworks which aim to alleviate this (the Web Client Software Factory, for example), but I like to take it to another level all together.


Some would argue that I take the separation of UI and application logic to the extreme: my preferred methodology relies almost purely on client side scripts to render UI and using only web services to supply data using ASP.NET AJAX.  Certainly, I lose design time support, but I gain in pure speed (all of the UI logic is in Javascript files which are cached by the client), data transfer sizes (since the only traffic is data, no presentation whatsoever), and the ultimate decoupling of UI development and server component development (the UI developer only needs to know the data model exposed by the web services).


The way I look at it, you'll only write the code a few times, but it could be in use for months (and if you're lucky in this Web 2.0 age, even a year or two).  Sure, you lose some productivity for a single developer with the loss of design time support, but you gain tremendously over time with each request serviced in terms of performance and bytes saved (a particularly important point for high traffic/high data volume applications).  As a bonus, I find it generally easier to think about application design in these terms.


Admittedly, this model seems to work better for "business applications" as opposed to "content applications".


In any case, I was interested to see if this methodology could be applied to SharePoint development as I've been working with SharePoint for quite a while now, but not at the UI level.  SharePoint allows you to deploy "application pages" which can be seemlessly integrated (kind of) into a SharePoint deployment.  This seemed like the perfect starting point to try to integrate ASP.NET AJAX and prototype, one of my favorite Javascript libraries.


The general steps are:



  1. Create an ASP.NET AJAX web application

    1. Add a reference to the Microsoft.SharePoint assembly
    2. Add the prototype.js script file to the project
    3. Add a strong name key file and sign the project
    4. Build a simple page
    5. Create a simple service

  2. Copy the content files (.js, .aspx, .asmx) over to the server to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\ into a new directory.
  3. Test by visiting the URL: http://myserver/_layouts/mynewdirectory/default.aspx

The base page should be simple.  Use the default page created by the ASP.NET AJAX web application project template and change the base class for the _Default.aspx.cs file to LayoutsPageBase instead of of the default of Page.  If you're not using ReSharper ;-), you'll need to add a using statement to your file:


using System;
using Microsoft.SharePoint.WebControls;

namespace WssAjaxApplicationTest {
public partial class _Default : LayoutsPageBase {
protected void Page_Load(
object sender, EventArgs e) {}
}
}


Next, you will need to modify the Default.aspx file.  The gist of the modifications comes from an MSDN article by Ted Pattison:


<%@ Page Language="C#" 
AutoEventWireup="true"
CodeBehind="Default.aspx.cs"
Inherits="WssAjaxApplicationTest._Default"
MasterPageFile="~/_layouts/application.master"%>

<asp:Content ID="Main" runat="server" ContentPlaceHolderID="PlaceHolderMain">
<script type="text/javascript" src="_scr/prototype.js"></script>
<script type="text/javascript" src="_scr/WssAjaxApplication.js"></script>
<script type="text/javascript">
var application;

function Init() {
application = new WssAjaxApplication();
}

Event.observe(window, "load", Init, false);
</script>
<asp:ScriptManager ID="ScriptManager1" runat="server" >
<Services>
<asp:ServiceReference Path="~/Services/EchoService.asmx" />
</Services>
</asp:ScriptManager>
<div>
<input type="text" id="message-input" />
<input type="button" id="action-button" value="Go!" />
<br />
<div id="message-output"></div>
</div>
</asp:Content>

<asp:Content ID="PageTitle"
runat="server"
contentplaceholderid="PlaceHolderPageTitle" >
Echo Page
</asp:Content>

<asp:Content ID="PageTitleInTitleArea"
runat="server"
contentplaceholderid="PlaceHolderPageTitleInTitleArea" >
The Echo Page Test
</asp:Content>


I've bolded the key part above, which is linking to the master page for SharePoint layout application pages.  In addition, you can see that I've created three placeholder content sections with the key section being the PlaceHolderMain.  I've placed my Javascript references and my ScriptManager into this section, pointing to our simple service, EchoService.asmx.  Notice the use of the root squiggly "~" :-D and the lack of squiggly on the script references to prototype.js and WssAjaxApplication.js.


The service I'm going to be using for this demo is a simple "echo service" which just echoes the input string with the server timestamp attached.  The following is my simple implementation of this web service:


using System;
using System.ComponentModel;
using System.Web.Script.Services;
using System.Web.Services;

namespace WssAjaxApplicationTest.Services {
/// <summary>
/// Summary description for EchoService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class EchoService : WebService {
[WebMethod]
[ScriptMethod]
public string Echo(string message) {
message = string.Format("You said: \"{0}\" at {1}",
message, DateTime.Now);

return message;
}
}
}


As you can see by the .aspx page above, I've organized my service in a sub-folder called "Services".  Now just make sure that you've added a copy of prototype.js under the _scr directory and my application script:


WssAjaxApplication = Class.create();

Object.extend(WssAjaxApplication.prototype, {
initialize:function() {
this.MessageInput = $("message-input");
this.ActionButton = $("action-button");
this.MessageOutput = $("message-output");

Event.observe($('action-button'), "click",
this.OnClickActionButton.bindAsEventListener(this), false);
},

OnClickActionButton:function(e) {
if(e) { Event.stop(e); } // Stop the event

// Perform the echo.
WssAjaxApplicationTest.Services.EchoService.Echo(
this.MessageInput.value,
this.OnClickActionButtonSuccess.bindAsEventListener(this),
this.OnClickActionButtonError.bindAsEventListener(this)
);
},

OnClickActionButtonSuccess:function(result) {
this.MessageOutput.innerHTML = result;
},

OnClickActionButtonError:function(error, userContext, methodName) {
window.alert(methodName +
" failed with the message: " + error.get_message());
}
});


The script simply attachs an event listener to the "Go" button and handles the click event.  Notice how clean and simple the HTML portion of the page is and how clean the Javascript is as well (admittedly, this is a very simple example).  The client rendering is completely decoupled from the UI logic except for the data and operations contract. 


You should be good to go so far as code goes.  Now compile your project with a strong named key file. 


Hopefully, the project was compiled successfully.  The next step is to copy the output dll to the GAC of the SharePoint server.  Be sure to note the public key token value.


This is probably the trickiest part: now you need to carefully merge the configuration files (is there a better tool to do this with?) generated by the project template with the web.config file located at the virtual directory root of your SharePoint application.  For example, if you have an application deployed at port 8080, the web.config file should be located at C:\Inetpub\wwwroot\wss\VirtualDirectories\8080.  Be sure to save a backup copy of the configuration file first before you attempt to merge it!


Once merged, you will need to add one more element to the configuration file:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
<system.web>
<compilation batch="false" debug="false">
<assemblies>
<add assembly="Microsoft.SharePoint,
Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" />
<add assembly="System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add assembly="WssAjaxApplicationTest,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=97d3f1fd9f5212b9"/>

</assemblies>
</compilation>
</system.web>
</configuration>

I've highlighted the key line (the line above it should have been merged into the file previously).  The bolded entry above is for the web application binary.


To test whether you've succeeded, you can simply point your browser to the URL: http://myserver/_layouts/mywebapp/default.aspx and you will have a fully AJAX enabled application using ASP.NET AJAX to connect to a .NET web service with prototype as a general purpose Javascript utility library (and you can even add scriptaculous on top of that for more awesome).


I've included a self extracting 7z file of the solution (see link below) if you'd like a quick start.  Note that the Microsoft SharePoint binaries are not included and you will have to add them back manually before the project will build.


Happy coding!

WssAjaxApplicationTest.exe (162.02 KB)

Filed under: .Net, SharePoint No Comments
22Feb/08Off

The Art And Mystery Of The Dunk

Posted by Charles Chen

Chris Ballard has an excellent essay on the art, history, and mystery of the dunk.



Like a sizable chunk of sporting America, I remain intrigued by the dunk, even if I'm not always sure why. After all, I've seen a million of them, replayed on the highlight shows and casually dropped in on NBA layup lines and shoved down my throat by anthropomorphic mascots hurtling off trampolines. Yet I can't look away.  For men, it's like cleavage; we've seen acres of it, but that doesn't stop us from looking again. It's part instinct, part the lure of the unattainable and part the hope that we'll see something spectacular.


The dunk is the easiest shot in basketball, really, but also one that relatively few can make, requiring a combination of height, youth, leaping ability and coordination. A 60-year-old can run a marathon, and almost anyone can get lucky and hit a hole in one or a half-court heave, but no one lucks into a dunk. Either you can do it or you can't.


Julius erving once said, "When you feel yourself go up above the rim for the first time and put the ball through, there's nothing like it. You want to do it again and again and again." Wilkins says throwing down made him feel like a king.


...maybe that's the ultimate appeal of the dunk. Close our eyes, and all of us can imagine doing it. Most of us never will, though, so we live vicariously through those who can, reveling in their ability to make the impossible look easy. We wish we could become one of them. Inevitably, they will become one of us.


I tried to get my body back into shape about this time last year for a push at dunking, but I came up unsuccessful, utlimately.  Mostly due having a hard time losing weight and probably putting on too much mass with weight training.  It was fun training for it, however; it definitely helped by pick up game in so far as being better at grabbing boards and sending ill-timed shots back into the shooter's face >:) (there's nothing quite like the satisfaction of emphatically blocking somone's jumpshot, though I imagine posterizing someone to be equally, it not more, exhilerating).


Worth a read for any fans of the game.

19Feb/08Off

Education And What We Can Learn From Other Countries

Posted by Charles Chen

As the spouse of a teacher, I know first hand the challenges that many young teachers face in the US today.  From waning parent interest and participation to lack of administrative support to poor professional development plans.  Of course, there is also the issue of compensation; let's face it: $40,000 just doesn't go very far.


I'd like to think that my wife is one of those teachers that takes her work very personally and always takes the initiative to help her students.  As Claudia Wallis writes in "How to Make Great Teachers", she writes that one of the key characteristics of successful teachers is "an unshakable belief in children's capacity to learn."  Indeed, I think my wife has a certain stubborness when it comes to her students in that she doesn't accept excuses for failure and always pushes her kids.  I'm constantly surprised by the number of parents of former students who come up to her and tell her how she's changed their children's lives, especially when it comes to the topic of mathematics.


One thing that amazes me is the incredible cost of education for teachers in the US and how much of that burden falls on the shoulders of America's teachers and their families, especially for post-graduate education.  For example, my wife's graduate school loans total over $25,000!  Her commitment from her school district? $750 per year.


Linda Darling-Hammond comments:



All teacher candidates in Finland, Sweden, Norway and the Netherlands, for example, receive two to three years of graduate-level preparation for teaching, at government expense, plus a living stipend.  Unlike the U.S., where teachers either go into debt to prepare for a profession that will pay them poorly or enter with little or no training, these countries made the decision to invest in a uniformly well-prepared teaching force by recruiting top candidates and paying them while they receive extensive training.


For certain, it seems like the US doesn't treat teaching like a first class profession.  Contrast this with Singapore's approach:



To get the best teachers, the [National Institute of Education] recruits students from the top third of each graduating high school class into a fully paid four-year teacher-education program and puts them on the government's payroll.  When they enter the profession, teachers' salaries are higher than those of beginning doctors.


Aside from the greather respect for the teaching profession, it seems like many countries also take a different approach to continued on the job professional development.



[In Singapore,] the government pays for 100 hours of professional development each year for all teachers.  In addition, they have 20 hours a week to work with other teachers and visit on another's classrooms.


Most US teachers, on the other hand, have no time to work with colleagues during the school day.  They plan by themselves and get a few hit-and-run workshops after school, with little opportunity to share knowledge or improve their practice.


Harold Stevenson noted that "Asian class lessons ae so well crafted [because] there is a very systematic effort to pass on the accumulated wisdom of teaching practice to each new generation of teachers and to keep providing teachers the opportunities to continually learn from each other."


In a paper titled Speeding Up Team Learning, Edmondson, Bohmer, and Pisano write, with regards to their study on surgical teams learning new procedures and practices in the area of cardiac surgery:



Teams that learned the new procedure most quickly shared three essential characteristics.  They were designed for learning; their leaders framed the challenge in such a way that team members were highly motivated to learn and the leaders' behavior created an environment of psychological safety that fostered communication and innovation.


I think we can take some of these ideas and merge apply them to the teaching profession as well by identifying what Darling-Hammond terms "expert teachers" and emphasizing the fostering of these individuals into drivers for team and mentor based professional development.  Furthermore, I think greater structured team based learning and communications would greatly enhance the experience of young teachers learning the craft.

Filed under: Rants No Comments
13Feb/08Off

Adventure Time

Posted by Charles Chen

I'm pretty sure this is the most awesome thing I've seen in a long time:




Filed under: Awesome No Comments
11Feb/08Off

Headline Of The Day

Posted by Charles Chen

"Some Team Disguised as the Nets Beats the Mavs by 19"

Filed under: lulz No Comments
11Feb/08Off

Artificial Sweeteners

Posted by Charles Chen

Time has an interesting article summarizing a study done at Perdue University on animals and how their bodies responded to artificial sweeteners.  More specifically, how their metabolism responded.  The results are a bit surprising:



When an animal eats a saccharin-flavored food with no calories, however — disrupting the sweetness and calorie link — the animal tends to eat more and gain more weight, the new study shows. The study was even able to document at the physiological level that animals given artificial sweeteners responded differently to their food than those eating high-calorie sweetened foods. The sugar-fed rats, for example, showed the expected uptick in core body temperature at mealtime, corresponding to their anticipation of a bolus of calories that they would need to start burning off — a sort of metabolic revving of the energy engines. The saccharin-fed animals, on the other hand, showed no such rise in temperature. "The animals that had the artificial sweetener appear to have a different anticipatory response," says Susan Swithers, a professor of psychological sciences at Purdue University and a co-author of the study. "They don't anticipate as many calories arriving." The net result is a more sluggish metabolism that stores, rather than burns, incoming excess calories.


So does that mean you should ditch the artificial sweeteners and welcome sugar back into your life? Not exactly. Excess sugar in the diet can lead to diabetes and heart disease, even independent of its effect on weight. But it's worth remembering that when it comes to counting calories, it's not just the ones you eat that you have to worry about. The calories you give up matter too, and they may very well reappear in that extra helping of pasta or dessert that your body demands. Your body may actually be keeping better count than you are.

Filed under: News No Comments
10Feb/08Off

Ants Boggle My Mind

Posted by Charles Chen

I'm pretty sure that if they were bigger, humans and primates would never have made it to the top of the food chain.  Check out this awesome video:





Awesome.

Filed under: Awesome No Comments
7Feb/08Off

Keep An Eye On This…

Posted by Charles Chen

My knowledge of physics isn't that great (most of it has been purged since completing my college physics courses :-D), but one thing that I do know is that perpetual motion, according to Newtonian physics, is thought to be impossible in the real world.  Thane Heins seems to have come up with a contradiction to Newtonian physics and the first law of thermodynamics :



In an interview with the Toronto Star, [Dr. Riadh] Habash was cautious but matter-of-fact with what he's seen so far. "It accelerates, but when it comes to an explanation, there is no backing theory for it. That's why we're consulting MIT. But at this time we can't support any claim."


It's now Jan. 28 – D Day. Heins has modified his test so the effects observed are difficult to deny. He holds a permanent magnet a few centimetres away from the driveshaft of an electric motor, and the magnetic field it creates causes the motor to accelerate. It went well.


Contacted by phone a few hours after the test, Zahn is genuinely stumped – and surprised. He said the magnet shouldn't cause acceleration. "It's an unusual phenomena I wouldn't have predicted in advance. But I saw it. It's real. Now I'm just trying to figure it out."


I'm just as skeptical as the next guy, but I'm going to keep my eye on this and see what comes of it.  It's also a pretty amazing story for Heins if science can legitimize his discovery.

Filed under: News No Comments