<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Phil Leggetter - Real-Time Web Software and Technology Evangelist &#187; ASP.NET MVC</title>
	<atom:link href="http://www.leggetter.co.uk/tag/asp-net-mvc/feed" rel="self" type="application/rss+xml" />
	<link>http://www.leggetter.co.uk</link>
	<description>Real-Time Web, Real-Time Data and Social Media Software and Technology Evangelist and Consultant</description>
	<lastBuildDate>Sun, 29 Jan 2012 05:00:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Adding a real-time &quot;Who&#8217;s shopping?&quot; widget to an ASP.NET Web App</title>
		<link>http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html</link>
		<comments>http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html#comments</comments>
		<pubDate>Thu, 04 Aug 2011 00:00:00 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[pusher]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time web]]></category>

		<guid isPermaLink="false">http://blog.pusherapp.com/2011/8/3/adding-a-real-time-who-s-shopping-widget-to-an-asp-net-web-app</guid>
		<description><![CDATA[<p>In our last ASP.NET post, <a href="http://blog.pusher.com/2011/6/25/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application">The easiest way to add real-time functionality to an ASP.NET e-commerce application</a>, I demonstrated how to add realtime stock level updates and notifications to an ASP.NET e-commerce application. In this post I&#8217;m going to show how to add a &#8220;Who&#8217;s shopping?&#8221; widget to the same application. The purpose of [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html' rel='bookmark' title='The easiest way to add real-time functionality to an ASP.NET e-commerce application'>The easiest way to add real-time functionality to an ASP.NET e-commerce application</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/17/kwwika-powered-real-time-opta-sports-cricket-widget.html' rel='bookmark' title='Kwwika Powered Real-Time Opta Sports Cricket Widget'>Kwwika Powered Real-Time Opta Sports Cricket Widget</a></li>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In our last ASP.NET post, <a  href="http://blog.pusher.com/2011/6/25/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application">The easiest way to add real-time functionality to an ASP.NET e-commerce application</a>, I demonstrated how to add realtime stock level updates and notifications to an ASP.NET e-commerce application. In this post I&#8217;m going to show how to add a &#8220;Who&#8217;s shopping?&#8221; widget to the same application. The purpose of this widget is to show other users that interest in the product they are viewing is high and that, in combination with the realtime stock levels, will encourage them to make a purchase before the product sells out.</p>
<p>In this tutorial I&#8217;ll show how to:</p>
<ul>
<li>subscribe to a presence channel</li>
<li>authenticate a subscription to a channel</li>
<li>provide Pusher with additional information about a user</li>
<li>display presence information on a product page for the &#8220;Who&#8217;s shopping?&#8221; widget</li>
</ul>
<p>If you are desperate to see the demo in action you can see the <a  href="http://realtimewebstore.apphb.com/">Real-Time Web Store demo here</a>.</p>
<h2>Pusher Presence</h2>
<p>To achieve the &#8220;Who&#8217;s shopping?&#8221; functionality I&#8217;m going to be using a feature in Pusher called <a  href="http://pusher.com/docs/client_api_guide/client_channels#subscribe-presence-channels">presence</a>. Presence provides you with additional information about a channel you are subscribed to so that you know:</p>
<ul>
<li>who is subscribed to that channel</li>
<li>when new users subscribe</li>
<li>when existing users unsubscribe (by either actually unsubscribing or navigating away from the page).</li>
</ul>
<p>We are going to have a presence channel per product so that we know who is viewing each product.</p>
<h2>User Info &amp; Authentication</h2>
<h3>Subscribing to a presence channel</h3>
<p>You subscribe to a presence channel in the same way that you do to any other channel but the name of the channel must have a <code>presence-</code> prefix. Presence channels are normal channels with two additions; authentication and presence information. With this in mind we are just going to update our application to use a presence channel.</p>
<p>The JavaScript that makes the subscription in our Razor view looks like this:</p>
<pre><code>var productId = "@Model.ProductId";
var pusher = new Pusher("APP_KEY");
var channel = pusher.subscribe("presence-" + productId);
</code></pre>
<p>We also need to update the code in our <code>StoreController</code> to publish our stock events on the new presence channel:</p>
<pre><code>var stockEvent = new StockUpdatedEvent(model, socketId);
ObjectPusherRequest request = new ObjectPusherRequest("presence-" + stockEvent.ProductId, "stockUpdated", stockEvent);
_provider.Trigger(request);
</code></pre>
<p><em>Note: If you are continuing where we left off in our last blog post there are a final couple of updates that are required to change the app to use the latest version of the Pusher JavaScript API. We recently released version 1.9 which introduced <a  href="http://blog.pusher.com/2011/7/12/connections-states">new connection state functionality</a> and also a new <code>connection</code> object. So, update your Pusher script tag as follows:</em></p>
<pre><code>&lt;script src="http://js.pusherapp.com/1.9/pusher.js"&gt;&lt;/script&gt;
</code></pre>
<p><em>And you&#8217;ll also need to update any pieces of code that access the <code>socket_id</code> via the <code>Pusher</code> instance. It should now be accessed via the new <code>connection</code> object as follows:</em></p>
<pre><code>var socketId = pusher.connection.socket_id;
</code></pre>
<h3>Getting User information</h3>
<p>If Pusher is to send events about users subscribing to and unsubscribing from presence channels it needs information about the users. It gets this information from your application when the subscription request to the channel is made (<code>pusher.subscribe('presence-channel')</code>). Since we can&#8217;t really trust the web browser/client (it&#8217;s so easy to hack JavaScript running in a web browser) the Pusher library requests this information from your web server by making an AJAX call. By default this call goes to <code>/pusher/auth</code> and passes two parameters; <code>channel_name</code>, which is the name of the channel being subscribed to, and <code>socket_id</code>, which is a unique identifier for the current user&#8217;s connection to Pusher.</p>
<pre><code>/pusher/auth/?channel_name=presence-pusher-tshirt&amp;socket_id=&lt;unique_socket_id&gt;
</code></pre>
<p>When our application responds to this request we must provide an authentication signature to confirm that the user can subscribe to the channel and, importantly for our &#8220;Who&#8217;s shopping?&#8221; widget, information about the current user. The way we&#8217;ll handle this within our ASP.NET MVC application is by creating a <code>PusherController</code> with an <code>Auth(string socket_id, string channel_name)</code> action, and by using the authentication functionality within the <a  href="https://github.com/leggetter/pusher-rest-dotnet">PusherRESTDotNet library</a>. This library is also available as a <a  href="http://nuget.org/List/Packages/PusherRESTDotNet">NuGet package</a>.</p>
<p><em>Note: If you got the NuGet package as part of the last tutorial you&#8217;ll need to update it since the authentication functionality has just been added. You should also check that the .NET 3.5 runtime version of Newtonsoft.Json is added.</em></p>
<h3>Handling the authentication request</h3>
<p>As mentioned above, the Pusher JavaScript library will make a request to <code>/pusher/auth</code> when making the authentication request. Our new <code>PusherController</code> with <code>Auth</code> action does the following:</p>
<ol>
<li>Fetches our Pusher credentials from the Web.config file.</li>
<li>Creates a new <code>PusherProvider</code> using the Pusher credentials</li>
<li>Creates a unique <code>user_id</code> for the presence channel</li>
<li>Creates an authentication string and returns that string as the <code>Content</code> of a <code>ContentResult' with the</code>ContentType<code>set to</code>application/json` in response to the AJAX request.</li>
</ol>
<p>For the moment this code doesn&#8217;t do any user authentication or provide any additional information about the current user.</p>
<pre><code>using System;
using System.Configuration;
using System.Web.Mvc;
using PusherRESTDotNet;
using PusherRESTDotNet.Authentication;

namespace RealTimeWebStore.Controllers
{
    public class PusherController : Controller
    {
        public ActionResult Auth(string channel_name, string socket_id)
        {
            var applicationId = ConfigurationManager.AppSettings["application_id"];
            var applicationKey = ConfigurationManager.AppSettings["application_key"];
            var applicationSecret = ConfigurationManager.AppSettings["application_secret"];

            var channelData = new PresenceChannelData()
            {
                user_id = Guid.NewGuid().ToString()
            };

            var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);
            string authJson = provider.Authenticate(channel_name, socket_id, channelData);

            return new ContentResult { Content = authJson, ContentType = "application/json" };
        }
    }
}
</code></pre>
<p>If we use one of the many web browser development tools available to us to inspect the authentication call within the browser we&#8217;ll see the JSON response coming back.</p>
<p><img alt="Screen+shot+2011-08-04+at+17" src="http://blog.pusher.com/media/2011/08/04/09/07/01/978/Screen+shot+2011-08-04+at+17.06.17.jpg?m=resize&amp;o%5Bgeometry%5D=500x400&amp;s=0d9d3c037a95e8d6" /></p>
<p>You&#8217;ll see the response contains a <code>channel_data</code> property which itself has a <code>user_id</code> with a unique <a  href="http://msdn.microsoft.com/en-us/library/system.guid.aspx"><code>Guid</code></a> value and a <code>user_info</code> property with a <code>null</code> value. Pusher uses this <code>user_id</code> value to uniquely identify the user subscription to the presence channel. So it&#8217;s very important to make sure that each user has a unique ID.</p>
<h3>Adding authentication</h3>
<p>We&#8217;ve mentioned authentication a few times but as yet we haven&#8217;t authenticated the user. If the user has already logged (our app doesn&#8217;t have this functionality, but most do) in we can use the existing <code>User.Identity</code> or else we can just assign a guest identity to the user. Once we have a unique ID for the user we&#8217;ll also add some additional <code>user_info</code> to the <code>channelData</code>. The value of <code>user_info</code> can be anything you like from a simple string to a complex object. This gives you the ability to push as much additional information through Pusher and to the web page as you like. In our case we&#8217;ll just send through a timestamp which identifies how long the user has been on the site.</p>
<pre><code>public ActionResult Auth(string channel_name, string socket_id)
{
    var channelData = new PresenceChannelData();
    if (User.Identity.IsAuthenticated)
    {
        channelData.user_id = User.Identity.Name;
    }
    else
    {
        channelData.user_id = GetUniqueUserId();
    }
    channelData.user_info = GetUserInfo();

    var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);
    string authJson = provider.Authenticate(channel_name, socket_id, channelData);

    return new ContentResult { Content = authJson, ContentType = "application/json" };
}
</code></pre>
<p><em>Note: In our case we don&#8217;t really need to authorise a user but in other situations where the user needs to be logged in we can return a 401  <a  href="http://msdn.microsoft.com/en-us/library/system.web.mvc.httpstatuscoderesult(v=vs.98).aspx?ppud=4"><code>HttpStatusCodeResult</code></a>.</em></p>
<h2>Who&#8217;s Shopping?</h2>
<p>Now that we&#8217;ve got a <code>PusherController</code> that gives Pusher information about the user, we can start showing information about the user on the product page. You can get information about the users subscribed to presence channels by binding to the <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#pusher-subscription-succeeded"><code>pusher:subscription_succeeded</code></a> event on the presence channel object. The callback method for this event receives a <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#members-parameter"><code>members</code></a> parameter which contains all the information about users subscribed to the channel.</p>
<p>First we&#8217;ll create some HTML within our web page where we are going to show &#8220;Who&#8217;s shopping?&#8221;. Then we&#8217;ll add the users to the HTML when pusher notifies us of them.</p>
<p><strong>HTML</strong></p>
<pre><code>&lt;div class="whos-shopping"&gt;
    &lt;h3&gt;Who's shopping?&lt;/h3&gt;
    &lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
