Configuration Section Designer

October 12, 2011

Personal note, this is awesome: http://csd.codeplex.com/

0

Visual Web Part in Sandbox Solution

September 16, 2011

This is super handy if you’re building web parts in a sandbox solution: http://visualstudiogallery.msdn.microsoft.com/8e602a8c-6714-4549-9e95-f3700344b0d9

0

Domain-Driven Design and The Repository Pattern in SharePoint

September 2, 2011

The Problem

I’ve done a lot of work with SharePoint in my career.  I’m talking big fat customization projects with 200,000+ lines of code.  One thing that’s always irked me is the ugly code that tends to proliferate in these projects like the following:

          using (SPSite mySite = new SPSite("http://SPSiteUrl"))
            {
                using (SPWeb myWeb = mySite.OpenWeb())
                {
                    SPList list = myWeb.Lists["MyList"];

                    SPListItem item = list.GetItemById(2);
                    item["MyField"] = "A new value";

                    item.Update();
                }
            }

As long as this is well encapsulated it’s fine, but in practice there are several problems with code like this:

  1. It tends to bleed into every corner of your code base.  It’s not uncommon to find stuff like this in the code behind for a web form (Blahhh).  When code like this is not properly wrapped and encapsulated, it tightly couples the whole codebase to the SharePoint object model and reduces its portability and maintainability.
  2. SPListItems commonly wind up representing business entities in a system.  These entities nearly always have custom data and behavior that is not included on the SPListItem type.  This means that instead of interacting with strongly-typed domain objects, you have to deal with weakly typed SPListItems.  In practice, this tends to push people towards a Transaction Script design instead of a rich Domain Model.
  3. The amount of code you’re required to write to do something simple, like update or get a list item is considerable and requires you to provide at least three strings.
  4. This type of coding is not conducive to unit testing at all.  Since everything is tightly coupled to SharePoint it makes validating your business logic with unit tests a huge headache.
  5. What happens if the name of “MyField” changes?  You’ll have to manually find every occurrence of that string and change it.  That my friend, is a pain in the ass.

My main beef with this is you wind up with ugly code that violates several widely accepted design principles.  I’ve thought a lot about what the right way to fix this is.  The answer depends on the project.  The rest of this article discusses an approach to abstracting data access called the Repository pattern that solves some of these problems.

A Solution

The Repository Pattern can help clean things up significantly. Here’s Martin Fowler’s definition:

“A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.”

Repositories provide a consistent and easily understood way to access data.  They also abstract away the implementation of

the data access so you don’t wind up tightly coupling your business logic to any given data source.

For simplicity, lets break up the solutions into the following projects:

1. Project.Core: This contains all of the domain objects and interfaces for the repositories.  There is no hard-wired dependency on the SPRepository project.

2. Project.SPRepository: This contains concrete implementations of the Repository interfaces defined in the Project.Core project.  This assembly is loaded by the Core using an inversion of control container.

3. Presentation Code:  Depending on the project this will differ, but the important thing is the only project the presentation code needs to reference is Project.Core.

You get a ton of benefits from setting up your projects this way.

  1. Your domain objects and logic are not dependent on any concrete implementation.
  2. Since your data access implementation is pluggable, unit tests for your domain code can be written without needing to set up and tear down any data in a SharePoint environment or database.
  3. SharePoint code is entirely encapsulated in the Project.SPRepository project since this is the only project with a reference to the Microsoft.SharePoint.dll.
  4. UI Code is dependent only on the Project.Core.
  5. There’s a consistent and easy to understand mechanism for accessing data throughout the system that will not change if you change platforms.

Repository Design 

Let’s take a simple example.  Consider a case where we have one custom content type called “Person” and a list instance deployed to SharePoint called “PersonList”.  Our simple content type has two custom fields: “FirstName” and “LastName”.  Take a look at the core project structure on the right.

You can see that the core project has no concrete dependency on SharePoint.  This project encapsulates the domain objects, the repository interfaces and the repository factory.

Lets start by defining the Domain objects.  In this case it’s simple, there’s one entity called Person, but let’s stick to good design principles and create an abstract base so our design is extensible:

namespace Project.Core
{
    /// <summary>
    /// Represents a base class for all entities
    /// </summary>
    public abstract class EntityBase
    {
        /// <summary>
        /// The primary key identifier for the entity
        /// </summary>
        public int ID { get; private set; }

        /// <summary>
        /// The person who created the entity
        /// </summary>
        public string CreatedBy { get; set; }

        /// <summary>
        /// The last person to modify the entity
        /// </summary>
        public string LastModBy { get; set; }

        /// <summary>
        /// The title of the entity
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// Default Constructor.  Initializes the entity with all the default values.
        /// </summary>
        protected EntityBase() : this(0, string.Empty, string.Empty, string.Empty)
        {}

        /// <summary>
        /// Initializes the entity with the input values
        /// </summary>
        /// <param name="id">The id of the entity</param>
        /// <param name="title">The title of the entity</param>
        /// <param name="createdBy">The person who created the entity</param>
        /// <param name="lastModBy">The last person to modify the entity</param>
        protected EntityBase(int id, string title, string createdBy, string lastModBy)
        {
            ID = id;
            Title = title;
            CreatedBy = createdBy;
            LastModBy = lastModBy;
        }

        /// <summary>
        /// Creates or updates the entity
        /// </summary>
        public abstract void Save();
    }
}

Then we would define the Person entity:

using Project.Core.Repository;

namespace Project.Core
{
    /// <summary>
    /// Represents a person entity
    /// </summary>
    public class Person : EntityBase
    {
        /// <summary>
        /// The first name of the Person
        /// </summary>
        public string FirstName { get; set; }

        /// <summary>
        /// The last name of the Person
        /// </summary>
        public string LastName { get; set; }

