Introduction
One of the article's goals is introduction of OpenSocial to ASP.NET developers. I hope it can help you to answer the questions like "how I can build my own social network using ASP.NET" or "how to provide the way to extend my ASP.NET site by third-party developers". The second goal is introducing of my custom implementation of OpenSocial specification.
What is OpenSocial?
OpenSocial is a specification that defines a browser-based component model, known as gadgets, and an API for accessing information about user profile information and social graphs, including friends and activities. Applications that use the OpenSocial APIs can be embedded within a social network itself, or access a site’s social data from anywhere on the web. [Sources: Wikipedia and Opensocial.org]
Here’s another definition: At it’s most simplified, OpenSocial is able to offer up bits of user interface from one application, while embedding them in another application, exchanging information along with it. [1]
Specification is available here.
Major versions:
- Version 1.0 - November, 2007
- Version 2.0 – August, 2011
OpenSocial 2.0 Features:
List of existing implementations of opensocial containers can be found here. The most known of them are:
- Orkut
- MySpace
- Jira
- Confluence
- Jive SBS
Exisiting opensource implementations
Apache Shindig
Apache Shindig is a container for hosting social application consisting of four parts:
- Gadget Container JavaScript: core JavaScript foundation for general gadget functionality (read more about gadget functionality). This JavaScript manages security, communication, UI layout, and feature extensions, such as the OpenSocial API.
- Gadget Rendering Server: used to render the gadget XML into JavaScript and HTML for the container to expose via the container JavaScript.
- OpenSocial Container JavaScript: JavaScript environment that sits on top of the Gadget Container JavaScript and provides OpenSocial specific functionality (profiles, friends, activities, datastore).
- OpenSocial Data Server: an implementation of the server interface to container-specific information, including the OpenSocial REST APIs, with clear extension points so others can
Apache Shindig is the reference implementation of OpenSocial API specifications, versions 1.0.x and 2.0.x, a standard set of Social Network APIs which includes:
- Profiles
- Relationships
- Activities
- Shared applications
- Authentication
- Authorization
There are two implementation of Shindig available:
What’s about .NET implementation?
Unfortunately, there are no production ready .NET implementations. See this question at stackoverflow. Briefly, there are few existing implementation and all of the are out of date and cannot be easily integrated into existing ASP.NET applications.
- Negroni: render engine
- Pesta: line by line port of java version of shindig
How does OpenSocial gadget look like?
OpenSocial Gadgets - simple HTML and JavaScript applications that can be embedded in webpages and other apps. Gadgets are developed using the OpenSocial Gadgets API and basic web technologies such as XML, JavaScript, Flash. Typical gadget can look like the picture below:
Description contains various information about gadget, e.g.:
- Author
- Title
- Thumbnail icon
This information can be used by container.
Locale element specifies the locales, or regional language types, supported within the gadget. There may be many Locale nodes within a single gadget if it supports many
international countries and languages.
Require (must include) and Optional (may include if available) elements denote feature dependencies to be made available to a gadget. A Feature is a set of processing instructions and JavaScript libraries that provides some specific functionality for a gadget. Examples:
- pubsub - allows your gadget to publish and subscribe to message channels
- rpc - provides operations for making remote procedure calls for gadget-to-container, container-to-gadget, and gadget-to-gadget communication.
- oauthpopup - manages popup windows for OAuth
- dynamic-height - gives a gadget the ability to resize itself
UserPref represents user-specific preferences for gadget
Content section contains the run time portion of the gadget – view. The view consists of HTML, CSS and Javascrip. Different views have different characteristics. For example, a container might have a view that shows gadgets in a small format, and a view that shows gadgets in full page format. There are exmples:
- default — the standard view of a gadget, displayed in a small box on the page, possibly with other gadgets.
- canvas — the maximised view of a gadget when displayed by itself on the page.
OpenSocial gadget examples
Render friends with templating and pipelining
This example demonstrates how to render friend list using opensocial templating and data pipelining.
="1.0"="UTF-8"
<Module>
<ModulePrefs title="Catpic.Host profile">
<Require feature="opensocial-templates"/>
<Require feature="opensocial-1.0"/>
<Require feature="opensocial-data" />
</ModulePrefs>
<Content type="html">
<![CDATA[
</Content>
</Module>
The gadget causes the following request and response in browser:
Request
POST http:
Host: catpic.apphb.com
Content-Type: application/json
[{"method":"people.get","params":{"userId":["@viewer"]{"groupId":"@friends","count":20,"sortBy":"topFriends","filterBy":"all","fields":["id","name","thumbnailUrl","id","displayName"]},"id":"viewerFriends"}]
Response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
[{"result":{"startIndex":0,"itemsPerPage":20,"totalResults":3,"filtered":true,"sorted":false,"updatedSince":true,"list":[{"id":"jane.doe","name":{"givenName":"Jane","familyName":"Doe","formatted":"Jane Doe"},"thumbnailUrl":"/Content/Social/Avatars/jane.doe.jpg","displayName":"Janey"},{"id":"george.doe","name":{"givenName":"George","familyName":"Doe","formatted":"George Doe"},"thumbnailUrl":"/Content/Social/Avatars/george.doe.jpg","displayName":"Georgey"},{"id":"maija.m","name":{"givenName":"Maija","familyName":"Meikäläinen","formatted":"Maija Meikäläinen"},"thumbnailUrl":"/Content/Social/Avatars/maija.m.jpg","displayName":"Maija"}]{,"id":"viewerFriends"}]
The same result can be achieved by REST protocol:
http:
Also RPC/REST protocols support paging, sorting and filtration.
Render activities using OSAPI
This short example demonstrates how to render friend's activities using osapi.
<script type="text/javascript">
function render(templateName, targetName, result ){
var template = opensocial.template.getTemplate(templateName);
var target = document.getElementById(targetName);
template.renderInto(target, result);
}
function getActivities(groupId){
osapi.activities.get({userId:"@viewer", groupId:groupId}).execute(function(result){
render("gadget:activities","activities", result);
$('#nav2').animate({left:'60px'}, 500);
});
}
function getCollections(){
var result = {"list":[{"id":"@self","title":"My activities"},{"id":"@friends","title":"Friend's activities"}]};
var nav2 = $('#nav2-items');
nav2.empty();
$.each(result.list, function(i, val){
var str = '<div class="nav2-item" collectionid="'+ val.id +'"><span>'+ val.title.toLowerCase() +'</span></div>'
nav2.append(str);
});
$('#nav2-back').click(function(){
$('#activities').empty();
renderCollections(result);
});
renderCollections(result);
}
function renderCollections(result){
render("gadget:collections", "collections",result);
$('.msg-collection, .nav2-item').click(function(){
$('#collections').empty();
var collectionId = $(this).attr("collectionid");
getActivities(collectionId);
});
}
gadgets.util.registerOnLoadHandler(getCollections);
</script>
<script type="text/os-template" tag="gadget:collections" xmlns:gadget="http://catpic.apphb.com/social">
<div>
<div class="msg-collection" repeat="${list}" collectionid="${Cur.id}">
<div class="activity-icon">
<img src="http://www.codeproject.com/Content/social/avatars/folder.png" />
</div>
<div class="msg-collection-title">${Cur.title}</div>
<div class="msg-collection-total">5 new</div>
</div>
</div>
</script>
<script type="text/os-template" tag="gadget:activities" xmlns:gadget="http://catpic.apphb.com/social">
<div>
<div class="activity-entry" repeat="${list}" >
<div class="activity-icon">
<img src="http://www.codeproject.com/Content/social/avatars/activity.png" />
<div class="activity-user">${Cur.userId}</div>
</div>
<div class="activity">
<div class="activity-title">${Cur.title}</div>
<div class="activity-text">${Cur.body}</div>
<div class="activity-streamTitle">${Cur.streamTitle}</div>
<div class="activity-date">10 hours ago</div>
</div>
<div repeat="${Cur.mediaItems}" var="mediaItem">
<div class="activity-image" if="${mediaItem.type == 'image'}">
<a href="${mediaItem.url}"><img src="${mediaItem.url}" /></a>
</div>
</div>
<br style="clear:both" />
</div>
</div>
</script>
<div id="collections"></div>
<div id="activities"></div>
More examples and information are available here.
Explore opensocial with ASP.NET and Catpic
Catpic is OpenSocial Container for .NET developers that provides extensible component hosting environment and social facilities to existing .NET applications using best practices. It is OpenSource project which is open for participation. In general, Catpic uses Shindig's client-side code and consists of the following parts:
- OpenSocial Container: implementation of the public specification that defines a component hosting environment (container) and a set of common application programming interfaces (APIs) for social networking web-based applications
- Gadget Container JavaScript: core JavaScript foundation for general gadget functionality. This JavaScript manages security, communication, UI layout, and feature extensions. Apache Shindig implementation is used by default.
- Gadget Rendering Server: used to render the gadget XML into JavaScript and HTML for the container to expose via the container JavaScript. This part is written on .NET and common modules can be replaced/extended by custom ones.
Catpic provides:
- OpenSocial container: people, activities, activity streams, messages
- implementation of core gadgets specification
- ability to host platform-independed components - gadgets
- fully .NET implementation on server side
- extensibility by custom modules
- simple integration into existing ASP.NET/ ASP.NET MVC application via NuGet package
Example application
Create ASP.NET MVC3 application from default template and install catpic using nuget package:
PM> Install-Package Catpic
After this, application dependency graph should be the following:
Some notes:
- Catpic depends on ASP.NET WebAPI, Json.NET and HtmlAgillitypack libraries
- EntityFramework library is required by Catpic.Data.EntityFramework library which uses Code First approach of EF to store information into MS SQL Server. You can safely remove it if you want to implement your custom implementation of data layer. Example site uses static json file by default.
- The easiest way to use catpic is usage of dependency injection containers. Nuget package provides default classes which use Unity as DI container. If you want to use different DI, just provide your implementation of Catpic.Web.Configuration.IHostContainer interface
The next step is registration of Catpic at Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterCatpic();
RegisterRoutes(RouteTable.Routes);
}
private void RegisterCatpic()
{
var container = new Microsoft.Practices.Unity.UnityContainer();
YourApp.HostConfigurator.Configure(container);
var unityResolver = new YourApp.UnityDependencyResolver(container);
DependencyResolver.SetResolver(unityResolver);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = unityResolver;
Catpic.Web.Configuration.CatpicConfigurator.ConfigureRoutes(System.Web.Http.GlobalConfiguration.Configuration, RouteTable.Routes);
Catpic.Web.Configuration.CatpicConfigurator.ConfigureFormatters(System.Web.Http.GlobalConfiguration.Configuration);
}
Add gadget to view
Open index view of Home controller and add the following content:
This example demonstrate how to render gadget using shindig client-side API. Result:
You can use different approach to render gadgets: just create iframe with src:
http:
Where
gadget_url - gadget’s url
Render OpenSocial gadgets
Demo application uses fake repository of shindig: canonicaldb.json file. Currently Catpic provides the implementation of repositories for people, messages, activitystreams services by Catpic.Data.EntityFramework library which contains logic to store social data into MS SQL Service database using Code First approach of EntityFramework.
Here are short examples:
User profile
User's friends
Catpic demo site
Example above demonstrates only few aspects of catpic implementation of opensocial container. You can checkout Catpic sources and explore more. It is available here:
http://catpic.codeplex.com
Continuous integration site is located at app harbor: http://catpic.apphb.com. It demonstrates various aspects of Catpic usage.
Specification compliance
What is done from specification point of view:
- Implemented essential parts of Core Gadget Spec:
- Features
- Views
- Preload (without authz)
- User preferences
- Signed requests (OAuth 1.0a / OAuth2)
- Locale
- Implemented social services of Social API Server Spec:
- People
- Activities (deprecated since opensocial 2.0)
- Activity Streams
- Messages
- RPC/REST protocols are supported
However, there a lot of work should be done before the full specification is supported. For example:
OpenSocial Books
Links
Interested in design/development of framework functionality using the best patterns and practices.