</code></pre>
<p><strong>JavaScript</strong></p>
<pre><code>var pusher = new Pusher("006c79b1fe1700c6c10d");
var channel = pusher.subscribe("presence-" + productId);
channel.bind("pusher:subscription_succeeded", function(members) {

    members.each(function(member) {
        addMember(member);
    });

});

function addMember(member) {
    var enteredSite = new Date(member.info.timestamp);
    var now = new Date();
    var timeOnSite = (now - enteredSite);
    var li = $("&lt;li data-user-id='" + member.id + "'&gt;" +
                    member.id + " here for " +
                    toReadableTime(timeOnSite) +
               "&lt;/li&gt;");
    $(".whos-shopping ul").append(li);
};
</code></pre>
<p><em>Note: The <code>members</code> object comes with a handy <code>each</code> method to make iterating the members collection really easy.</em></p>
<p>Of course new users can navigate to the page and existing users can leave it so the Pusher JavaScript library also exposes <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#pusher-member-added"><code>pusher:member_added</code></a> and <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#pusher-member-removed"><code>pusher:member_removed</code></a> events on the presence channel object. When these events fire we should add or remove the user as required.</p>
<pre><code>channel.bind("pusher:member_added", function(member) {
    addMember(member);
});
channel.bind("pusher:member_removed", function(member) {
    removeMember(member);
});