        /// <summary>
        /// Initializes an instance of Person with all of the default values
        /// </summary>
        public Person() : this(string.Empty, string.Empty)
        {}

        /// <summary>
        /// Initializes an instance of Person with the input first name and last name
        /// </summary>
        /// <param name="firstName">The first name of the person</param>
        /// <param name="lastName">The last name of the person</param>
        public Person(string firstName, string lastName) : this(0, string.Empty, string.Empty, string.Empty, firstName, lastName)
        {}

        /// <summary>
        /// Initializes an instance of Person with all of the input parameters
        /// </summary>
        /// <param name="id">The primary key ID of the user</param>
        /// <param name="title">The title of the user</param>
        /// <param name="createdBy">The user who created this person</param>
        /// <param name="lastModBy">The user who last modified this person</param>
        /// <param name="firstName">The first name of the person</param>
        /// <param name="lastName">The last name of the person</param>
        public Person(int id, string title, string createdBy, string lastModBy, string firstName, string lastName)
            : base (id, title, createdBy, lastModBy)
        {
            FirstName = firstName;
            LastName = lastName;
        }

        /// <summary>
        /// Creates or updates the Person
        /// </summary>
        public override void Save()
        {
            IPersonRepository personRepo = RepositoryFactory.GetRepository<IPersonRepository>();
            if (ID > 0)
            {
                personRepo.Update(this);
            }
            else
            {
                personRepo.Add(this);
            }
        }
    }
}

The next step is defining the interfaces for accessing the repository.  This breaks down into two parts.  First, you have to define the interfaces for the repository itself.  Second, you must define the framework that will be used to query the repository.

IRepository
using System.Collections.Generic;
using Project.Core.Repository.Queries;

namespace Project.Core.Repository
{
    /// <summary>
    /// Defines the basic contract used by all repositories
    /// </summary>
    /// <typeparam name="T">The type of domain object that the repository will be used to retrieve</typeparam>
    /// <typeparam name="TE">The type of the query object that is used to search for objects in this repository</typeparam>
    public interface IRepository<T, TE> where T : EntityBase where TE : QueryBase<T>
    {
        /// <summary>
        /// Adds the input item to the repository
        /// </summary>
        /// <param name="newEntity"></param>
        void Add(T newEntity);

        /// <summary>
        /// Deletes the input item from the repository
        /// </summary>
        /// <param name="id"></param>
        void Delete(int id);

        /// <summary>
        /// Updates the input item in the repository
        /// </summary>
        /// <param name="entity"></param>
        void Update(T entity);

        /// <summary>
        /// Gets the item with the input id from the repository
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        T Get(int id);

        /// <summary>
        /// Gets all of the items from the repository
        /// </summary>
        /// <returns></returns>
        IList<T> All();

        /// <summary>
        /// Finds items matching the input query object in the repository
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        IList<T> Find(TE query);
    }
}

 

Notice that IRepository takes two generic parameters.  The first specifies the type of the entity that will be contained in the repository.  The second defines the type of object that will be used to query the repository.  This second type is one of the more powerful aspects of this pattern.  What we’re doing here is defining a context-independent interface for accessing and querying data.  Setting things up this way allows us to send queries to any data source without changing the Core project.  Take a look at how the query objects are set up.

QueryBase
namespace Project.Core.Repository.Queries
{
    /// <summary>
    /// Base class for all query objects.  Objects that inherit from this class are used to query repositories in the Core.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class QueryBase<T> where T : EntityBase
    {
        /// <summary>
        /// The template object that is matched against when querying the repository.
        /// </summary>
        private T _template;

        /// <summary>
        /// The template object that is matched against when querying the repository.
        /// </summary>
        public T Template
        {
            get { return _template; }
            set{ _template = value; }
        }

        /// <summary>
        /// Initializes the query object
        /// </summary>
        protected QueryBase()
        {
        }

        /// <summary>
        /// Initializes the query object
        /// </summary>
        /// <param name="template">The template object used to match records in the repository</param>
        protected QueryBase(T template)
        {
            _template = template;
        }
    }
}

Objects implementing QueryBase could contain additional parameters for the query.

The last step is defining an interface that the repository implementations will use to map objects from their data sources into domain objects.  Here’s the code for defining the mapper:

IMapper
namespace Project.Core.Repository
{
    /// <summary>
    /// Defines a common interface for mapping domain entities into data records and vice versa.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IMapper<T> where T : EntityBase
    {
        /// <summary>
        /// Maps a data record into a domain object
        /// </summary>
        /// <param name="dataSource">The data source object</param>
        /// <returns>The mapped domain entity</returns>
        T FromData(object dataSource);

        /// <summary>
        /// Maps a domain entity into a data record
        /// </summary>
        /// <param name="domainEntity"></param>
        /// <returns></returns>
        object ToData(T domainEntity);
    }
}

That covers all the pieces that you need in the Core.  Whew!  If you’re still with me pat yourself on the back.  We’re almost done.

SPRepository

The next step is implementing the repository for SharePoint.  We need to set up a simple project that provides concrete implementations for all of our repositories (see right).

NOTE: In this implementation I’m leveraging LINQ to SharePoint.  It’s an extremely flexible mechanism for querying SharePoint 2010 data.  There is a performance hit that comes with this flexibility, but for our purposes here it’s acceptable.

Person Mapper

Here’s the person mapper:

using System;
using Project.Core;
using Project.Core.Repository;

namespace Project.SPLinqRepository.Mappers
{
    /// <summary>
    /// Provides mapping functionality between the Person SharePoint content type and the Person domain object
    /// </summary>
    internal class PersonMapper : IMapper<Person>
    {
        /// <summary>
        /// Maps an Person into a Person
        /// </summary>
        /// <param name="dataSource">The data source entity</param>
        /// <returns>The fully populated domain object</returns>
        public Person FromData(object dataSource)
        {
            LinqPerson aewPerson = dataSource as LinqPerson;
            if(aewPerson == null)
            {
                return null;
            }

            Person person = new Person(
                aewPerson.Id.Value,
                aewPerson.Title,
                aewPerson.CreatedBy,
                aewPerson.ModifiedBy,
                aewPerson.FirstName,
                aewPerson.LastName);

            return person;
        }

