<?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>binoot!binoot!</title>
	<atom:link href="http://www.binoot.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.binoot.com</link>
	<description>technology, life, etc.</description>
	<lastBuildDate>Tue, 23 Apr 2013 03:13:22 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Integrating DISQUS to your SPA</title>
		<link>http://www.binoot.com/2013/04/23/integrating-disqus-to-your-spa/</link>
		<comments>http://www.binoot.com/2013/04/23/integrating-disqus-to-your-spa/#comments</comments>
		<pubDate>Tue, 23 Apr 2013 03:09:39 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Single Page Applications]]></category>
		<category><![CDATA[DISQUS]]></category>
		<category><![CDATA[Durandal]]></category>
		<category><![CDATA[spa]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=524</guid>
		<description><![CDATA[I am building a single page application (SPA) using Durandal JS (with ServiceStack powered API layer). In one of the sections I wanted to have DISQUS discussion integrated. This blog post outlines problems I faced and solution to the problem I found. In a normal web site, integration of DISQUS to your pages is easy, you sign up for DISQUS, get the JavaScript Universal Code for web sites, add it where you want your discussion ...]]></description>
			<content:encoded><![CDATA[<p>I am building a single page application (SPA) using Durandal JS (with ServiceStack powered API layer). In one of the sections I wanted to have DISQUS discussion integrated. This blog post outlines problems I faced and solution to the problem I found.<br />
In a normal web site, integration of DISQUS to your pages is easy, you sign up for DISQUS, get the JavaScript Universal Code for web sites, add it where you want your discussion thread to show up in your page. When web page loads, DISQUS loads the required Javascript and adds it to the section of your page. By default DISQUS will use the page url as the key to the discussion and manages unique thread ids for your posts and replies within that.</p>
<p>Now with this model we have a problem, in a SPA, there is no &#8220;pages&#8221; its all one &#8220;single&#8221; page with routes (by some convention) managing the loading of various views. So if you simply paste DISQUS code where you want the discussion to show up in your SPA view html page, result will be disappointing! At least it was for me the first time. Again to my defense, it was late in the night and I was not thinking clearly. When the page ran, it did not load anything&#8230;blank! Problem is that if you add a JS snippet to your view code, its not going to work in a SPA architecture.</p>
<p><strong>Solution</strong></p>
<p>We need to load the required JavaScript file just like you load any other piece of code that is required by your application. Here  is how you do it&#8230;</p>
<pre class="brush: jscript; title: ; notranslate">
     function initDisqus() {
	window.disqus_shortname = 'your-app-name';
	var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
		dsq.src = '//' + window.disqus_shortname + '.disqus.com/embed.js';
		$.getScript(dsq.src)
			.done(function () {
		          //
			});

	}
</pre>
<p>This works, well mostly&#8230;If you run your page now, you will see your discussion initialized on the page. And you can start adding comments, I was happy to get to this point, and soon realized that all the comments were getting added to the root of the site, and if you reload the page, DISQUS failed to attach the comments back to this discussion. All those comments were kinda orphaned. Soon I realized that the presence of &#8216;#&#8217; (hash) in my url is also messing up with how DISQUS works!! If you have a URL like http://www.mysite.com/#/blog/my-first-blog, DISQUS does not treat anything after the &#8216;#&#8221; as part of your Url and attaches the thread id after the &#8216;#&#8217;.</p>
<p>So what do you do? One way (at least what I think) is to<strong> change &#8216;#&#8217; to &#8216;#!&#8217;,</strong> for example, the URL given before will change to http://www.mysite.com/#!/blog/my-first-blog. Durandal did not complain and loads the page, and DISQUS seems to like it too. One another thing you will need to do is to reload DISQUS every time your new view loads with new unique identifier for the page and the link. This way all the discussions that happens will be tracked under your unique view (urls).</p>
<p><strong>More complete solution:</strong></p>
<pre class="brush: jscript; title: ; notranslate">
     function initDisqus() {
	window.disqus_shortname = 'your-app-name';
	var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
	dsq.src = '//' + window.disqus_shortname + '.disqus.com/embed.js';
	$.getScript(dsq.src)
			.done(function () {
				DISQUS.reset({
					reload: true,
					config: function () {
						this.page.identifier = window.location.href;
						this.page.url = window.location.href;
					}
				});
			});

	}

</pre>
<p><em>Note: Make sure to call this function from your &#8220;viewAttached&#8221; within your view model code.</em></p>
<p>That&#8217;s all for now folks, Happy programming!</p>
<p>Cheers!<br />
Binu</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2013/04/23/integrating-disqus-to-your-spa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deploying Durandal SPA to Production</title>
		<link>http://www.binoot.com/2013/04/18/deploying-durandal-spa-to-production/</link>
		<comments>http://www.binoot.com/2013/04/18/deploying-durandal-spa-to-production/#comments</comments>
		<pubDate>Thu, 18 Apr 2013 18:50:59 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Single Page Applications]]></category>
		<category><![CDATA[Durandal]]></category>
		<category><![CDATA[Require JS]]></category>
		<category><![CDATA[Single Page Application]]></category>
		<category><![CDATA[spa]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=520</guid>
		<description><![CDATA[I have been building a single page application (SPA) using Durandal JS. In this post, I want to talk about some of the steps that you want to take when you are deploying your single page application to your production/live web server. In my case I am using ASP.Net MVC 4 and I use Windows Azure to host my website. If you want to learn more about how to build a SPA using Durandal, I ...]]></description>
			<content:encoded><![CDATA[<p>I have been building a single page application (SPA) using Durandal JS. In this post, I want to talk about some of the steps that you want to take when you are deploying your single page application to your production/live web server. In my case I am using ASP.Net MVC 4 and I use Windows Azure to host my website. If you want to learn more about how to build a SPA using Durandal, I strongly suggest you watch <a href="http://www.johnpapa.net/">John Papa</a>&#8216;s <a href="http://www.pluralsight.com/training/Courses/TableOfContents/single-page-apps-jumpstart">SPA Jump Start course</a> in Pluralsight.</p>
<p>Typically your SPA application will have a structure like this:<br />
<a href="http://www.binoot.com/wp-content/uploads/2013/04/spa-structure.png" rel="image_group"><img class="alignnone size-full wp-image-521" title="spa-structure" src="http://www.binoot.com/wp-content/uploads/2013/04/spa-structure.png" alt="" width="174" height="187" /></a></p>
<p>In this all the files except the main-built.js is your application. This includes Durandal, Require JS, your files, etc. &#8220;main-built.js&#8221; is the optimized single file that contains your javascript and html files that you need to deploy to your production web server. So you do you package this for production? This is simple than I thought. I was thinking of using ASP.Net Bundle capability to bundle all the JS files, but decided against it because I felt to manage my SPA files using ASP.Net bundling could become very tricky very fast because of paths, and html files. So I went with the optimizer that is included with Durandal.</p>
<p>Once you install durandal using Nuget ( or HotTowel Nuget), you will see under App\durandal\amd\ you have a file called optimizer.exe. This is the tool we will use to package our SPA application.</p>
<ol>
<li>Step1: To use this you will need to install Node.js, So get node.js and install. You can download Node.js from <a href="http://nodejs.org/">here</a>.</li>
<li>Click on Start &gt; All Programs &gt; Node.js &gt; Node js command prompt</li>
<li>Navigate to your projects \app\durandal\amd folder</li>
<li>Run optimizer.exe</li>
<li>This will scan everything under your \App folder and creates the combined and optimized file main-built.js</li>
</ol>
<p>Now we can use this file in our application, following code snippet shows how to include this in your index.chtml file. We will use the full files when we are in debug mode and when we are running a release configuration, use the optimized file.</p>
<pre class="brush: csharp; title: ; notranslate">
@Scripts.Render(&quot;~/scripts/vendor&quot;)
@if(HttpContext.Current.IsDebuggingEnabled) {
     &lt;script src=&quot;~/App/durandal/amd/require.js&quot; data-main=&quot;App/main&quot;&gt;&lt;/script&gt;
}
else
{
    &lt;script type=&quot;text/javascript&quot; src=&quot;~/App/main-built.js&quot;&gt;&lt;/script&gt;
}
</pre>
<p>As you can see, I am using ASP.Net Bundles to combine and compress all the standard JS files like bootstrap, jquery plugins, or any other components that I use and are not part of my SPA code and use the optimizer created file for my SPA code. With this approach, our application code (SPA code) is send to browser as a single file enabling faster download. If you want to bust cache when each time you are deploying new code to your server, you can configure Require.js to include a query string parameter to each resource it fetches.</p>
<pre class="brush: jscript; title: ; notranslate">
require.config({
	paths: { &quot;text&quot;: &quot;durandal/amd/text&quot; },
	urlArgs: &quot;bust=&quot; + (new Date()).getTime()
});
</pre>
<p>Reference: http://requirejs.org/docs/api.html#config.</p>
<p>Please note that the code snippet above is ideal only for development, for your release code, change this to something like :</p>
<pre>urlArgs: "bust=v1.1"</pre>
<p>This will make sure that your users will not be downloading any resources that browser already has unless it is changed (which typically happens when you have a new release)</p>
<p>That&#8217;s all for now folks! Happy Programming!<br />
Cheers!<br />
Binu</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2013/04/18/deploying-durandal-spa-to-production/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LinkedIn Provider for ServiceStack Authentication</title>
		<link>http://www.binoot.com/2013/03/30/linkedin-provider-for-servicestack-authentication/</link>
		<comments>http://www.binoot.com/2013/03/30/linkedin-provider-for-servicestack-authentication/#comments</comments>
		<pubDate>Sat, 30 Mar 2013 00:54:07 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[ServiceStack]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[LinkedIn]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=513</guid>
		<description><![CDATA[I love ServiceStack ! Its just pure awesomeness!  It includes a very robust Authentication and Authorization feature that is very easily extensible. Read all about it here =&#62; https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization. &#8230;But it did not support LinkedIn provider, so I spend some time this afternoon to write one, here is the code. (I told you, its easy, even I can do this Happy programming ! Cheers! Binu]]></description>
			<content:encoded><![CDATA[<p>I love ServiceStack ! Its just pure awesomeness!  It includes a very robust Authentication and Authorization feature that is very easily extensible. Read all about it here =&gt; <a title="ServiceStack" href="https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization" target="_blank">https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization</a>.</p>
<p>&#8230;But it did not support LinkedIn provider, so I spend some time this afternoon to write one, here is the code. (I told you, its easy, even I can do this <img src='http://www.binoot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: csharp; title: ; notranslate">
    public class LinkedinAuthProvider : OAuthProvider 
    {
        public const string Name = &quot;linkedin&quot;;
        public static string Realm = &quot;https://www.linkedin.com/uas/oauth2/&quot;;

        public static string PeopleDataUrl =
            &quot;https://api.linkedin.com/v1/people/~:(id,first-name,last-name,formatted-name,industry,email-address)?format=json&amp;&quot;;

        public LinkedinAuthProvider(IResourceManager appSettings): base(appSettings, Realm, Name) {}

        public override object Authenticate(IServiceBase authService, IAuthSession session, ServiceStack.ServiceInterface.Auth.Auth request)
        {
            var tokens = Init(authService, ref session, request);
            var code = authService.RequestContext.Get&lt;IHttpRequest&gt;().QueryString[&quot;code&quot;];
            var error = authService.RequestContext.Get&lt;IHttpRequest&gt;().QueryString[&quot;error&quot;];
            var isPreAuthError = !error.IsNullOrEmpty();
            if (isPreAuthError)
            {
                return authService.Redirect(session.ReferrerUrl);
            }
            var isPreAuthCallback = !code.IsNullOrEmpty();
            if (!isPreAuthCallback)
            {
                var preAuthUrl = Realm + &quot;authorization?response_type=code&amp;client_id={0}&amp;scope={1}&amp;state={2}&amp;redirect_uri={3}&quot;;
                preAuthUrl = preAuthUrl.Fmt(ConsumerKey, &quot;r_fullprofile%20r_emailaddress&quot;, Guid.NewGuid().ToString(), this.CallbackUrl.UrlEncode());
      
                authService.SaveSession(session, SessionExpiry);
                return authService.Redirect(preAuthUrl);
            }

            var accessTokenUrl = Realm +
                                 &quot;accessToken?grant_type=authorization_code&amp;code={0}&amp;redirect_uri={1}&amp;client_id={2}&amp;client_secret={3}&quot;;
            accessTokenUrl = accessTokenUrl.Fmt(code, this.CallbackUrl.UrlEncode(), this.ConsumerKey,
                                                this.ConsumerSecret);

            try
            {
                var contents = accessTokenUrl.GetStringFromUrl();
                var authInfo = JsonObject.Parse(contents);
                tokens.AccessTokenSecret = authInfo[&quot;access_token&quot;];
                session.IsAuthenticated = true;
                authService.SaveSession(session, SessionExpiry);
                OnAuthenticated(authService, session, tokens, authInfo.ToDictionary());

                
                return authService.Redirect(session.ReferrerUrl.AddHashParam(&quot;s&quot;, &quot;1&quot;));
            }
            catch (WebException we)
            {
                var statusCode = ((HttpWebResponse)we.Response).StatusCode;
                if (statusCode == HttpStatusCode.BadRequest)
                {
                    return authService.Redirect(session.ReferrerUrl.AddHashParam(&quot;f&quot;, &quot;AccessTokenFailed&quot;));
                }
            }
            return null;
        }
        protected override void LoadUserAuthInfo(AuthUserSession userSession, IOAuthTokens tokens, Dictionary&lt;string, string&gt; authInfo)
        {
            var url = PeopleDataUrl + &quot;oauth2_access_token={0}&quot;;
            url = url.Fmt(authInfo[&quot;access_token&quot;]);
            var json = url.GetStringFromUrl();

            var obj = JsonObject.Parse(json);
            tokens.UserId = obj.Get(&quot;id&quot;);
            tokens.UserName = obj.Get(&quot;emailAddress&quot;);
            tokens.DisplayName = obj.Get(&quot;formattedName&quot;);
            tokens.FirstName = obj.Get(&quot;firstName&quot;);
            tokens.LastName = obj.Get(&quot;lastName&quot;);
            tokens.Email = obj.Get(&quot;emailAddress&quot;);
            
            LoadUserOAuthProvider(userSession, tokens);
        }

        public override void LoadUserOAuthProvider(IAuthSession authSession, IOAuthTokens tokens)
        {
            var userSession = authSession as AuthUserSession;
            if (userSession == null) return;

            userSession.DisplayName = tokens.DisplayName ?? userSession.DisplayName;
            userSession.FirstName = tokens.FirstName ?? userSession.FirstName;
            userSession.LastName = tokens.LastName ?? userSession.LastName;
            userSession.PrimaryEmail = tokens.Email ?? userSession.PrimaryEmail ?? userSession.Email;
        }
</pre>
<p>Happy programming !</p>
<p>Cheers!</p>
<p>Binu</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2013/03/30/linkedin-provider-for-servicestack-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bundle your resources to speed up your ASP.Net website</title>
		<link>http://www.binoot.com/2013/02/13/bundle-your-resources-to-speed-up-your-asp-net-website/</link>
		<comments>http://www.binoot.com/2013/02/13/bundle-your-resources-to-speed-up-your-asp-net-website/#comments</comments>
		<pubDate>Wed, 13 Feb 2013 16:13:13 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Asp.net MVC]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=510</guid>
		<description><![CDATA[I am not going to write a big blog post on this here, because there is already quite a bit of good articles out there on this topic. Why I am writing is this to share a very good article on this topic for anyone who wants to learn about Bundling and Minnification features that are available with ASP.Net 4.5. It is written by Rick Anderson and you can read full article from here.]]></description>
			<content:encoded><![CDATA[<p>I am not going to write a big blog post on this here, because there is already quite a bit of good articles out there on this topic. Why I am writing is this to share a very good article on this topic for anyone who wants to learn about Bundling and Minnification features that are available with ASP.Net 4.5.</p>
<p>It is written by Rick Anderson and you can read full article from <a href="http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2013/02/13/bundle-your-resources-to-speed-up-your-asp-net-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to call ServiceStack API end point from JavaScript</title>
		<link>http://www.binoot.com/2013/01/21/how-to-call-servicestack-end-point-from-javascript/</link>
		<comments>http://www.binoot.com/2013/01/21/how-to-call-servicestack-end-point-from-javascript/#comments</comments>
		<pubDate>Mon, 21 Jan 2013 04:36:50 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ServiceStack]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=505</guid>
		<description><![CDATA[Why this is important? You might ask? Yes, it is straight forward and we all have done this several times. But why I thought of writing about this is because I wasted couple of hours because of a silly oversight. In the title I said API based on ServiceStack, this is nothing different from any other RESTful endpoint, ex: WebAPI. So in my service takes an input like this: and service implementation goes something like ...]]></description>
			<content:encoded><![CDATA[<p>Why this is important? You might ask? Yes, it is straight forward and we all have done this several times. But why I thought of writing about this is because I wasted couple of hours because of a silly oversight. In the title I said API based on ServiceStack, this is nothing different from any other RESTful endpoint, ex: WebAPI. </p>
<p>So in my service takes an input like this:</p>
<pre class="brush: csharp; title: ; notranslate">
[Route(&quot;/usermeta&quot;)]
public class UserMeta
    {
        public string Email { get; set; }
        public List&lt;string&gt; Expertise { get; set; }
    }
</pre>
<p>and service implementation goes something like this:</p>
<pre class="brush: csharp; title: ; notranslate">
[Authenticate]
        public object Post(UserMeta request)
        {
        
            //I do something here
            
        }
</pre>
<p>Now to call this api, this is what we do in JavaScript world,</p>
<pre class="brush: jscript; title: ; notranslate">
                    var request = { };
                   
                    request.Email = this.profileEmail;
                    request.Expertise = this.expertAreas(); //ERROR!!!
                   
                    $.ajax({
                        type: &quot;post&quot;,
                        url: 'api/usermeta',
                        dataType: 'json',
                        data:request,
                        success: function (data) {
                            toastr.success(&quot;Everything is saved, you are all set for now!&quot;, 'Wohoo!');
                        },
                        error: function (data) {
                            toastr.error(&quot;Oh! snap...something went wrong!&quot;, 'Error!');
                        }
                    });
</pre>
<p>Now this is straightforward, isnt&#8217;it? I thought so too. But when I ran this code, I got the email address correctly in server side, but field &#8220;Expertise&#8221; was null. Issue was that I was passing the object literal and the request was expecting json. </p>
<p>Every thing started working the moment, I converted &#8220;this.expertAreas()&#8221; to json using JSON.stringify() (in json2.js). Simple stupid thing, but I lost my 2 hours!!!<br />
(Thanks to my wife for pointing out the error <img src='http://www.binoot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Corrected code is given below, you can stringify the whole object literal too,</p>
<pre class="brush: jscript; title: ; notranslate">
                    var request = { };
                   
                    request.Email = this.profileEmail;
                    request.Expertise = JSON.stringify(this.expertAreas());
                   
                    $.ajax({
                        type: &quot;post&quot;,
                        url: 'api/usermeta',
                        dataType: 'json',
                        data:request,
                        success: function (data) {
                            toastr.success(&quot;Everything is saved, you are all set for now!&quot;, 'Wohoo!');
                        },
                        error: function (data) {
                            toastr.error(&quot;Oh! snap...something went wrong!&quot;, 'Error!');
                        }
                    });
</pre>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2013/01/21/how-to-call-servicestack-end-point-from-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transform your templated web.config files with NAnt</title>
		<link>http://www.binoot.com/2012/12/05/transform-your-templated-web-config-files-with-nant/</link>
		<comments>http://www.binoot.com/2012/12/05/transform-your-templated-web-config-files-with-nant/#comments</comments>
		<pubDate>Wed, 05 Dec 2012 18:49:46 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[etc.]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[CI]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[NAnt]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=491</guid>
		<description><![CDATA[There are many steps one need to do to setup a good working development environment. In large products where there are many project files and solutions that needed to be build in a certain order, managing all the config files can be a nightmare. This post is not going to tell you how to do things in such a large scale, but I want to show how easy is to use NAnt tool to do web ...]]></description>
			<content:encoded><![CDATA[<p>There are many steps one need to do to setup a good working development environment. In large products where there are many project files and solutions that needed to be build in a certain order, managing all the config files can be a nightmare. This post is not going to tell you how to do things in such a large scale, but I want to show how easy is to use NAnt tool to do web config transformations. This will become one of the steps that we need to do as part of a continuous integration (CI) build or a local build. I have seen development teams struggle with setting up local development environment. This becomes a pain when project builds are not well thought, or designed well. My advise to any development team or developer is to spend some time to think thru our development process and build and deployment process. Treat this as a technical debt and deal with it aggressively before it reaches a point where you are spending hours every day trying to build your solution(s) so that you can write code.</p>
<p>Enough of the story, let us get to the point.</p>
<p>Our aim is to transform a template config file. Let us name config files in the format web.config.TEMPLATE. Idea is to use NAnt to do a transformation while copying this file to the target name of web.config. In the template file, you will need to tokenize the parts that you want to change depending on the environment. For example, when you are developing local, you may want to point to your local database server, in a QA environment, this will be a QA database server. You got the idea.</p>
<p>NAnt works with a project file for the build. There are several tasks NAnt can do, one of these tasks is a copy task. All NAnt related files are XML files. You can run NAnt from the command prompt and it takes many command line parameters.</p>
<pre class="brush: xml; title: ; notranslate">
nant.exe -buildfile:config.build -D:sourcefile=.\source\web.config.TEMPLATE -D:propertyfile=.\build\local.properties -D:destinationfile=.\source\web.config
</pre>
<p>Command line switch -buildfile is the name of the build file; -D allows us to pass multiple property name-values.</p>
<p>For our little experiment, I want to build web.config files for my two scenarios, one is when I work on local machine, I need a local version of web.config created and when I move to my QA environment, I need a different web.config file. The following picture shows how files and folders are setup:</p>
<p><a href="http://www.binoot.com/wp-content/uploads/2012/12/FolderView-All.png" rel="image_group"><img class="alignnone size-medium wp-image-494" title="FolderView-All" src="http://www.binoot.com/wp-content/uploads/2012/12/FolderView-All-300x83.png" alt="" width="300" height="83" /></a></p>
<p>What I have in \build folder &#8211; property files for various environments</p>
<p><a href="http://www.binoot.com/wp-content/uploads/2012/12/FolderView-build.png" rel="image_group"><img class="alignnone size-medium wp-image-495" title="FolderView-build" src="http://www.binoot.com/wp-content/uploads/2012/12/FolderView-build-300x49.png" alt="" width="300" height="49" /></a></p>
<p>what I have in \source folder &#8211; we.config.TEMPLATE file (actual config file is generated here itself)</p>
<p><a href="http://www.binoot.com/wp-content/uploads/2012/12/FolderView-source.png" rel="image_group"><img class="alignnone size-medium wp-image-496" title="FolderView-source" src="http://www.binoot.com/wp-content/uploads/2012/12/FolderView-source-300x44.png" alt="" width="300" height="44" /></a></p>
<p>This is the NAnt project file. A default.properties is loaded always. We will use this file to capture all the properties that are common across the different configurations<br />
we are building.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;project default=&quot;buildconfig&quot;&gt;  
	&lt;property name=&quot;propertyfile&quot; value=&quot;invalid.file&quot; overwrite=&quot;false&quot; /&gt;  

	&lt;if test=&quot;${file::exists('default.properties')}&quot;&gt;
		&lt;echo message=&quot;Loading default.properties&quot; /&gt;
		&lt;include buildfile=&quot;default.properties&quot; /&gt;
	&lt;/if&gt;
	&lt;echo message=&quot;Loading ${propertyfile}&quot; /&gt;
	
	&lt;include buildfile=&quot;${propertyfile}&quot; failonerror=&quot;false&quot; unless=&quot;${string::contains(propertyfile, 'invalid.file')}&quot; /&gt;  
	
	&lt;target name=&quot;buildconfig&quot;&gt;  
		&lt;copy file=&quot;${sourcefile}&quot; tofile=&quot;${destinationfile}&quot; overwrite=&quot;true&quot;&gt;  
		  &lt;filterchain&gt;  
			&lt;expandproperties /&gt;  
		  &lt;/filterchain&gt;  
		&lt;/copy&gt;  

	&lt;/target&gt;  
&lt;/project&gt; 
</pre>
<p>So for example we have the following we.config.TEMPLATE file that needs to get build for local and QA environments,</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;configuration&gt;
  &lt;connectionStrings&gt;
    &lt;add name=&quot;DatabaseConnection&quot;  connectionString=&quot;Server=${DBServerName};Database=${DBName};Trusted_Connection=${TrustedConnectionValue}&quot; /&gt;
  &lt;/connectionStrings&gt;
&lt;/configuration&gt;
</pre>
<p>So we have tokens for database server, database name and trusted connection value. For example, if our database name and the trusted connection value is not changing from environment to environment, then you keep these property values in default.properties file. Since this file is loaded always (see build file), NAnt will be able to replace those tokens. Furthermore we will pass the environment specific property file along with the command line that is used to run NAnt.</p>
<p>Our default.properties file:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;project&gt;  
   &lt;property name=&quot;DBName&quot; value=&quot;FancyApp&quot; /&gt;  
   &lt;property name=&quot;TrustedConnectionValue&quot; value=&quot;true&quot; /&gt;  
&lt;/project&gt;  
</pre>
<p>and our local.properties file; where we specify the database server name as (local). When we are running for another environment like QA, a qa.properties file can be created and passed in as parameter.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;project&gt;  
   &lt;property name=&quot;DBServerName&quot; value=&quot;(local)&quot; /&gt;  
&lt;/project&gt;  
</pre>
<p>So, now with these files all set in the right places, if we run the commandline for NAnt, NAnt will run the <copy> task with a FilerChain to expand the properties using the files and/or property values supplied. Resulting file is the config file that you would want to use in the specified environment.</p>
<p>I am planning to expand this post in coming weeks, to show how we can use MSBuild to build the project,, deploy it to the specified location, how we can automatically checkout files from SVN, run some Unit/INtegration tests etc.</p>
<p>Once we have a full local build worked out, I will expand it further to use a CI Build server like Team City to kick off automated builds.</p>
<p>Exciting&#8230;</p>
<p>Until then, be productive <img src='http://www.binoot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2012/12/05/transform-your-templated-web-config-files-with-nant/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>StructureMap update using Nuget &#8211; Error and Resolution</title>
		<link>http://www.binoot.com/2012/09/26/structuremap-update-using-nuget-error-and-resolution/</link>
		<comments>http://www.binoot.com/2012/09/26/structuremap-update-using-nuget-error-and-resolution/#comments</comments>
		<pubDate>Wed, 26 Sep 2012 18:58:29 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[nuget]]></category>
		<category><![CDATA[StructureMap]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=455</guid>
		<description><![CDATA[If you update StructureMap to 2.6.4 using Nuget Package Management console, you (may) get this error message Could not load file or assembly &#8216;StructureMap, Version=2.6.3.0, Culture=neutral.. Here is what you need to do to get moving past this error&#8230;Pop this into your app.config or web.config file and you will be good to go! Basically what it does is a binding redirect for StructureMap assembly that uses old versions 0.0 thru 2.6.4 to use the new ...]]></description>
			<content:encoded><![CDATA[<p>If you update StructureMap to 2.6.4 using Nuget Package Management console, you (may) get this error message</p>
<blockquote><p>
Could not load file or assembly &#8216;StructureMap, Version=2.6.3.0, Culture=neutral..
</p></blockquote>
<p>Here is what you need to do to get moving past this error&#8230;Pop this into your app.config or web.config file and you will be good to go!</p>
<pre class="brush: csharp; title: ; notranslate">
  &lt;runtime&gt;
    &lt;assemblyBinding xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot;&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name=&quot;StructureMap&quot; publicKeyToken=&quot;e60ad81abae3c223&quot; culture=&quot;neutral&quot; /&gt;
        &lt;bindingRedirect oldVersion=&quot;0.0.0.0-2.6.4.0&quot; newVersion=&quot;2.6.4.0&quot; /&gt;
      &lt;/dependentAssembly&gt;
    &lt;/assemblyBinding&gt;
  &lt;/runtime&gt;
</pre>
<p>Basically what it does is a binding redirect for StructureMap assembly that uses old versions 0.0 thru 2.6.4 to use the new version<br />
Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2012/09/26/structuremap-update-using-nuget-error-and-resolution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guid Strategy for DB Primary Keys</title>
		<link>http://www.binoot.com/2012/09/14/guid-db-primary-ke/</link>
		<comments>http://www.binoot.com/2012/09/14/guid-db-primary-ke/#comments</comments>
		<pubDate>Fri, 14 Sep 2012 20:15:51 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[ADO.Net]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[Sql Server]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Data Access]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=448</guid>
		<description><![CDATA[I was thinking about this for a while now, some years back, I always used Integer fields as Primary key columns in my database tables, more recently I have switched to using Guid values (uuid datatype in Sql Server) for the same.  This is not a new thing for most of us, we have weighed the options and have chosen one way or the other. In my mind, Integers work very well as a Primary ...]]></description>
			<content:encoded><![CDATA[<p>I was thinking about this for a while now, some years back, I always used Integer fields as Primary key columns in my database tables, more recently I have switched to using Guid values (uuid datatype in Sql Server) for the same.  This is not a new thing for most of us, we have weighed the options and have chosen one way or the other.</p>
<p>In my mind, Integers work very well as a Primary Key column, it works very well as an clustered index, the most recent is naturally the largest value. If you use a regular Guid, it is random in nature and can lead to fragmented indices. But Guid being unique, we can easily  move around that data, replicate, etc. No issues like in the case of a auto number integer.</p>
<p>So, in short if we can get to generate a sequential Guid, we strike gold ! I am using NHibernate ORM (with Fluent NHibernate), and it can use a Comb Identifier strategy to generate sequential Guids.</p>
<p>It is very easy to set this up, when you setup your session factory, you can add conventions for your mappings. You can define a PrimaryKey convention like this:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class PrimaryKeyConvention : IIdConvention
    {
        public void Apply(IIdentityInstance instance)
        {
            instance.Column(&quot;Id&quot;);
            instance.GeneratedBy.GuidComb();
        }
    }
</pre>
<p>and you can use this convention in your configuration like this:</p>
<pre class="brush: csharp; title: ; notranslate">
    var cfg = new NHibernate.Cfg.Configuration()
                    .SetProperty(NHibernate.Cfg.Environment.CommandTimeout, &quot;100&quot;)
                    .Proxy(p =&gt; p.ProxyFactoryFactory&lt;DefaultProxyFactoryFactory&gt;())
                    .DataBaseIntegration(db =&gt;
                        {
                            db.Dialect&lt;MsSqlAzure2008Dialect&gt;();
                            db.ConnectionString = _context.ConnectionString;
                            db.BatchSize = (short) _batchSize;
                        });

                var sessionFactory = Fluently.Configure(cfg)
                    .Mappings(m =&gt;
                    {
                        m.FluentMappings.AddFromAssembly(_context.Assembly);
                        m.FluentMappings.Conventions.Add(typeof(EnumConvention));
                        m.FluentMappings.Conventions.Add(typeof(PrimaryKeyConvention));
                        m.FluentMappings.Conventions.Add(typeof(DefaultStringLengthConvention));
                    })
                    .BuildSessionFactory();
</pre>
<p>This should help us having a better strategy for handling Guids as our PrimaryKey values in tables.</p>
<p>I still have an open question in my mind. Does this scale well (as an Int or Long) when we have millions of rows in our tables??</p>
<p>What do you guys think?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2012/09/14/guid-db-primary-ke/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grab ReSharper 7 discount NOW!</title>
		<link>http://www.binoot.com/2012/09/12/grab-resharper-7-discount-now/</link>
		<comments>http://www.binoot.com/2012/09/12/grab-resharper-7-discount-now/#comments</comments>
		<pubDate>Wed, 12 Sep 2012 20:31:13 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[resharper]]></category>
		<category><![CDATA[static code analysis]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=441</guid>
		<description><![CDATA[I just noticed that there is a &#8220;Back to School&#8221; discount on new version of ReSharper. If you are a C# developer, this is the time for upgrading your personal license. If you do not have a license yet, its great time to get a personal license. Your life is so much better if you use ReSharper ! More details on this offer. &#160; Cheers! &#160;]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.binoot.com/wp-content/uploads/2012/09/resharper-school1.png" rel="image_group"><img class="alignnone size-full wp-image-443" title="resharper-back-to-school-sale" src="http://www.binoot.com/wp-content/uploads/2012/09/resharper-school1.png" alt="resharper-back-to-school-sale" width="328" height="103" /></a></p>
<p>I just noticed that there is a &#8220;Back to School&#8221; discount on new version of ReSharper. If you are a C# developer, this is the time for upgrading your personal license. If you do not have a license yet, its great time to get a personal license. Your life is so much better if you use ReSharper !</p>
<p><a title="resharper-back-to-school-sale" href="http://www.jetbrains.com/resharper/buy/index.jsp?BacktoSchool" target="_blank">More details on this offer.</a></p>
<p><a href="http://www.binoot.com/wp-content/uploads/2012/09/resharper-full.png" rel="image_group"><img class="alignnone size-full wp-image-444" title="resharper-full" src="http://www.binoot.com/wp-content/uploads/2012/09/resharper-full.png" alt="resharper-full" width="589" height="71" /></a></p>
<p><a href="http://www.binoot.com/wp-content/uploads/2012/09/resharper-personal.png" rel="image_group"><img class="alignnone size-full wp-image-445" title="resharper-personal" src="http://www.binoot.com/wp-content/uploads/2012/09/resharper-personal.png" alt="resharper-personal" width="591" height="76" /></a></p>
<p>&nbsp;</p>
<p>Cheers!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2012/09/12/grab-resharper-7-discount-now/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn to write Single Page Applications using HTML5, Web API, Knockout and JQuery for Free!</title>
		<link>http://www.binoot.com/2012/09/12/free-html5-knockout-training/</link>
		<comments>http://www.binoot.com/2012/09/12/free-html5-knockout-training/#comments</comments>
		<pubDate>Wed, 12 Sep 2012 18:33:50 +0000</pubDate>
		<dc:creator>Binu Thayamkery</dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[etc.]]></category>
		<category><![CDATA[MVC3]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[knockout]]></category>
		<category><![CDATA[spa]]></category>
		<category><![CDATA[web api]]></category>

		<guid isPermaLink="false">http://www.binoot.com/?p=439</guid>
		<description><![CDATA[Its FREE! This week only! check it out, I got this email from Pluralsight announcing this new course! SPA w/HTML5, Web API, Knockout and jQuery - Free this week! By John Papa &#8211; Learn to build end to end Single Page Application solutions using data binding and MVVM on the client; and examine layered patterns and data access on the server. Check our blog tomorrow for a free offer to this new course!]]></description>
			<content:encoded><![CDATA[<p>Its FREE! This week only! check it out, I got this email from Pluralsight announcing this new course!</p>
<blockquote>
<h4><a href="http://cts.vresp.com/c/?Pluralsight/d733acfa58/0c7b73654a/1d64ec0c8d" target="_blank">SPA w/HTML5, Web API, Knockout and jQuery</a> - Free this week!<a href="http://cts.vresp.com/c/?Pluralsight/d733acfa58/0c7b73654a/ffb30b3dbc" target="_blank"><img title="John Papa" src="http://pr.ak.vresp.com/9ae6a19d5/s.pluralsight.com/mn/img/au/sm/john-papa-v1.png" alt="John Papa" width="64" height="65" align="right" border="0" hspace="5" vspace="0" /></a></h4>
<div>By John Papa &#8211; Learn to build end to end Single Page Application solutions using data binding and MVVM on the client; and examine layered patterns and data access on the server. Check our blog tomorrow for a free offer to this new course!</div>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.binoot.com/2012/09/12/free-html5-knockout-training/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