function addMember(member) {
    /* as before */
};

function removeMember(member) {
    $(".whos-shopping ul li[data-user-id='" + member.id + "']").remove();
};
</code></pre>
<p>With this in place we now have a fully functioning &#8220;Who&#8217;s shopping?&#8221; widget that shows the current user who else is viewing the same product as they are.</p>
<p><img alt="Screen+shot+2011-08-03+at+21" src="http://blog.pusher.com/media/2011/08/03/13/19/53/544/Screen+shot+2011-08-03+at+21.10.42.jpg?m=resize&amp;o%5Bgeometry%5D=500x400&amp;s=ee8762b09260ca71" /></p>
<p>As mentioned in the opening paragraph, the theory here is that if shoppers can see that others users are viewing the same product it might give them that little push they need to take the plunge and make that purchase &#8220;while stocks last&#8221;.</p>
<p>There are a few refinements and enhancements that could be made to this widget such as filtering out the current user from the &#8220;Who&#8217;s shopping?&#8221; list or possibly showing them which one they are. You could also use the notification system from last time to notify the shopper when another shopper joins or leaves the product page. And, of course, you could add some user chat functionality to get the users discussing the product and really engaging. You could also have a staff member user who could answer any questions that the shoppers may have.</p>
<p>Just as last time all the code from this post is available in the <a  href="https://github.com/leggetter/realtime-webstore">real-time web store github repo</a>. You can also see the <a  href="http://realtimewebstore.apphb.com/">Real-Time Web Store application up and running</a> on <a  href="https://appharbor.com/">AppHarbor</a>. I&#8217;ve tried to link to relevant parts of the <a  href="http://pusher.com/docs">Pusher documentation</a> throughout the post but if there anything that isn&#8217;t clear, if there&#8217;s anything that I&#8217;ve not provided enough detail on and it all just seems too <em>&#8216;magical&#8217;</em>, then please leave a comment or send an email to me (<a  href="mailto:phil@pusher.com?subject=ASP.NET%20real-time%20web%20store">phil@pusher.com</a>).</p>
<p>Here are some links to the key things covered in this post:</p>
<ul>
<li><a  href="http://pusher.com/docs/presence">Presence channels</a></li>
<li><a  href="http://pusher.com/docs/client_api_guide/client_presence_events">Presence channel events</a></li>
<li><a  href="http://pusher.com/docs/authenticating_users">Authenticating Users</a></li>
<li><a  href="http://pusher.com/docs/rest_libraries#cs">Pusher REST .NET Library</a> | <a  href="http://nuget.org/List/Packages/PusherRESTDotNet">NuGet package</a></li>
<li><a  href="https://github.com/leggetter/realtime-webstore">ASP.NET real-time web store in github</a></li>
<li><a  href="http://realtimewebstore.apphb.com/">Real-Time Web Store application up and running</a></li>
<li><a  href="http://www.asp.net/mvc/mvc3">ASP.NET MVC 3</a></li>
</ul>
<h2>Addendum: What about WebForms?</h2>
<p>The post above shows how to user the Pusher REST .NET library within an ASP.NET MVC application but it can just as easily be used within an ASP.NET WebForms app. The way I achieved this was by adding a new Generic HTTP Handler to our web app which will handle the authentication AJAX call.</p>
<p><img alt="Screen+shot+2011-08-02+at+16" src="http://blog.pusher.com/media/2011/08/03/13/22/53/682/Screen+shot+2011-08-02+at+16.07.19.jpg?m=resize&amp;o%5Bgeometry%5D=500x400&amp;s=8b9774ad1cdd29ca" /></p>
<p>In the code below the <code>ProcessRequest</code> method does the following things:</p>
<ol>
<li>Fetches our Pusher credentials from the Web.config file.</li>
<li>Gets the values of the <code>channel_name</code> and <code>socket_id</code> parameters from the <code>context.Request</code></li>
<li>Creates a new <code>PusherProvider</code> using the Pusher credentials</li>
<li>Creates a unique <code>user_id</code> for the presence channel</li>
<li>Creates an authentication string and returns that string as the response body of the AJAX request.</li>
</ol>
<p>For the moment this code doesn&#8217;t do any user authentication or provide any additional information about the current user.</p>
<pre><code>using System.Configuration;
using System.Web;
using PusherRESTDotNet;
using PusherRESTDotNet.Authentication;
using System;