        /// <summary>
        /// Maps a Person into an AEWPerson
        /// </summary>
        /// <param name="domainEntity">The Person to transform into an AEWPerson</param>
        /// <returns>The fully populated AEWPerson</returns>
        public object ToData(Person domainEntity)
        {
            if (domainEntity == null)
            {
                return null;
            }

            LinqPerson person = new LinqPerson();
            if (domainEntity.ID > 0)
            {
                person.Id = domainEntity.ID;
            }
            person.CreatedBy = domainEntity.CreatedBy;
            person.ModifiedBy = domainEntity.LastModBy;
            person.Title = domainEntity.Title;
            person.FirstName = domainEntity.FirstName;
            person.LastName = domainEntity.LastName;

            return person;
        }
    }
}
PersonRepository

Here’s the implementation of the person repository:

public class PersonRepository : IRepository<Person, PersonQuery>
    {
        public void Add(Person newEntity)
        {
            using (DataContext context = new DataContext(Configuration.SiteUrl))
            {
                PersonMapper personMapper = new PersonMapper();
                LinqPerson aewPerson = personMapper.ToData(newEntity) as LinqPerson;

                context.PersonList.InsertOnSubmit(aewPerson);
                context.SubmitChanges();
            }
        }

        public void Delete(int id)
        {
            using (DataContext context = new DataContext(Configuration.SiteUrl))
            {
                LinqPerson aewPerson = context.PersonList.SingleOrDefault(p => p.Id == id);
                if (aewPerson != null)
                {
                    context.PersonList.DeleteOnSubmit(aewPerson);
                    context.SubmitChanges();
                }
            }
        }

        public void Update(Person entity)
        {
            using (DataContext context = new DataContext(Configuration.SiteUrl))
            {
                PersonMapper personMapper = new PersonMapper();
                LinqPerson aewPerson = personMapper.ToData(entity) as LinqPerson;

                context.PersonList.Attach(aewPerson);
                context.SubmitChanges();
            }
        }

        public Person Get(int id)
        {
            Person person = null;
            using (AEWDataContext context = new AEWDataContext(AEWConfiguration.SiteUrl))
            {
                LinqPerson aewPerson = context.PersonList.SingleOrDefault(p => p.Id == id);

                PersonMapper personMapper = new PersonMapper();
                person = personMapper.FromData(aewPerson);
            }
            return person;
        }

        public IList<Person> All()
        {
            IList<Person> people = new List<Person>();
            using (DataContext context = new DataContext(Configuration.SiteUrl))
            {
                PersonMapper mapper = new PersonMapper();
                foreach (LinqPerson aewPerson in context.PersonList)
                {
                    Person person = mapper.FromData(aewPerson);
                    people.Add(person);
                }
            }
            return people;
        }

        public IList<Person> Find(PersonQuery query)
        {
            IList<Person> people = new List<Person>();
            Expression<Func<LinqPerson, bool>> predicate = PredicateBuilder.True<LinqPerson>();
            using (DataContext context = new DataContext(Configuration.SiteUrl))
            {
                if (!string.IsNullOrEmpty(query.Template.FirstName))
                {
                    predicate = predicate.And<AEWPerson>(p => p.FirstName == query.Template.FirstName);
                }
                if (!string.IsNullOrEmpty(query.Template.LastName))
                {
                    predicate = predicate.And<AEWPerson>(p => p.LastName == query.Template.LastName);
                }
                if (!string.IsNullOrEmpty(query.Template.CreatedBy))
                {
                    predicate = predicate.And<AEWPerson>(p => p.CreatedBy == query.Template.CreatedBy);
                }
                if (!string.IsNullOrEmpty(query.Template.LastModBy))
                {
                    predicate = predicate.And<AEWPerson>(p => p.ModifiedBy == query.Template.LastModBy);
                }

                var aewPeople = context.PersonList.Where(predicate);
                PersonMapper personMapper = new PersonMapper();
                foreach (LinqPerson aewPerson in aewPeople)
                {
                    Person person = personMapper.FromData(aewPerson);
                    people.Add(person);
                }
            }
            return people;
        }
    }

Repository in Action

So now that you’ve set up this Repository, what does it look like when you actually use it?  Here are a few examples of core use cases.

Adding an Item
            //Get the repository
            IPersonRepository personRepo = RepositoryFactory.GetRepository<IPersonRepository>();

            //Create a new person object
            Person hanz = new Person("Hanz", "Vagner");

            //Add the person to the repository
            personRepo.Add(hanz);

Getting an Item

            //Get the repository
            IPersonRepository personRepo = RepositoryFactory.GetRepository<IPersonRepository>();         

            //Get the person from the repository
            Person person = personRepo.Get(3);
Saving an Item
            //Get the repository
            IPersonRepository personRepo = RepositoryFactory.GetRepository<IPersonRepository>();         

            //Get the person from the repository
            Person person = personRepo.Get(3);

            //Change the first name
            person.FirstName = "Franz";

            //Save your change
            person.Save();
Finding an Item
            //Get the repository
            IPersonRepository personRepo = RepositoryFactory.GetRepository<IPersonRepository>();

            //Create a query
            PersonQuery personQuery = new PersonQuery(new Person { FirstName="Hanz" });

            //Find all people with the first name "Hanz"
            IList<Person> people = personRepo.Find(personQuery);

Conclusion

As you can see, the repository gives you a consistent interface for accessing and manipulating domain objects regardless of the data source implementation.  I hope you found this helpful.  In my experience this sort of decoupling can be very helpful.  It’s not right for every scenario, but if you find yourself in a situation where code re-usability is paramount, this approach has a lot of benefits.