namespace RealTimeWebStore
{
    public class AuthHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            var applicationId = ConfigurationManager.AppSettings["pusher-application-id"];
            var applicationKey = ConfigurationManager.AppSettings["pusher-application-key"];
            var applicationSecret = ConfigurationManager.AppSettings["pusher-application-secret"];

            var socketID = context.Request["socket_id"].ToString();
            var channelName = context.Request["channel_name"].ToString();
            var channelData = new PresenceChannelData()
            {
                user_id = Guid.NewGuid().ToString()
            };

            var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);
            string authJson = provider.Authenticate(channelName, socketId,  channelData);

            context.Response.Write(authJson);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
</code></pre>
<p>Finally we need to configure our handler in the application <code>Web.config</code> file. We want the <code>ProcessRequest</code> method of our handler to be invoked for any call to <code>/pusher/auth</code>. To do this we just add a handler to the <code>httpHandlers</code> element and specify our handler, <code>RealTimeWebStore.AuthHandler</code> as the handler:</p>
<pre><code>&lt;system.web&gt;
  &lt;!-- other config --&gt;
  &lt;httpHandlers&gt;
    &lt;add verb="*"
         path="/pusher/auth/"
         type="RealTimeWebStore.AuthHandler" /&gt;
  &lt;/httpHandlers&gt;