3

Error Content Type is in use… wait, no it isn’t!

August 24, 2011
Tags:

If you’ve ever tried removing all the SharePoint lists associated with a content type, then deleting the content type, you may have still gotten an error saying the content type is in use. To fix this you need to clear the recycle bin.

Yes. This is annoying.

Go to the normal recycle bin: http://sharepoint/_layouts/recyclebin.aspx, clear the problem list.

Then go to the deleted from end user recycle bin, recycle bin: http://sharepoint/_layouts/AdminRecycleBin.aspx?View=2, and clear the problem list again.

Voila, your content type can be deleted.

2

Calling an External Assembly from a Sandbox Solution

August 22, 2011

This one ground my gears for about two hours.  If you’re trying to call code in an external assembly from a Sandbox Solution in SharePoint 2010, you may have gotten this error message:

“Web Part Error: Unhandled exception was thrown by the sandboxed code wrapper’s Execute method in the partial trust app domain: An unexpected error has occurred.”

This is the generic error message that comes up whenever you try to do something that violates the CAS policies for sandbox solutions.  Beyond that, it doesn’t give you much to go on (thanks Microsoft).

Luckily the solution is pretty simple.  Assuming the code that you are trying to reference doesn’t violate any of the sandbox solution restrictions (see Microsoft’s documentation for more details), you can follow these steps to add a reference to an external class library to your Sandbox Solution.

  1. Open up the AssemblyInfo.cs class in each of the assemblies you want to reference and make sure that they include the AllowPartiallyTrustedCallers attribute.  Code that runs in sandbox solutions can only interact with code that allows partially trusted callers.
  2. In your SharePoint project in visual studio, right click on the “Package” directory and click “View Designer”, click “Advanced” and add the additional assembly.
That’s it.  Sandbox solutions are more difficult to work with, but I’m discovering that there are workarounds for most things.
0

How to make jQuery Autocomplete and WCF Services play nice

January 7, 2011

Wow.  File this under things that were way harder than they needed to be.  I spent the majority of my morning trying to get a jQuery autocomplete textbox to talk to a WCF Service.  This is definitely worth documenting.

The reason that I was trying to do this was performance.  I needed the autocomplete to read from a list of several hundred thousand names, which makes caching these in js or the DOM very ugly.  The solution for me is delegating the list retrieval and the searching to a WCF service.  In my production scenario this service pulls the names out of a cache.  In the example below I’ll simplify it a bit and just use a small list so you can get the idea.

Pre-requisites:

  1. Make sure you have jQuery loaded.  If you don’t have a copy, you can get one here.
  2. Make sure you have jQuery UI loaded.  If you don’t have a copy you can get one here.

The first step is configuring the WCF Service:

SearchService.svc

[ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class SearchService
    {
        [OperationContract]
        [WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest,
            RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public IEnumerable<string> FindTerms(string term)
        {
            //This is just some test data for the autocomplete
            string[] terms = new []
              {
                  "John",
                  "John Peterson",
                  "John Prior Peterson",
                  "John the programmer",
                  "John Jones",
                  "John Doe",
                  "John Smith"
              };

            IEnumerable<string> filteredTerms = terms.Where(s => s.StartsWith(term, StringComparison.InvariantCultureIgnoreCase));
            return filteredTerms;
        }
    }

Web.Config

	<system.serviceModel>
		<behaviors>
			<endpointBehaviors>
				<behavior name="SpeedySearch.Web.SearchServiceAspNetAjaxBehavior">
					<enableWebScript/>
				</behavior>
			</endpointBehaviors>
		</behaviors>
		<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
		<services>
			<service name="SpeedySearch.Web.SearchService">
				<endpoint address="" behaviorConfiguration="SpeedySearch.Web.SearchServiceAspNetAjaxBehavior" binding="webHttpBinding" contract="SpeedySearch.Web.SearchService"/>
			</service>
		</services>
	</system.serviceModel>

Next you need to set up your aspx.  Note the references to jQuery and jQuery UI.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SpeedySearch.Web._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
    <link href="/js/jQuery/jquery-ui.custom.css" rel="stylesheet" type="text/css" />   

    <script src="/js/jQuery/jquery.min.js" type="text/javascript"></script>
    <script src="/js/jQuery/jquery-ui.custom.min.js" type="text/javascript"></script>        

    <script type="text/javascript">
        $(document).ready(function() {

            $("#_autocomplete").autocomplete({
                minLength: 2,
                source: function(term, data) {
                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        url: "SearchService.svc/FindTerms",
                        data: { "term": term.term },
                        dataType: "json",
                        success: function(response) {
                            data(response.d);
                        }
                    });
                }
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <input id="_autocomplete" />
    </form>
</body>
</html>

Now you should be good to go.  Good luck!

1

JQuery Conference 2010: Boston

October 18, 2010

I got the opportunity to attend the jQuery conference in Boston over the weekend and I want to share some of the awesome stuff I learned.  I’m going to follow this up with several other posts over the next week or so as I investigate the various awesome tools and concepts that I learned about, but for now I want to do a quick rundown of the highlights and best presentations.

Great Presentations

While all the speakers were great, there were four that really stood out for me.  Two of these were the keynote speakers and the other two gave presentations on development efficiency and best practices.  If you’re like me and you work in a .NET/Java shop, an argument you’ve probably heard against jQuery is that it’s not compile time checked and it’s not stable because the code is written in fugly javascript.  These presenters and the tools they showed off  really make a strong case against that argument.

The first was John Resig, one of the creators of jQuery.  He made the keynote address on Saturday and gave a run down of some of the exciting new features that are coming out in jQuery 1.4.3.  It really is remarkable how successful and powerful jQuery has become.  It’s used on nearly 40% of the top 10,000 websites worldwide and that number is growing rapidly.  This statistic alone should throw any worries about the maturity or stability of the jQuery library out the window.

The second was Richard D. Worth, who gave the keynote on Sunday.  He’s the release manager of jQuery UI, and that was his focus.  In short, it is very impressive what these guys have created for UI developers.  Their UI widgets and third party extensions of these widgets made by companies like Wijmo, will drastically reduce the amount of effort it takes to build rich, interactive web sites.  As a .NET developer by trade, it’s great to see a viable solution to traditional Asp.Net WebControls being baked into the out-of-the-box jQuery framework.

The last two presentations I’ll talk about together.  They were given by Menno van Slooten and Alex Sexton.  These two were hands down the most useful at the entire conference.  As a developer I am constantly looking for ways to increase my efficiency and the efficiency of those around me.  The tools and concepts that these guys talked about have the potential to drastically improve both the productivity of front end developers and the stability of the code that they produce.  While it’s true that javascript is not compile time checked, there are tools out there that allow for complete UI functional testing, unit testing and decoupling of segments of applications.  

Great Tools and Features

Here are some really great tools, features and new products:

  • Voxeo PhonoSDK: This is very awesome.  These guys put together an SDK that allows you to make phone calls through your browser using nothing but javascript, JAVASCRIPT!!! (free for the first 10 minutes). 
  • jQuery DataLinking: This is a new feature.  It’s very similar to data binding and was developed with help from people at Microsoft.  It amounts to a very clean way to populate your page and modify the corresponding object.
  • jQuery Templating:  I’ve seen a number of different ways of doing this, but this is the cleanest syntax in my opinion.  I’ll be modifying the code I used in a previous post to use this templating engine.  It’s also integrated in jQuery 1.4.3 so you don’t need any additional code to support it.
  • Adding element syntax:  I had never seen this syntax for creating elements, but I like it.  It’s more object-oriented.
  • Live Events:  These are cool, but not new.  They automatically apply events to newly generated elements if they share the correct properties.
  • FuncUnit:  I like this one (a lot).  Automated functional testing of web pages.  If nothing else this speeds up development considerably.  No more refresh, click, type, click , type, test…  How would you’re QA team feel about getting a set of automated functional tests for every UI in your application when you hand off the code?  My guess is they’d be pumped.
  • MockJax: I also like this one.  For projects where your front end and back end teams are separated, this is essential.  It allows you to set up Mock ajax responses for testing a UI.  No longer will a web developer have to wait until a server developer is finished.  As long as a contract is defined between the two teams, the two can work independent (at least in theory).
  • jQueryUI:  I haven’t played with this stuff yet, but it looks very powerful and they apparently have some new features in 1.4.3.   They’re also currently working with Microsoft to develop a Grid control, which they are saying will be part of a new release in January 2011.
  • Wijmo:  They just released a set of sexy looking open source javascript widgets.  They’ve also got a more extensive set that you can buy. 
  • qUnit:  So you think you can’t unit test javascript huh.  This is baked right into jQuery… Awesome.
  • RequireJs:  This is handy for cleaning up your markup and building dependencies into your JavaScript application files instead of your pages.  It’s basically a bootstrapper for javascript.  This is great because it allows you to remove sets of javascript dependencies from your pages and place them in the files containing the code that is actually dependant on them.  I’m a clean code NAZI.  This tool is awesome.
  • LabJs:  This is similar to requireJs.  It’s a highly optimized javascript loader that allows you to build dependencies between your JavaScript files. 
  • Underscore.js:  A basic utility library that augments jquery’s functionality.  
  • PubSub:  This is an eventing API that sits on top of jQuery.  I need to read more about this and how it’s different from the jQuery eventing API, but it seems like a good tool to decouple segments of your javascript application.
  • PromoteJs/JsDocs:  Javascript documentation tool.  I still need to try this out, but it looks great.
  • Backbone.js:  Need to read more about this one as well.  Seems like it’s a library that will help you decouple segments of your app.

Like I said, I’ve got to spend some time investigating each of these tools.  Some of them try to solve the same (or very similar) problems, but in slightly different ways.  I’ll be doing lots of posts on these in the future.

Overall this was a great experience.  Thanks very much to the jQuery project and everyone that helped put the conference together.  I’ll definitely be attending next year as well.

5

Building Web Controls with jQuery

October 8, 2010

Introduction

In a previous post I discussed some of the features of jQuery that enable WCF communication.  In this post I’m going to expand on that and describe how to build DHTML controls with jQuery.  These are a great alternative to traditional asp.net web controls in many scenarios.  In this post I’ll show you how to create a reusable, template based grid control using jQuery. 

Why do this?

I don’t want to get into too many details, but here are a few reasons: 

  1. Traditional Asp.Net controls are heavy.  What does heavy mean?  In this context I’m talking about three things: ViewState, postbacks and lots of unneccessary features.
  2. The traditional Asp.Net development model tends to promote bad coding practices i.e. blurring the lines between presentation and business logic
  3. jQuery gives you a cleaner, lighter, more responsive UI.  Especially if you eliminate postbacks and use ajax calls instead.  You don’t need an update panel or a postback to capture a cell click, for example.
  4. You have a much higher degree of control over the rendered html.  More control is always a good thing.

The Basics

I’m going to build on my previous post Calling WCF Services using jQuery.  If you’ve got any questions about the services I’m calling please refer to that post.  Let’s assume we have an aspx page that is executing an ajax request to retrieve a list of people: 

function getPeople() {
    //Make ajax request...
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "WebServices/PeopleService.svc/GetPeople",
        processData: false,
        dataType: "json",
        //If the call succeeds
        success:
            function(response) {

            },
        //If the call fails
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.responseText);
        }
    });
}

So we’ve got our list of objects.  The next step is displaying them in a grid for our users.  We could just hard wire code that creates an html table, but a better approach is creating a template-driven control.  This way we’ll end up with a handy reusable component that will reduce the work we have to do on similar things in the future.  Consider the aspx page below for starters: 