&lt;/system.web&gt;
</code></pre>
<p><script>
var div = $("
<div/>")
.css({
"text-align":"center",
"margin":"auto",
"margin-bottom":"10px"
});
$(".entrybody img")
.css({
"-moz-border-radius": "4px", 
"-webkit-border-radius": "4px", 
"-o-border-radius": "4px", 
"-ms-border-radius": "4px", 
"-khtml-border-radius": "4px", 
"border-radius": "4px", 
"border": "1px solid #DEDEDE", 
"padding": "4px"})
.wrap(div);
</script></p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html' rel='bookmark' title='The easiest way to add real-time functionality to an ASP.NET e-commerce application'>The easiest way to add real-time functionality to an ASP.NET e-commerce application</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/17/kwwika-powered-real-time-opta-sports-cricket-widget.html' rel='bookmark' title='Kwwika Powered Real-Time Opta Sports Cricket Widget'>Kwwika Powered Real-Time Opta Sports Cricket Widget</a></li>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking for a C# (ASP.NET MVC), jQuery &amp; Real-Time Web Contractor</title>
		<link>http://www.leggetter.co.uk/2011/03/23/looking-for-a-c-javascript-real-time-web-contractor.html</link>
		<comments>http://www.leggetter.co.uk/2011/03/23/looking-for-a-c-javascript-real-time-web-contractor.html#comments</comments>
		<pubDate>Wed, 23 Mar 2011 09:45:04 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Job]]></category>
		<category><![CDATA[Jobs]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[real-time data]]></category>
		<category><![CDATA[real-time web]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://leggetter.posterous.com/looking-for-a-c-javascript-real-time-web-cont</guid>
		<description><![CDATA[        
	I&#039;m very hopeful that I&#039;ll be looking to hire a contractor very soon and I thought I would post this to get a feeling for who is out there and interested. The skills I&#039;m looking for are as follows:EssentialC#Advanced JavaScriptTD...
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/01/31/drag-drop-bug-in-jquery-ui-153.html' rel='bookmark' title='Drag Drop bug in JQuery UI 1.5.3'>Drag Drop bug in JQuery UI 1.5.3</a></li>
<li><a href='http://www.leggetter.co.uk/2009/10/29/real-time-rich-internet-applications-rtria.html' rel='bookmark' title='Real-Time Rich Internet Applications (RTRIA)'>Real-Time Rich Internet Applications (RTRIA)</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/20/the-real-time-web-techmeetup-aberdeen-19012011.html' rel='bookmark' title='The Real-Time Web: TechMeetup Aberdeen &#8211; 19/01/2011'>The Real-Time Web: TechMeetup Aberdeen &#8211; 19/01/2011</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m looking for a contractor for a provisional 3 month contract with the following skills, experience and interests:</p>
<p><strong>Essential</strong></p>
<ul>
<li>C#</li>
<li>jQuery</li>
<li>TDD/BDD</li>
<li>ASP.NET MVC</li>
<li>ADO.NET Entity Framework or other ORM</li>
</ul>
<p><strong>Great to have</strong></p>
<ul>
<li>Passionate about the real-time web and real-time data (essential for the longer term)</li>
<li>Knowledge of building scalable systems on Amazon Infrastructure</li>
<li>Experience of integrating with 3rd party payment systems and building basic ecommerce functionality</li>
<li>Experience of building a SaaS or IaaS offering</li>
<li>Interest/experience in API and Web Service development</li>
<li>Advanced JavaScript</li>
<li>CSS</li>
<li>Excited about HTML5</li>
<li>Part of a tech community</li>
</ul>
<p><strong>Location</strong></p>
<p>The role will be primarily home-based but at times we may need to meet around 2 to 3 times a week at a location that we agree on anywhere between or around Dundee and Edinburgh.</p>
<p>Moving forward I&#8217;m hopeful that this could develop into a fulltime role so it would be ideal if we could get somebody who was interested in this also.</p>
<p>If you are interested please <a  href="mailto:phil@kwwika.com">get in touch</a>&nbsp;with&nbsp;your availability and your rate.</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/01/31/drag-drop-bug-in-jquery-ui-153.html' rel='bookmark' title='Drag Drop bug in JQuery UI 1.5.3'>Drag Drop bug in JQuery UI 1.5.3</a></li>
<li><a href='http://www.leggetter.co.uk/2009/10/29/real-time-rich-internet-applications-rtria.html' rel='bookmark' title='Real-Time Rich Internet Applications (RTRIA)'>Real-Time Rich Internet Applications (RTRIA)</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/20/the-real-time-web-techmeetup-aberdeen-19012011.html' rel='bookmark' title='The Real-Time Web: TechMeetup Aberdeen &#8211; 19/01/2011'>The Real-Time Web: TechMeetup Aberdeen &#8211; 19/01/2011</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/03/23/looking-for-a-c-javascript-real-time-web-contractor.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Master does not have a definition for ViewData (ASP.NET MVC2)</title>
		<link>http://www.leggetter.co.uk/2010/08/04/master-does-not-have-a-definition-for-viewdata-asp-net-mvc2.html</link>
		<comments>http://www.leggetter.co.uk/2010/08/04/master-does-not-have-a-definition-for-viewdata-asp-net-mvc2.html#comments</comments>
		<pubDate>Wed, 04 Aug 2010 11:05:28 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Microsoft]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=1126</guid>
		<description><![CDATA[<p>I&#8217;m building an ASP.NET MVC2 web application and I was trying to access ViewData in my Site.Master page and I kept getting &#8220;master does not have a definition for ViewData&#8221;.</p> <p>The simple answer was that my Master Page was not an ASP.NET MVC2 master page. Somehow I had a standard master page.</p> <p>So, all I [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/07/09/wikipedia-now-has-a-definition-for-real-time-web.html' rel='bookmark' title='Wikipedia now has a definition for Real-Time Web'>Wikipedia now has a definition for Real-Time Web</a></li>
<li><a href='http://www.leggetter.co.uk/2010/03/12/making-cross-domain-javascript-requests-using-xmlhttprequest-or-xdomainrequest.html' rel='bookmark' title='Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest'>Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest</a></li>
<li><a href='http://www.leggetter.co.uk/2010/04/02/defining-the-kwwika-api.html' rel='bookmark' title='Defining the Kwwika API'>Defining the Kwwika API</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m building an ASP.NET MVC2 web application and I was trying to access ViewData in my Site.Master page and I kept getting &#8220;master does not have a definition for ViewData&#8221;.</p>
<pre class="brush: xml; title: ; notranslate">&lt;%= ViewData[&quot;topic&quot;] %&gt;</pre>
<p>The simple answer was that my Master Page was not an ASP.NET MVC2 master page. Somehow I had a standard master page.</p>
<p>So, all I did was swap the existing page declaration</p>
<pre class="brush: xml; title: ; notranslate">&lt;%@ Master Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeBehind=&quot;Site.Master.cs&quot; Inherits=&quot;HubSubscriber.Views.Shared.Site&quot; %&gt;</pre>
<p>With an ASP.NET MVC2 declaration:</p>
<pre class="brush: xml; title: ; notranslate">&lt;%@ Master Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewMasterPage&quot; %&gt;</pre>
<p>And bingo! ViewData was now accessible from my master page.</p>
<p>This post on <a  href="http://www.asp.net/mvc/tutorials/passing-data-to-view-master-pages-cs">Passing Data to View Master Pages</a> may also be useful.</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/07/09/wikipedia-now-has-a-definition-for-real-time-web.html' rel='bookmark' title='Wikipedia now has a definition for Real-Time Web'>Wikipedia now has a definition for Real-Time Web</a></li>
<li><a href='http://www.leggetter.co.uk/2010/03/12/making-cross-domain-javascript-requests-using-xmlhttprequest-or-xdomainrequest.html' rel='bookmark' title='Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest'>Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest</a></li>
<li><a href='http://www.leggetter.co.uk/2010/04/02/defining-the-kwwika-api.html' rel='bookmark' title='Defining the Kwwika API'>Defining the Kwwika API</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2010/08/04/master-does-not-have-a-definition-for-viewdata-asp-net-mvc2.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Windows Azure &#8211; 503 Service Unavailable</title>
		<link>http://www.leggetter.co.uk/2009/08/28/windows-azure-503-service-unavailable.html</link>
		<comments>http://www.leggetter.co.uk/2009/08/28/windows-azure-503-service-unavailable.html#comments</comments>
		<pubDate>Thu, 27 Aug 2009 23:44:57 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Windows Azure]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=271</guid>
		<description><![CDATA[<p>I finally got around to trying out ASP.NET MVC and while I was at it I thought I&#8217;d also give Windows Azure a whirl. Windows Azure doesn&#8217;t support ASP.NET MVC out of the box but Jim over on MSDN Blogs has written up the details of how to get <a href="http://blogs.msdn.com/jnak/archive/2008/10/28/asp-net-mvc-projects-running-on-windows-azure.aspx">ASP.Net MVC Projects running on Windows [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/10/06/response-redirect-in-windows-azure.html' rel='bookmark' title='Response.Redirect in Windows Azure'>Response.Redirect in Windows Azure</a></li>
<li><a href='http://www.leggetter.co.uk/2008/05/20/how-to-install-caplin-systems-liberator-free-edition-on-windows.html' rel='bookmark' title='How to install Caplin Systems&#8217; Liberator Free Edition on Windows'>How to install Caplin Systems&#8217; Liberator Free Edition on Windows</a></li>
<li><a href='http://www.leggetter.co.uk/2007/02/02/get-windows-temporary-directory.html' rel='bookmark' title='C# &#8211; Get Windows Temporary Directory'>C# &#8211; Get Windows Temporary Directory</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I finally got around to trying out ASP.NET MVC and while I was at it I thought I&#8217;d also give Windows Azure a whirl. Windows Azure doesn&#8217;t support ASP.NET MVC out of the box but Jim over on MSDN Blogs has written up the details of how to get <a  href="http://blogs.msdn.com/jnak/archive/2008/10/28/asp-net-mvc-projects-running-on-windows-azure.aspx">ASP.Net MVC Projects running on Windows Azure</a>.</p>
<h3>Problem</h3>
<p>So, I followed the instruction from the blog and uploaded the package and configuration file, waited for the staging application to get into a runnable state, and clicked on the staging link&#8230;</p>
<blockquote><p>Windows Azure &#8211; 503 Service Unavailable</p></blockquote>
<p>Clearly not a good thing! In addition to this error I occasionally got a random network error or a full-on connection error reported by the browser.</p>
<p>I tried googling for this error but there was nothing about this problem after deploying to the real Windows Azure hosting (the cloud). As far as I can tell there&#8217;s no way of getting any debug information or logs to work out what&#8217;s going wrong. Maybe this is something that Microsoft will add later on?</p>
<h3>Solution</h3>
<p>Then it struck me that I hadn&#8217;t actually set up any kind of TableStorage on my Windows Azure hosting so I removed all mentions of storage and database connections from the MVC application. This included editing Web.config and removing the following.</p>
<ul>
<li>The &lt;section name=&#8221;authenticationService&#8221; type=&#8221;System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&#8243; requirePermission=&#8221;false&#8221; allowDefinition=&#8221;MachineToApplication&#8221; /&gt; section element.</li>
<li>The &lt;connectionStrings&gt; element</li>
<li>The &lt;membership&gt;element</li>
<li>The &lt;authentication mode=&#8221;Forms&#8221;&gt; element</li>
<li>The &lt;profile&gt; element</li>
<li>The &lt;roleManager&gt;element</li>
</ul>
<p><strong><em>Update: I&#8217;ve found that without the &lt;authentication&gt;element I started getting the error below so you may want to instead replace it with :</em></strong></p>
<blockquote><p>CCT: Role instances did not start within the time allowed.  Please try again.  If you continue to encounter this behavior please try shutting down the Development Fabric.</p></blockquote>
<p>I&#8217;m guessing that not all of these elements actually need to be removed but doing so resulted in the MVC ASP.NET application working in Windows Azure.</p>
<p><strong><em>Update 2: ServiceDefinition.csdef</em></strong></p>
<p>If you happen to get network timeouts or 404 network connection issues it&#8217;s worth checking your ServiceDefinition.csdef to make sure that you&#8217;ve got port 80 configured. I noticed that mine had updated to port 8080 so obviously I couldn&#8217;t access the staging site on port 80 like I was trying. If you do have the port set to something else other than port 80 you can use that port to access your application but the ServiceDefinition.csdef does have a comment in there telling you your application should be on port 80 so you are probably best to stick with that.</p>
<blockquote><p>&lt;!&#8211; Must use port 80 for http and port 443 for https when running in the cloud &#8211;&gt;<br />
&lt;InputEndpoint name=&#8221;HttpIn&#8221; protocol=&#8221;http&#8221; port=&#8221;80&#8243; /&gt;</p></blockquote>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/10/06/response-redirect-in-windows-azure.html' rel='bookmark' title='Response.Redirect in Windows Azure'>Response.Redirect in Windows Azure</a></li>
<li><a href='http://www.leggetter.co.uk/2008/05/20/how-to-install-caplin-systems-liberator-free-edition-on-windows.html' rel='bookmark' title='How to install Caplin Systems&#8217; Liberator Free Edition on Windows'>How to install Caplin Systems&#8217; Liberator Free Edition on Windows</a></li>
<li><a href='http://www.leggetter.co.uk/2007/02/02/get-windows-temporary-directory.html' rel='bookmark' title='C# &#8211; Get Windows Temporary Directory'>C# &#8211; Get Windows Temporary Directory</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2009/08/28/windows-azure-503-service-unavailable.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>System.Security.SecurityException: That assembly does not allow partially trusted callers</title>
		<link>http://www.leggetter.co.uk/2009/08/26/system-security-securityexception-that-assembly-does-not-allow-partially-trusted-callers.html</link>
		<comments>http://www.leggetter.co.uk/2009/08/26/system-security-securityexception-that-assembly-does-not-allow-partially-trusted-callers.html#comments</comments>
		<pubDate>Tue, 25 Aug 2009 23:51:12 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[C# Snippets]]></category>
		<category><![CDATA[Windows Azure]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=268</guid>
		<description><![CDATA[<p>I was writing a Windows Azure ASP.NET MVC application and when making a call to a page I received the following exception:</p> <p>System.Security.SecurityException: That assembly does not allow partially trusted callers</p> <p>In my application I&#8217;m using <a href="http://www.castleproject.org/container/index.html">Castle Windsor</a> for dependency injection and when trying to resolve a service using:</p> } <p>IGravatar gravatar = MvcApplication.Container.Resolve&#60;IGravatar&#62;();</p> [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/08/28/windows-azure-503-service-unavailable.html' rel='bookmark' title='Windows Azure &#8211; 503 Service Unavailable'>Windows Azure &#8211; 503 Service Unavailable</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I was writing a Windows Azure ASP.NET MVC application and when making a call to a page I received the following exception:</p>
<blockquote><p>System.Security.SecurityException: That assembly does not allow partially trusted callers</p></blockquote>
<p>In my application I&#8217;m using <a  href="http://www.castleproject.org/container/index.html">Castle Windsor</a> for dependency injection and when trying to resolve a service using:</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">}</div>
<blockquote><p>IGravatar gravatar = MvcApplication.Container.Resolve&lt;IGravatar&gt;();</p></blockquote>
<p>I received this message. To solve things I needed to update the WebRole element in the ServiceDefinitions.csdef file so that enableNativeCodeExecution is enabled.</p>
<blockquote><p>&lt;WebRole name=&#8221;TwitterGravatarMVC&#8221; enableNativeCodeExecution=&#8221;true&#8221;&gt;</p></blockquote>
<p>I found <a  href="http://social.msdn.microsoft.com/Forums/en-US/netservices/thread/c2e49731-9e72-49b6-9fb3-1243c85b265d">the solution</a>, detailed above, on the<a  href="http://social.msdn.microsoft.com/Forums/en-US/netservices/thread/c2e49731-9e72-49b6-9fb3-1243c85b265d"> Azure Services Platform Developer Centre forum</a>.</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2009/08/28/windows-azure-503-service-unavailable.html' rel='bookmark' title='Windows Azure &#8211; 503 Service Unavailable'>Windows Azure &#8211; 503 Service Unavailable</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2009/08/26/system-security-securityexception-that-assembly-does-not-allow-partially-trusted-callers.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced
Database Caching 22/78 queries in 0.045 seconds using disk: basic

Served from: www.leggetter.co.uk @ 2012-02-04 20:39:12 -->