<head runat="server">
    <title>Jquery Intro</title>    

    <script src="JavaScript/jquery-1.4.1.js"type="text/javascript"></script>
    <script src="JavaScript/json2.js" type="text/javascript"></script>
    <script src="JavaScript/Default.js" type="text/javascript"></script>
    <script src="JavaScript/Grid.js" type="text/javascript"></script>
    <%--Grid Templates--%>
    <script type="text/html" id="_gridTemplate">
        <tr>
            <td><#= FirstName #></td>
            <td><#= LastName #></td>
            <td><#= Age #></td>
        </tr>

    </script>
</head>
<body>
    <form id="form1" runat="server">
         <div id="_gridDiv">
            <table id="_gridTable">
                <thead>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Age</th>
                </thead>
                <tbody></tbody>
                <tfoot></tfoot>
            </table>
        </div>
    </form>
</body>

There are two important things here.  First is the table with id “_gridTable”.  This is the target table for your grid.  Also, notice the script with id “_gridTemplate”.  This is the template for a row in your grid.  Notice how I’ve got the names of the members surrounded by “<#= #>” tags.  This is what allows the control’s templating engine to extract the properties from each json object. 

Let’s take a look at the code for the grid next: 

Grid = function() {
    //The id of the table that the grid uses to generate its content
    var _targetTableId;

    //The id of the template script that the grid uses
    var _templateId;

    return {
        initialize: function(targetTableId, templateId) {
            if ($("#" + _targetTableId).length == 0) {
                _targetTableId = targetTableId;
                _templateId = templateId;
            }
        },
        bind: function(data) {
            //remove all old rows
            $("#" + _targetTableId + " tbody tr").remove();

            $.each(data, function(i) {

                var template = $("#" + _templateId).html();
                var html = parseTemplate(template, this);
                var newItem = $(html);

                newItem.appendTo("#" + _targetTableId + " tbody");
            });
        }
    }
};

This is pretty basic right?  It’s got two public methods: initialize and bind.  The initialize function exists to set up the state of the object, sort of like a constructor.  It accepts the id of the target table, in this case “_gridTable” and the id of the template, “_gridTemplate”.  It stores these for use later. 

The bind method is where the magic happens.  It accepts an array of objects, iterates through them and uses a templating engine to generate the corresponding html.  It then appends that html to the body of the table with the id that we populated in the initialize method.  I have to give Rick Strahl props for the templating engine.  You’ll need to use the code below to get the template working: 

/* based on John Resig's Micro Templating engine, taken from Rick Strahl's web log */
var _tmplCache = {}
this.parseTemplate = function(str, data) {
    var err = "";
    try {
        var func = _tmplCache[str];
        if (!func) {
            var strFunc =
            "var p=[],print=function(){p.push.apply(p,arguments);};" +
                        "with(obj){p.push('" +
            str.replace(/[\r\t\n]/g, " ")
               .replace(/'(?=[^#]*#>)/g, "\t")
               .split("'").join("\\'")
               .split("\t").join("'")
               .replace(/<#=(.+?)#>/g, "',$1,'")
               .split("<#").join("');")
               .split("#>").join("p.push('")
               + "');}return p.join('');";

            func = new Function("obj", strFunc);
            _tmplCache[str] = func;
        }
        return func(data);
    } catch (e) { err = e.message; }
    $("#errors").html(err);
}

Once you’ve got this, you should be good to go.  The code above will generate a very plain looking html table.  I’ll leave configuring some nice css to you, you’ve got a blank slate to work with.  Look how easy it is to use this new control from the perspective of the caller: 

var _grid;

$(document).ready(function() {
    _grid = new Grid();
    _grid.initialize('_gridTable', '_gridTemplate');

    getPeople();
});

function getPeople() {
    //Make ajax request...
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "WebServices/PeopleService.svc/GetPeople",
        processData: false,
        dataType: "json",
        //If the call succeeds
        success:
            function(response) {
                _grid.bind(response.GetPeopleResult); //bind the results to the grid
            },
        //If the call fails
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.responseText);
        }
    });
}

Very cool stuff.  We’ve now got a reusable way to bind a collection to an html table and it takes only three lines of code to do it. 

Incorporating Events

Now that we’ve covered the basics, lets add some features.  Events are a good place to start.  The jQuery event model is very powerful.  We can use events in lots of places, but one of the most obvious is sorting.  Sorting is something any grid control needs to support.  Luckily this is really simple.  Let’s think about the goal here for a second.  All we really need to do is configure a mechanism to tell people that the user initiated a sort based on one of the columns.  To support this all we need to do is fire an event whenever a user clicks on a cell header.  We can leave the implementation of sorting logic to our callers.  That’s their business.  

To incorporate this into the grid, all you need to do is respond to the click event on the grid headers and fire off the event like so: 

 bind: function(data) {
            //remove all old rows
            $("#" + _targetTableId + " tbody tr").remove();

            $.each(data, function(i) {

                var template = $("#" + _templateId).html();
                var html = parseTemplate(template, this);
                var newItem = $(html);

                newItem.appendTo("#" + _targetTableId + " tbody");
            });

            $("#" + _targetTableId + " thead th").click(function(e) {
                $("body").trigger("OnGridSorted", $(e).html());
            });
        }

Once you’ve got that part, you need to create an event handler in the caller to respond to the OnGridSorted event: 

var _grid;

$(document).ready(function() {
    _grid = new Grid();
    _grid.initialize('_gridTable', '_gridTemplate');

    //Bind sorted event handler
    $('body').bind('OnGridSorted', handleGridSorted);   

    getPeople();
});

/*
*   Handles the sort event for the grid
* */
function handleGridSorted(e, sortColumnName) {
    //Execute sort logic here.  I'd recommend delegating this to the server.
}

Now you’ve got a place to execute whatever sorting logic you need.  Most likely you’ll want to do another ajax call here and delegate this to the server. 

Thats all for now.  This is a big topic and I’m sure I’ll do more posts on it in the future.  

 

4

.NET Reflection and the Command Pattern

September 30, 2010

Introduction

Every time I work with reflection in C# I’m impressed by how powerful it is.  As a tool for decoupling segments of an application, reflection has few peers in the .NET framework. 

Remembering that good code is “open for extension, but closed for modification”, it’s relatively easy to see why something like reflection is so helpful.  It allows you to decouple sections of an application that would otherwise be tightly coupled.  Here I’m going to explore how reflection can be used to facilitate working with class hierarchies.  I’ll use a simplified version of the command pattern to drive the discussion.

Reflection with the Command Pattern

Say we’re working on an application that requires several operations to execute before a user is permitted to commit changes to a document.  We’ve encapsulated these individual requests as objects using the command pattern, which gives us a hierarchy to work with.  We’re able to use these commands individually, and with the help of reflection we can also work with them as a group.  The class hierarchy is below:

 

Our goal here should be to create a mechanism for executing these commands that is not tied directly to any of the concrete implementations.  Why do we want to do that?  Consider a scenario where we have the below code

        /// <summary>
        /// Runs every inspector command in the application
        /// </summary>
        internal void RunInspectorCommands()
        {
            ContentInspectorCommand contentCommand = new ContentInspectorCommand();
            contentCommand.Execute();

            LinkInspectorCommand linkCommand = new LinkInspectorCommand();
            linkCommand.Execute();

            MetaDataInspectorCommand metaCommand = new MetaDataInspectorCommand();
            metaCommand.Execute();
        }

This code will successfully execute all of the commands, but what happens if we want to add a new one or remove an existing one?  It’s not enough to simply add or remove a command class, we also have to come back here and update this code.  We’ve created a situation where we have to modify code whose purpose has not changed to incorporate our changes.  We’ve violated our design principle. 

A more flexible and extensible solution is to utilize reflection to accomplish this.  Take a look at the code below:

        /// <summary>
        /// Runs every inspector command in the application
        /// </summary>
        internal void RunInspectorCommands()
        {
             foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
             {
                 if (type.BaseType == typeof(InspectorCommand) &&
                     type != typeof(InspectorCommand))
                 {
                     InspectorCommand command =
                            (InspectorCommand)Activator.CreateInstance(type);

                     command.Execute();
                 }
             }
        }

Now these two parts of your application are completely decoupled.  We can add or subtract command objects and the code above will pick up the changes automatically.  It creates a design that makes people less likely to make mistakes.  It makes it easier for people to do the right thing, which is always a good practice.

This is only scratching the surface of what reflection is capable of.  Stay tuned for more posts on this topic in the future.

0

Calling WCF services using jQuery

September 21, 2010

Introduction

A couple weeks ago I was asked to start looking into the capabilites of jQuery at work.  Let’s be honest here, I was pumped about this opportunity.  There’s been lots of buz around jQuery and I’d been looking for a chance to get my hands dirty.  While the syntax can initially seem rather cryptic, it really is well worth the effort to sit down and learn it.  It’s an invaluable tool to have in your arsenal if you’re doing any type of web development work.

Doing basic stuff in jQuery is easy $(“#myDivId).appendTo(“Hello world”); .  However, I found figuring out the proper syntax for making WCF calls with complex objects a challenge.  Mostly this was because of a serious deficit of good examples.  This post is an attempt to capture what I learned for anyone who’s interested.  Here I’ll show you how to configure each piece of an Asp.Net web application to support making Ajax calls with jQuery.  Hopefully this will save you some of the headaches that I went through. 

When talking to WCF services through jQuery there are several pieces that need to fit together to make everything work:

  1. The WCF Service
  2. The Web.config
  3. The jQuery code
  4. Also any objects that will be passed around must be tagged with the proper attibutes

Say we have a basic asp.net project that looks like this:

 

The idea is we want Javascript that lives in the Default.js file to be able to talk to a WCF Service (PeopleService.svc) via jQuery.  Notice that I’ve included the jQuery and json2 javascript files as well. 

WCF Service

Starting from the bottom, the first step is properly configuring your WCF Service.  In this case I’ve seperated the service into an interface and an implementation.  Mostly this is because that’s the way that Visual Studio adds it to a project by default and I want to make this easy for people to follow.  Here’s the Interface:

using System.Collections.Generic;
using System.Net.Security;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace JPPete.Jquery.Intro.WebServices
{
    [ServiceContract(Namespace = "http://jppete.com/jquery/intro",
      Name = "IPeopleService",
      SessionMode = SessionMode.NotAllowed,
      ProtectionLevel = ProtectionLevel.None)]
    public interface IPeopleService
    {
        [OperationContract]
        [WebInvoke(
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Json)]
        string GetStatus();

        [OperationContract]
        [WebInvoke(
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Json)]
        void AddPerson(Person person);

        [OperationContract]
        [WebInvoke(
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Json)]
        void AddPeople(IList<Person> people);

        [OperationContract]
        [WebInvoke(
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Json)]
        IList<Person> GetPeople();
    }
}

The key here is adding the WebInvoke attribute to your interface methods.  This adds additional metadata to your service that tells it what to expect from callers (see documentation).  In our case we want the service to be able to interpret JSON messages.

Here is the implementation: 

using System.Collections.Generic;
using System.ServiceModel.Activation;

namespace JPPete.Jquery.Intro.WebServices
{
    [AspNetCompatibilityRequirements(
        RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class PeopleService : IPeopleService
    {
        private static List<Person> _people;
        /// <summary>
        /// List of People objects for demo purposes
        /// </summary>
        private static List<Person> People
        {
            get
            {
                if (_people == null)
                {
                    _people = new List<Person>
                      {
                          new Person
                          {
                              Age = 20,
                              FirstName = "Joe",
                              LastName = "Smith"
                          },
                          new Person
                          {
                              Age = 25,
                              FirstName = "John",
                              LastName = "Peterson"
                          },
                          new Person
                          {
                              Age = 60,
                              FirstName = "Joan",
                              LastName = "Smith"
                          }
                      };
                }
                return _people;
            }
        }

        #region IPeopleService Members

        /// <summary>
        /// Gets the status of the service
        /// </summary>
        /// <returns></returns>
        public string GetStatus()
        {
            return "Ready";
        }

        /// <summary>
        /// Adds the input person to the local collection
        /// </summary>
        /// <param name="person"></param>
        public void AddPerson(Person person)
        {
            People.Add(person);
        }

        /// <summary>
        /// Adds the input people to the local collection
        /// </summary>
        /// <param name="people"></param>
        public void AddPeople(IList<Person> people)
        {
            People.AddRange(people);
        }

        /// <summary>
        /// Gets the list of people from the service
        /// </summary>
        /// <returns></returns>
        public IList<Person> GetPeople()
        {
            return People;
        }

        #endregion
    }
}

Take note of the AspNetCompatibilityRequirements attribute.  This is essentially tagging your WCF Service as a web service that is compatible with asp.net, which opens it up to ajax requests and gives you access to HTTP Session State and several other Asp.Net features.  Keep in mind that tagging a WCF service with this attribute basically makes it behave like an asmx web service.  This means that it is available only via HTTP (see documentation ).

Web.Config

<system.serviceModel>
		<behaviors>
			<serviceBehaviors>
				<behavior name="JPPete.Jquery.Intro.WebServices.PeopleServiceBehavior">
					<serviceMetadata httpGetEnabled="true"/>
					<serviceDebug includeExceptionDetailInFaults="false"/>
				</behavior>
			</serviceBehaviors>
			<endpointBehaviors>
				<behavior name="PersonServiceEndpointBehavior">
					<webHttp/>
				</behavior>
			</endpointBehaviors>
		</behaviors>
		<services>
			<service behaviorConfiguration="JPPete.Jquery.Intro.WebServices.PeopleServiceBehavior" name="JPPete.Jquery.Intro.WebServices.PeopleService">
				<endpoint address="" binding="webHttpBinding" contract="JPPete.Jquery.Intro.WebServices.IPeopleService" behaviorConfiguration="PersonServiceEndpointBehavior">
					<identity>
						<dns value="localhost"/>
					</identity>
				</endpoint>
			</service>
		</services>
	</system.serviceModel>

 

Setting up the Web.Config for basic scenarios is pretty straightforward.  There are only a couple modifications you need to make to the default ServiceModel entries that get created automatically in Visual Studio.  First, you need to add an endpointBehavior section.  Second, you need to add a behaviorConfiguration attribute in your service>endpoint element.  Finally, you need to set the endpoint binding attribute to webHttpBinding (this works with the WebInvoke attribute we applied to the interface methods above).  Some parts of this will vary considerably based on your specifc scenario, but this should be enough to get you started.

 Calling the service with jQuery

 Where this got hairy for me was figuring out the syntax for jQuery.  Below are several examples of how you would consume these services using jQuery:

Calling GetStatus()

function getStatus() {
    //Make ajax request...
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "WebServices/PeopleService.svc/GetStatus",
        processData: false,
        dataType: "json",
        //If the call succeeds
        success:
        function(response) {
            alert(
                'Ping was successfull.  The service status is: ' + response.GetStatusResult);
        },
        //If the call fails
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.responseText);
        }
    });
}

Calling AddPerson()

function addPerson() {
    var person = {
        "person":
            {
                "FirstName": "Jane",
                "LastName": "Doe",
                "Age": 25
            }
        };

    //Make ajax request...
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "WebServices/PeopleService.svc/AddPerson",
        processData: false,
        dataType: "json",
        data: JSON.stringify(person),
        //If the call succeeds
        success:
        function(response) {
            alert('Person added successfully');
        },
        //If the call fails
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.responseText);
        }
    });
}
 

Calling AddPeople() 

function addPeople() {
    var person1 =
        {
            "FirstName": "Jane",
            "LastName": "Doe",
            "Age": 25
        };

    var person2 =
        {
            "FirstName": "John",
            "LastName": "Doe",
            "Age": 25
        };

    var people = new Array(person1, person2);

    var peopleInput = { "people": people };

    //Make ajax request...
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "WebServices/PeopleService.svc/AddPeople",
        processData: false,
        dataType: "json",
        data: JSON.stringify(peopleInput),
        //If the call succeeds
        success:
        function(response) {
            alert('People added successfully');
        },
        //If the call fails
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.responseText);
        }
    });

}

Calling GetPeople()

function getPeople() {
    //Make ajax request...
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "WebServices/PeopleService.svc/GetPeople",
        processData: false,
        dataType: "json",
        //If the call succeeds
        success:
        function(response) {
            //loop and display the results
            $.each(response.GetPeopleResult, function(i) {
                alert(
                    "FirstName: " + this.FirstName +
                    " LastName: " + this.LastName +
                    " Age: " + this.Age);
            });
        },
        //If the call fails
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.responseText);
        }
    });
}

Once you nail the sytax here everything falls into place. 

Person.cs

For those who aren’t familiar with WCF you have to tag your object with the DataContractAttribute and all of the members that you want WCF to translate with the DataMemberAttribute.

 

using System.Runtime.Serialization;

namespace JPPete.Jquery.Intro
{
    [DataContract]
    public class Person
    {
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }
        [DataMember]
        public int Age { get; set; }
    }
}
 

Hope this helps someone.  I’ll look forward to any comments or feedback.  Happy coding!

4