<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Site-Server v@build.version@ (http://www.squarespace.com) on Thu, 16 Apr 2026 09:04:13 GMT
--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://www.rssboard.org/media-rss" version="2.0"><channel><title>Blog - EricPhan.net</title><link>http://ericphan.net/blog/</link><lastBuildDate>Tue, 08 Sep 2020 11:50:06 +0000</lastBuildDate><language>en-AU</language><generator>Site-Server v@build.version@ (http://www.squarespace.com)</generator><description><![CDATA[<p>Random thoughts about development on the Microsoft platform</p>]]></description><item><title>Migrating test cases from one VSTS Project to another</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Wed, 03 Jan 2018 05:25:09 +0000</pubDate><link>http://ericphan.net/blog/2018/1/3/migrating-test-cases-from-one-vsts-project-to-another</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:5a4c61799140b791bb2b8a2c</guid><description><![CDATA[Recently I was helping a client of SMEx Digital to migrate their VSTS 
projects. One of the requirements was also retain their ~450 test cases 
that they have built up.

VSTS gives you hope in the Queries interface by providing an option to 
"Move to team project..."]]></description><content:encoded><![CDATA[<p>Recently I was helping a client of SMEx Digital to migrate their VSTS projects. One of the requirements was also retain their ~450 test cases that they have built up.</p><p>VSTS gives you hope in the Queries interface by providing an option to "Move to team project..."</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png" data-image-dimensions="492x283" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=1000w" width="492" height="283" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955409611-1TWZS9HKOF3V8XC8DPU0/2018-01-03_15-56-20.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>However this doesn't work for Test Cases as they are classed as <a target="_blank" href="https://docs.microsoft.com/en-us/vsts/work/work-items/agile-glossary#hidden-types">hidden </a>and you will get an error message if you try.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png" data-image-dimensions="596x519" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=1000w" width="596" height="519" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514955673045-0FTE2APCWWD7L794LAF0/2018-01-03_16-00-08.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Figure: "Work item type Test Case cannot be moved because it is disabled, hidden or not supported in the destination project" error message</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>Thankfully, if you have Microsoft Test Manager installed, then you have access to Test Case Management CLI (tcm.exe)</p><p>To migrate test cases from one project to another, what you have to do is:</p><ul dir="ltr"><li>Select Test | Test Plans</li><li>Create a new Test Plan (call it All Test Cases)</li><li>Create a new Query Based Test Suite (call it All Test Cases)</li></ul>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png" data-image-dimensions="661x377" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=1000w" width="661" height="377" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514956083657-2BNM54AUPBO1HOOA6GGC/2018-01-03_16-06-02.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ul><li>For the Query, just use "Work Item Type" "In Group" "Microsft.TestCaseCategory"</li><li>Select all your test cases and Create Suite</li><li>You need to note the Test Suite ID as we'll need this in the command line later. I'll refer to this as the &lt;SourceSuiteID&gt;</li></ul><p>Now in your destination Team Project (&lt;TargetProjectName&gt;)</p><ul><li>Create a new Test Plan called Imported Test Cases</li><li>Note the Suite ID of this test plan. I'll refer to this as the &lt;TargetSuiteID&gt;</li></ul><p>Now fire up the Developer command prompt</p>
























  
    <pre class="source-code">C:\Users\ephan&gt;tcm suites /clone 
/collection:https://&lt;youraccount&gt;.visualstudio.com/defaultcollection 
/teamproject:&lt;SourceProjectName&gt; 
/suiteid:&lt;SourceSuiteId&gt; 
/destinationteamproject:"&lt;TargetProjectName&gt;"  
/destinationsuiteid:&lt;TargetSuiteId&gt; 
/overridefield:"Iteration Path"="&lt;TargetProjectName&gt;)"
/overridefield:"Area Path"="&lt;TargetProjectName&gt;" 

Started clone operation with id 1.
Use /status:1 to get progress and completion information of the operation.
Warning: You have cloned the following query based suites as part of this clone operation. You are advised to fix their respective queries in the source and destination suites, after the clone operation completes.
1. All Test Cases -&gt; All Test Cases
</pre>
  




  <p>It should give you an operation id which you use to query the status of the job.</p>
























  
    <pre class="source-code">C:\Users\ephan&gt;tcm suites /status:&lt;Operation ID&gt; /clone /collection:https://&lt;youraccount&gt;.visualstudio.com/defaultcollection /teamproject:&lt;SourceProjectName&gt;

Clone operation 1 is in progress.
Total test cases:    446
Processed:           198
Progress:             44%

C:\Users\ephan&gt;tcm suites /status:&lt;Operation ID&gt; /clone /collection:https://&lt;youraccount&gt;.visualstudio.com/defaultcollection /teamproject:&lt;SourceProjectName&gt;

Clone operation 1 has succeeded. Summary information:
Started on:           3/01/2018 3:26:24 PM
Started by:           Eric Phan
Source suite id:      20105
Destination suite id: 20579
Test cases cloned:    446
Shared steps cloned:  24
Requirements cloned:  0
Completed on:         3/01/2018 3:28:36 PM</pre>
  




  <p>Now if we go over to the target project and query the test cases, we can see that they've all been imported.</p><p> </p><p>Note: This only works when you want to migrate within the same VSTS instance/collection</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1514957138347-MSFLKB6HHWOACHC0P6TX/2018-01-03_15-56-20.png?format=1500w" medium="image" isDefault="true" width="492" height="283"><media:title type="plain">Migrating test cases from one VSTS Project to another</media:title></media:content></item><item><title>Auto creating tasks/work items in Visual Studio Team Services (VSTS) with Microsoft Flow</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Fri, 20 Oct 2017 01:01:26 +0000</pubDate><link>http://ericphan.net/blog/2017/10/20/auto-creating-taskswork-items-in-visual-studio-team-services-vsts-with-microsoft-flow</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:59e93ba790badebf168c827a</guid><description><![CDATA[One of the manual processes that we have at SMEx is that when a pull 
request is accepted, the reviewer needs to go to the linked work item and 
update the state to "Testing" then create a child task and assign it to the 
QA staff to test the PBI before it can finally be marked as "Done"

It's a tedious process with many clicks involved, and I think most of the 
devs here follow the process, sometimes it is still missed. So I began 
exploring ways to automate the creation of this child testing task.

Thankfully Microsoft has a workflow engine called Flow that plays nicely 
with VSTS. So here's what you need to do:]]></description><content:encoded><![CDATA[<p>One of the manual processes that we have at SMEx is that when a pull request is accepted, the reviewer needs to go to the linked work item and update the state to "Testing" then create a child task and assign it to the QA staff to test the PBI before it can finally be marked as "Done"</p><p>It's a tedious process with many clicks involved, and I think most of the devs here follow the process, sometimes it is still missed. So I began exploring ways to automate the creation of this child testing task.</p><p>Thankfully Microsoft has a workflow engine called Flow that plays nicely with VSTS. So here's what you need to do:</p><h2>Create a new connection to VSTS</h2><ol><li>Select <strong>Settings | Connections</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png" data-image-dimensions="1055x368" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=1000w" width="1055" height="368" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458530468-HHB60EUM1WL9KEUZL5HL/SelectConnections.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol><li>Select <strong>New connection</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png" data-image-dimensions="1057x149" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=1000w" width="1057" height="149" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458573445-TDT12YN6VLI5KP28YFYO/NewConnection.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol><li>Search for "<strong>Visual</strong>"</li><li>Click the "<strong>+</strong>" next to <strong>Visual Studio Team Services</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png" data-image-dimensions="1055x222" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=1000w" width="1055" height="222" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458616885-0UG4D0GJBSJ2K022N4HE/NewVSTSConnection.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol><li>Click <strong>Create</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png" data-image-dimensions="613x287" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=1000w" width="613" height="287" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458664002-0G5KZ6TXL5GD9BS5EZVC/CreateVSTSConnection.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p> </p><ol><li>Sign into your VSTS account</li></ol><h2>Create a new Flow</h2><ol><li>Create a new blank Flow</li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png" data-image-dimensions="1054x114" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=1000w" width="1054" height="114" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508457950031-7ST472RXHW3KU94ZK4AW/CreateNewFlow.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol dir="ltr"><li>Click on <strong>S</strong><strong>earch hundreds of connectors and triggers</strong></li><li>Search for "<strong>Visual Studio Team Services</strong>"</li><li>Select <strong>When a work item is updated</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png" data-image-dimensions="1037x692" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=1000w" width="1037" height="692" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508458147857-F1GZ597M7B3XV1Y7CLES/SelectWhenAWorkItemIsUpdated.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol dir="ltr"><li>Fill in the <strong>Account Name</strong>, <strong>Project Name </strong>and <strong>Type</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png" data-image-dimensions="601x261" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=1000w" width="601" height="261" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459721803-U925KH7CXRY31QXET5MX/WorkItemUpdated.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol dir="ltr"><li>Click on <strong>+ New Step</strong></li><li>Select <strong>Add a Condition</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png" data-image-dimensions="531x202" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=1000w" width="531" height="202" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459853093-QR6MAEV6HAK6O72H59A9/AddACondition.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol dir="ltr"><li>Setup the condition details by checking when the <strong>State</strong> is equal to Testing</li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png" data-image-dimensions="634x237" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=1000w" width="634" height="237" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459952654-3ZTMY06MM0CDVLGKN9QY/StateEqualsTesting.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png" data-image-dimensions="600x149" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=1000w" width="600" height="149" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508459972938-9FB5VHC3ZEUID7P92JKP/SetCondition.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol dir="ltr"><li>In the <strong>If Yes</strong> box, select <strong>Add an action</strong> and look for <strong>Create a work item</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png" data-image-dimensions="615x200" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=1000w" width="615" height="200" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460031915-2A7O7CDCHGS2IL62OGEO/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png" data-image-dimensions="637x483" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=1000w" width="637" height="483" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460043547-HAN6M28MXSJUH14CP37O/CreateWorkItem.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol dir="ltr"><li>Fill in the details to create a new task</li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png" data-image-dimensions="600x505" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=1000w" width="600" height="505" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460096553-Y1GF4QBJEM7FDQHDRW4A/CreateWorkItemDetails.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>In the above example, I've created a child task to the PBI with title "&lt;PBI's ID&gt; - Testing. It will have the same area and iteration path as the parent PBI and I've setup the relationship using the Link URL and Link Type.</p><p>Note: The dynamic content does provide a URL for the PBI, but it links directly to the revision of the PBI, so that URL in the Link URL won't work. That's why in the Link URL field I've had to hand craft the URL and put in the ID of the PBI. The link types are also as follows:</p><ul><li><strong>Dependency-forward </strong>- Creates a "Successor" relationship</li><li><strong>Dependency-reverse </strong>- Creates a "Predecessor" relationship</li><li><strong>Hierarchy-forward </strong>- Creates a "Child" relationship</li><li><strong>Hierarchy-reverse </strong>- Creates a "Parent" relationship</li></ul><h2>Save &amp; Test</h2><p>You flow should now look something like this.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png" data-image-dimensions="1205x808" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=1000w" width="1205" height="808" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461261534-Q766ITCEZH6GI8Z7ZFFL/Finished+Flow.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>Last but not least, give the flow a name and click "Create Flow"</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png" data-image-dimensions="1109x117" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=1000w" width="1109" height="117" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508460585721-CZ0JQSE1ZHZ9I53T3PA9/SaveFlow.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>Now you just need to go and update a PBI's state to "Testing" or whatever state you want and see the flow in action. If you click into the flow, you'll see the history of whenever it ran. If you need to tweak things, you can click on one of the previous runs, and run the flow away (after you've made changes)</p><p>I would love to have an event on Pull Request completed, so I can even automate the change of state from Committed to Testing.</p><p> </p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1508461213309-ZZJ0UQ087YPAGTIPZOYH/2017-10-20_11-59-59.png?format=1500w" medium="image" isDefault="true" width="1205" height="808"><media:title type="plain">Auto creating tasks/work items in Visual Studio Team Services (VSTS) with Microsoft Flow</media:title></media:content></item><item><title>Azure Active Directory - Bulk updating user profile attributes using PowerShell</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Tue, 26 Sep 2017 00:17:01 +0000</pubDate><link>http://ericphan.net/blog/2017/9/26/azure-active-directory-bulk-updating-user-profile-attributes-using-powershell</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:59c98e838419c2c62d3ef114</guid><description><![CDATA[At SMEx we are all for using cloud based SaaS products. We use Office 365 
and Azure AD to manage our users, and we use Exclaimer Cloud - Signatures 
for Office 365 to manage our email signatures.

The way Exclaimer works is that it reads profile info from Azure AD and 
generates a signature during message transport and applies it to the 
message. It's actually quite a neat solution.

At SMEx, we have three offices and we include the address of the office in 
the signature. So instead of creating three different signatures in 
Exclaimer, we wanted one signature that can pull the address from the 
user's profile attributes.]]></description><content:encoded><![CDATA[<p>At <a target="_blank" href="http://smexdigital.com">SMEx </a>we are all for using cloud based SaaS products. We use Office 365 and Azure AD to manage our users, and we use <a target="_blank" href="https://www.exclaimer.com.au/exclaimer-cloud/signatures-for-office-365/">Exclaimer Cloud - Signatures for Office 365</a> to manage our email signatures.</p><p>The way Exclaimer works is that it reads profile info from Azure AD and generates a signature during message transport and applies it to the message. It's actually quite a neat solution.</p><p>At SMEx, we have three offices and we include the address of the office in the signature. So instead of creating three different signatures in Exclaimer, we wanted one signature that can pull the address from the user's profile attributes.</p><p>In AzureAD we put each user into an AD Group by office so we just need to update the same address for all users in a group. Now whilst Azure AD provides a nice UI for updating profile attributes, it can become tedious if you need to update many users.&nbsp;</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png" data-image-dimensions="810x843" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=1000w" width="810" height="843" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384840827-8Q77WZOGVC0IRYJKYOS7/AzureAD-UserProfile.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>The solution was <a target="_blank" href="https://docs.microsoft.com/en-us/powershell/">PowerShell </a>and the <a target="_blank" href="https://docs.microsoft.com/en-us/powershell/azure/active-directory/install-adv2?view=azureadps-2.0">AzureAD module</a></p><p>All you need to do is:</p><ol><li>Import the AzureAD powershell module using&nbsp;<ol><li>Import-Module AzureAD</li></ol></li><li>Connect to Azure Active Directory using<ol><li>Connect-AzureAD</li><li>This pops open a Microsoft Live login window</li></ol></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png" data-image-dimensions="568x755" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=1000w" width="568" height="755" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384534047-69D3BU5106AK1VEQE1CS/azure-ad-signin.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol><li>Get a list of AD Groups and find the ID of the group to update<ol><li>Get-AzureADGroup</li></ol></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png" data-image-dimensions="581x135" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=1000w" width="581" height="135" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506384737478-QRUMEP4IEU0F6TTZ4SZ6/Get-AzureADGroup.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol><li>Update the profile attribute for all users in the group (in this case we are updating the Department field)<ol><li>Get-AzureAdGroupMember -ObjectId "&lt;Id of the group&gt;" | ForEach-Object -Process { Set-AzureADUser -ObjectId $_.Mail -Department "New Address/Value here" }</li></ol></li></ol><p>Below is a Gist you can use. All you need to do is replace the GroupID and the value to update. If you want to update an attribute other than Department you can see the list of available attributes here</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506385009386-2K5CL5ASBM0FKIN7YLVH/AzureAD-UserProfile.png?format=1500w" medium="image" isDefault="true" width="810" height="843"><media:title type="plain">Azure Active Directory - Bulk updating user profile attributes using PowerShell</media:title></media:content></item><item><title>Visual Studio Code - Must have extensions for the .NET Core Developer</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Sun, 24 Sep 2017 04:50:11 +0000</pubDate><link>http://ericphan.net/blog/2017/9/24/visual-studio-code-must-have-extensions-for-the-net-core-developer</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:59c7309690bade1b592029c6</guid><description><![CDATA[Visual Studio Code is my preferred IDE for .NET Core development because:

    * It's fast
    * It's highly customizable
    * And did I mention fast?

So as a .NET Core developer, here's my list of must have extensions....]]></description><content:encoded><![CDATA[<p>Visual Studio Code is my preferred IDE for .NET Core development because:</p><ul><li>It's fast</li><li>It's highly customizable</li><li>And did I mention fast?</li></ul><p>So as a .NET Core developer, here's my list of must have extensions:</p><ul><li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp">C#</a> - you need this to get intelli sense, Go to definition, Find all references</li><li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=tintoy.msbuild-project-tools">MS Build Project Tools</a> - Gives you NuGet package intellisense in the *.proj files</li></ul>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png" data-image-dimensions="1289x508" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=1000w" width="1289" height="508" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228094756-X49BQR0HWRQTTVV6BRAV/msbuildtools.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ul><li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ms-vsts.team">Visual Studio Team Services</a> - Lets to integrate with TFS/Visual Studio.com and access Work Items</li><li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=robertohuertasm.vscode-icons">vscode-icons</a>&nbsp;- Turns VS Code from this</li></ul>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG" data-image-dimensions="304x300" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=1000w" width="304" height="300" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228253606-4DBHSCSBF0ARSAJ9YX8U/vscode-plain.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>to this</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG" data-image-dimensions="680x1431" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=1000w" width="680" height="1431" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506227075240-E4HS0IZS37T7G1LVB32P/vscode-icons.PNG?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>I think these 4 extensions are the bare minimum, but the following are highly recommended<a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens">:</a></p><ul dir="ltr"><li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens">GitLens</a>&nbsp;- Give you more git stats using CodeLens</li><li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=jchannon.csharpextensions">C# Extensions</a>&nbsp;- Give you more refactoring and text expansion snippets for C#</li></ul><p>Do you have other awesome extensions that you use? Let me know in the comment.</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1506228578207-LAPHXO0PTBRYHGBBF899/vscode-icons.PNG?format=1500w" medium="image" isDefault="true" width="680" height="656"><media:title type="plain">Visual Studio Code - Must have extensions for the .NET Core Developer</media:title></media:content></item><item><title>Octopus Deploy - Schedule a deployment at a given time using Azure Functions</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Tue, 29 Aug 2017 01:56:15 +0000</pubDate><link>http://ericphan.net/blog/2017/8/29/octopus-deploy-schedule-a-deployment-at-a-given-time-using-azure-functions</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:59a4c05b03596ef2c21d4e6b</guid><description><![CDATA[At SMEx Digital we have a distributed Scrum development team with resources 
in Australia and South Africa. Typically at the start of the day in 
Australia, the QA resource logs into Octopus deploy and pushes that latest 
version from Dev to QA to perform integration tests, as there would be new 
commits coming overnight from the team in South Africa.

So to save the tester roughly 10 minutes each morning waiting for 
environments to be deployed to QA, I decided to automate this process using 
Octopus Deploy and Azure Functions]]></description><content:encoded><![CDATA[<p>At <a target="_blank" href="http://smexdigital.com">SMEx Digital</a> we have a distributed Scrum development team with resources in Australia and in South Africa. Typically at the start of the day in Australia, the QA resource logs into Octopus deploy and pushes that latest version from Dev to QA to perform integration tests, as there would be new commits coming overnight from the team in South Africa.</p><blockquote><strong>Note</strong>: We made a conscious decision not to automatically deploy to QA as the testers were being interrupted as when a developer commits code, the code got built and pushed to QA giving them a few minutes of down time.</blockquote><p>So to save the tester roughly 10 minutes each morning waiting for environments to be deployed to QA, I decided to automate this process.</p><p>Unfortunately, <a target="_blank" href="https://octopus.com">Octopus Deploy</a> doesn't have built in capabilities to schedule a deployment at a given time every day, but thankfully Octopus Deploy has a great <a target="_blank" href="https://octopus.com/docs/api-and-integration/octopus-rest-api">API </a>that will let you automate pretty much everything.</p><p>This is where the new <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference">Azure Functions</a> and the Trigger come in handy.</p><p>1. In <strong>Microsoft Azure</strong> create a new <strong>Function App</strong></p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png" data-image-dimensions="308x510" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=1000w" width="308" height="510" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503969951253-PY1LY0SOCPVDRJUXEA8V/azure-create-function-app.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>2. Create a <strong>New Function</strong></p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png" data-image-dimensions="814x376" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=1000w" width="814" height="376" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970248787-SQDD6AXAG6DOS480HLZ4/Azure-Functions-New-Function.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>3. Select <strong>TimerTrigger - C#</strong> and fill in a <a target="_blank" href="https://www.freeformatter.com/cron-expression-generator-quartz.html">Cron expression</a> that represents when you want to run the function</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png" data-image-dimensions="758x794" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=1000w" width="758" height="794" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970350296-IOZX1VNEV73CAIAVH9O5/AzureFunctions-TimeTrigger.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>4. We want to add the <strong>Octopus.Client</strong> as a NuGet reference, so select your function | <strong>View Files | Add</strong> | Add a new<strong> project.json</strong> file with the following content &nbsp;</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles" data-image-dimensions="537x208" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=1000w" width="537" height="208" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503970800662-YZ23YPOUSNWBEX2F7EKR/AzureFunctions-AddFiles?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  



  
    <pre class="source-code">{
  <span class="cm-string">"frameworks"</span>: {
    <span class="cm-string">"net46"</span>:{
      <span class="cm-string">"dependencies"</span>: {
        <span class="cm-string">"Octopus.Client"</span>: <span class="cm-string">"4.5.0"</span>
      }
    }
   }
}</pre>
  




  <p>5. Now select the run.csx and paste in the code that will trigger the deployments</p>
























  
    <pre class="source-code">using System;
using Octopus.Client;
using Octopus.Client.Model;


public static async Task Run(TimerInfo myTimer, TraceWriter log)
{
    log.Info($"DeployToQA function executed at: {DateTime.Now}");
    log.Info($"Octopus URL: {GetSetting("OctopusUrl")}");
    var endpoint = new OctopusServerEndpoint(GetSetting("OctopusUrl"), GetSetting("OctopusApiKey"));
    var environmentId = GetSetting("OctopusQAEnvironmentId");

    using (var client = await OctopusAsyncClient.Create(endpoint))
    {
        var projects = await client.Repository.Projects.FindMany(x =&gt; !x.IsDisabled);
        foreach (var project in projects)
        {
            log.Info($"Checking project: {project.Name}");
            // Get the latest release
            var releases = await client.Repository.Projects.GetReleases(project);
            var release = releases.Items.FirstOrDefault();
            if (release != null) 
            {
                log.Info($"Latest release is {release.Version} with Id {release.Id}");
                // See if this release is already deployed to QA
                var deploymentQA = await client.Repository.Deployments.FindOne(x =&gt; x.ProjectId == project.Id &amp;&amp; x.ReleaseId == release.Id &amp;&amp; x.EnvironmentId == environmentId);
                if (deploymentQA == null)
                {                    
                    log.Info($"Deploying release {release.Version} to QA");
                    await client.Repository.Deployments.Create(new Octopus.Client.Model.DeploymentResource
                    {
                        EnvironmentId = environmentId,
                        ProjectId = project.Id,
                        ReleaseId = release.Id
                    });
                }
                else {
                    log.Info($"Release {release.Version} is already on QA");

                }
            }
        }
    }

}

public static string GetSetting(string name) =&gt;  System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);</pre>
  




  <p>This code loops through all the active projects, gets the latest release and checks to see if it has been deployed to the QA environment already. If it hasn't then it creates the deployment.</p><p>6. Next setup the application variables that the script uses. Click on the Function App in the left nav then select Application Settings</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings" data-image-dimensions="714x445" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=1000w" width="714" height="445" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971107920-DTTQR81O2ANHMCYJG87P/AzureFunctions-ApplicationSettings?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>7. Add keys for:</p><ul dir="ltr"><li>OctopusUrl - URL to your Octopus Deploy server</li><li>OctopusApiKey - API key (Generate one from your profile page in Octopus Deploy)</li><li>OctopusQAEnvironmentId - The ID of the environment (edit the environment, the ID is in the URL, it should be in the form "Environments-&lt;id&gt;"</li></ul>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings" data-image-dimensions="753x415" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=1000w" width="753" height="415" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971363295-NWD4WQ22ESNIKP3C2IGF/AzureFunctions-AppSettings?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>8. Now you can test your function. Go back to the run.csx and click Run</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run" data-image-dimensions="606x288" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=1000w" width="606" height="288" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971470443-00DNP87LVTXHNLPVKYBP/AzureFunctions-Run?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  













































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log" data-image-dimensions="1027x277" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=1000w" width="1027" height="277" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503971719264-GUHE3AMMDBX3GMFS55SB/AzureFunctions-Log?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>Now every morning when the tester comes in, there's a fresh deployment for them to start testing on!</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1503976158726-ICH51FTGA08UKSYNOWL3/2017-08-29_11-30-15.png?format=1500w" medium="image" isDefault="true" width="814" height="376"><media:title type="plain">Octopus Deploy - Schedule a deployment at a given time using Azure Functions</media:title></media:content></item><item><title>SSRS - Find out which reports area being used (handy for migrating only the useful reports to a new server)</title><category>Development</category><category>SSW</category><dc:creator>Eric Phan</dc:creator><pubDate>Mon, 12 Sep 2016 01:01:37 +0000</pubDate><link>http://ericphan.net/blog/2016/9/12/ssrs-find-out-which-reports-area-being-used-handy-for-migrating-only-the-useful-reports-to-a-new-server</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:57d5f6eb29687f1a258c2c1f</guid><description><![CDATA[At SSW, we are currently migrating our SQL Server Reporting Services 2008 
R2 reports to our new SQL Server Reporting Services 2016 server.

If you haven't decided to make the move to SSRS 2016 you should check out 
What's New in Reporting Services (SSRS). The main features we care about 
are:

    * Better Portal
    * Mobile Reports
    * PowerBI integration
    * Better HTML5 report rendering]]></description><content:encoded><![CDATA[<p>At <a target="_blank" href="https://www.ssw.com.au">SSW</a>, we are currently migrating our SQL Server Reporting Services 2008 R2 reports to our new SQL Server Reporting Services 2016 server.</p><p>If you haven't decided to make the move to SSRS 2016 you should check out <a target="_blank" href="https://msdn.microsoft.com/en-us/library/ms170438.aspx">What's New in Reporting Services (SSRS)</a>. The main features we care about are:</p><ul dir="ltr"><li>Better Portal</li><li>Mobile Reports</li><li>PowerBI integration</li><li>Better HTML5 report rendering</li></ul><p>As part of the migration process, we needed to assess which reports were actively being used so that we only migrated the useful reports and not the legacy baggage.</p><p>Thankfully, this is easily done as SSRS keeps an execution log for all the reports that it renders. The only thing you'll need to consider is how long that execution log tracks data for. The default is 60 days. If you want to update this to a longer period then the rule <a target="_blank" href="https://rules.ssw.com.au/do-you-keep-track-of-which-reports-are-being-executed">Do you keep track of which reports are being executed?</a>. Thankfully at SSW, this was already set to retain the logs for 365 days.</p><p>So all that's left to do is write a query against the ExecutionLog table in the ReportServer database</p>
























  
    <pre class="source-code">WITH RankedReports
AS
(SELECT ReportID,
        TimeStart,
        UserName, 
        RANK() OVER (PARTITION BY ReportID ORDER BY TimeStart DESC) AS iRank
   FROM dbo.ExecutionLog t1
        JOIN 
        dbo.Catalog t2
          ON t1.ReportID = t2.ItemID
)
SELECT t2.Name AS ReportName,
       MAX(t1.TimeStart) LastAccessed,
       --t1.UserName,
       t2.Path,    
       SUBSTRING(t2.Path, 0, CHARINDEX('/', t2.Path, 2)) ParentFolder,
       t1.ReportID
  FROM RankedReports t1
       JOIN 
       dbo.Catalog t2
         ON t1.ReportID = t2.ItemID
 WHERE t1.iRank = 1
GROUP BY t2.Name, Path, ReportID
ORDER BY MAX(t1.TimeStart) DESC;</pre>
  




  <p>Credit goes to <a target="_blank" href="http://stackoverflow.com/a/11042684">Russell Fox</a> for this query (I've modified this to give distinct reports)</p>]]></content:encoded></item><item><title>Solving the TFS Build Agent Error - The session for this agent already exists</title><category>Development</category><category>SSW</category><dc:creator>Eric Phan</dc:creator><pubDate>Fri, 10 Jun 2016 02:43:22 +0000</pubDate><link>http://ericphan.net/blog/2016/6/10/solving-the-tfs-build-agent-error-the-session-for-this-agent-already-exists</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:575a26c53c44d8a71ac558af</guid><description><![CDATA[Recently we've been getting the following error for our TFS build agents 
which caused all our builds to fail

The error reported is "The job has been abandoned because agent <agent 
name> did not renew the lock. Ensure agent is running, not sleeping, and 
has not lost communication with the service."

Investigating the _diag folder of the build agent itself reveals the actual 
error.]]></description><content:encoded><![CDATA[<p>Recently we've been getting the following error for our TFS build agents which caused all our builds to fail</p>

































































 

  
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError" data-image-dimensions="760x388" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=1000w" width="760" height="388" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526331012-IMBW1QH0GUFKK0KE3EHQ/TFSBuildError?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Figure: TFS Builds are failing</p>
          </figcaption>
        
      
        </figure>
      

    
  






  <p>The error reported is "The job has been abandoned because agent &lt;agent name&gt;&nbsp;did not renew the lock. Ensure agent is running, not sleeping, and has not lost communication with the service."</p><p>Investigating the _diag folder of the build agent itself reveals the actual error.</p>
























  
    <pre class="source-code">---------------------------------------------------------------------------
The session for this agent already exists. Sleeping for 30 seconds before next retry. Attempts=1/10.
---------------------------------------------------------------------------
Microsoft.TeamFoundation.DistributedTask.WebApi.TaskAgentSessionConflictException: The task agent Agent-SYDTFSBLDP01-1 already has an active session for owner SYDTFSBLDP01.
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.HandleResponse(HttpResponseMessage response)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__79.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__76`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__65`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__64`1.MoveNext()
  at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.HandleResponse(HttpResponseMessage response)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__79.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__76`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__65`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<span class="cm-tag cm-bracket">&lt;</span><span class="cm-tag">SendAsync</span><span class="cm-tag cm-bracket">&gt;</span>d__64`1.MoveNext()</pre>
  




  <p>To fix this issue, you need to re-run the ConfigureAgent.cmd and on the first option "Do you want to also replace the server registration (default is N)" Choose "Y"</p>
























  
    <pre class="source-code">PS C:\Agents\2&gt; .\ConfigureAgent.cmd
An existing configuration file was detected.  This will update the local agent settings.  Do you want to also replace th
e server registration (default is N)? Y
</pre>
  




  <p>This will remove the existing agent registration and clean up the locked "session".</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1465526750071-GMQY65MVPDX7EMZPDRXS/2016-06-10_12-36-18.png?format=1500w" medium="image" isDefault="true" width="760" height="388"><media:title type="plain">Solving the TFS Build Agent Error - The session for this agent already exists</media:title></media:content></item><item><title>Visual Studio 2015 hangs when publishing a website</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Thu, 28 Jan 2016 01:26:14 +0000</pubDate><link>http://ericphan.net/blog/2016/1/28/visual-studio-2015-hangs-when-publishing-a-website</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:56a95f52be7b96c6877cf3e8</guid><description><![CDATA[For the last month or so I've been living with my Visual Studio 2015 
hanging for up to two minutes when simply right clicking on the web project 
and selecting Publish.

Well today I got fed up with waiting and went to search for solutions. I 
stumbled across this Stack Overflow answer  from Mike.]]></description><content:encoded><![CDATA[<figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang" data-image-dimensions="562x125" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=1000w" width="562" height="125" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453940972974-68SFIZIR7UB93C77XWDX/VisualStudio2015-Hang?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>For the last month or so I've been living with my Visual Studio 2015 hanging for up to two minutes when simply right clicking on the web project and selecting <strong>Publish</strong>&nbsp;(before the publishing UI comes up)</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png" data-image-dimensions="509x385" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=1000w" width="509" height="385" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453941201934-E6FM2Y69QC2JSYMP0XBA/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>Well today I got fed up with waiting and went to search for solutions. I stumbled across this <a target="_blank" href="http://stackoverflow.com/a/32885126/77555">Stack Overflow answer</a>&nbsp;&nbsp;from <a target="_blank" href="http://stackoverflow.com/users/2217954/mike">Mike</a>.</p><p>Following the instructions:</p><ol dir="ltr"><li>Open the <strong>Properties </strong>of the web application you are trying to publish</li><li>Select <strong>Package/Publish SQL (click Enable This Page if available)&nbsp;</strong></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png" data-image-dimensions="794x366" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=1000w" width="794" height="366" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944088681-69DT5SJ917HK633C0BZD/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <ol dir="ltr"><li>Click <strong>Import from web.config</strong></li><li>Uncheck all the options</li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png" data-image-dimensions="766x878" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=1000w" width="766" height="878" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944348410-2N1AND7J6TF3BQ05S6A0/image-asset.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>Now right clicking and Publishing only takes a few seconds before the Publishing UI comes up</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453944245495-44CKUU73NEQ2NEGKUZ3F/image-asset.png?format=1500w" medium="image" isDefault="true" width="562" height="125"><media:title type="plain">Visual Studio 2015 hangs when publishing a website</media:title></media:content></item><item><title>Consolidating NuGet Package versions</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Thu, 21 Jan 2016 23:24:12 +0000</pubDate><link>http://ericphan.net/blog/2016/1/22/consolidating-nuget-package-versions</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:56a166b95dc6de06062e4034</guid><description><![CDATA[One of my pet peeves is having differently versioned NuGet packages across 
my projects. Previously I would just dig around in the packages.config of 
each project and check if the versions are consistent and install the right 
versioned package. Never again!]]></description><content:encoded><![CDATA[<p>One of my pet peeves is having differently versioned NuGet packages across my projects. Previously I would just dig around in the packages.config of each project and check if the versions are consistent and install the right versioned package. Never again!</p><p>Last week I discovered that the solution wide NuGet package manage in Visual Studio 2015 has a "Consolidate" tab for this exact purpose.&nbsp;</p><p>Simply go to <strong>Tools | NuGet Package Manager | Manage NuGet Packages for Solution...</strong></p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png" data-image-dimensions="702x288" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=1000w" width="702" height="288" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418369535-JCD39DEQECE2HBLUSJWF/Manage-NuGet-Packages-For-Solution.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>Then click on the <strong>Consolidate</strong> tab</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
              
              
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png" data-image-dimensions="1140x790" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=1000w" width="1140" height="790" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418455176-XE1WWXM0HOJPK7GYBR11/Consolidate-NuGet-Packages.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
            
          
        

        
      
        </figure>
      

    
  


  





  <p>Select the out of date projects, then click <strong>Install</strong></p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1453418655644-DR580PCB17570KTKCKPK/image-asset.png?format=1500w" medium="image" isDefault="true" width="1140" height="790"><media:title type="plain">Consolidating NuGet Package versions</media:title></media:content></item><item><title>Test Driving the Tesla Model S</title><category>Stuff</category><dc:creator>Eric Phan</dc:creator><pubDate>Mon, 29 Jun 2015 11:47:00 +0000</pubDate><link>http://ericphan.net/blog/2015/12/16/test-driving-the-tesla-model-s</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:5671414e1115e008c1d385bd</guid><description><![CDATA[Thanks Adam for lending me his Tesla Model S for the last two weeks. It has 
been really fun to drive and both Hayden and Michelle love it. Hayden’s 
going to miss it!]]></description><content:encoded><![CDATA[<p><span>Thanks <a target="_blank" href="http://adamcogan.com">Adam</a> for lending me his Tesla for the last two weeks. It has been really fun to drive and both Hayden and Michelle love it. Hayden’s going to miss it!</span></p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg" data-image-dimensions="3264x2448" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=1000w" width="3264" height="2448" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263574053-Q7KR9PXJ6ASLNEW6H2FT/image-asset.jpeg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p><span>&nbsp;For me the biggest positives were:</span></p><ol><li><span>Quietness and smoothness of the ride (Yes after having kids, quietness is important! No hooning while the kids are asleep!)</span></li><li><span>The instant feedback when you push the accelerator and how easily it goes uphills</span></li><li><span>The 17” center console (I pretty much have maps + rear view camera on all the time)</span></li><li><span>The turn by turn navigation right next to the speedo</span></li><li><span>Space, lots of it for passengers and groceries and whatever else you need</span></li><li><span>Child seat anchors are nicely hidden so if you don’t use them you can’t even see that they’re there</span></li><li><span>The awesome reversing camera and markings that change based on how you rotate the wheel make it really easy to reverse.</span></li><li><span>The mobile app that allows you to turn the car on/off, lock, turn on climate control (air conditioning), see the charging status and where the car is parked</span></li><li><span>Cruise control is pretty smart too, slows and accelerates when needed</span></li><li><span>Michelle’s favorite – heated seats and the ability to turn on climate control before you enter the car, so it can be as warm or cool as you want</span></li></ol><p><span>&nbsp;There are a lot of little nice touches too like:</span></p><ol><li><span>Mirrors turn downwards when you reverse</span></li><li><span>The lights on the handles when they extend out</span></li><li><span>Bluetooth phone connectivity just resumes playing when you get in the car</span></li><li><span>The charge port opening when the charger gets close </span></li></ol>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg" data-image-dimensions="3264x2448" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=1000w" width="3264" height="2448" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263623952-VI4EX5ZZ2W3IFB6SDNYI/image-asset.jpeg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p id="yui_3_17_2_1_1450262791720_41354"><span>The negatives were:</span></p><ol><li><span>It’s wider than you expect, so you have to be a bit cautious on the narrow Sydney streets or when passing between trucks :)</span></li><li><span>I had to reboot the car/consoles once during the two weeks when the 3G connection stopped working (still had many bars of reception, but it was not getting any internet connectivity, so google maps were limited)</span></li><li><span>The slowness of the home charger (~13km per hour) – so from flat it would take 24 hrs to fully charge. This would obviously not be a problem once more super charging infrastructure is in place.</span></li></ol><p><span>&nbsp;Improvements:</span></p><ol><li><span>Auto speed detection by sign reading is a bit flakey. When driving in highways and freeways it incorrectly detects the exit lane speeds when you’re not exiting, causing the speeding warning to incorrectly chime.</span></li><li><span>If you forget to close the charge port and are driving, it should just close it for you.&nbsp;</span></li><li><span>Having the heavy regenerative braking on sort of detracts away from defensive driving where you want to rest your foot on the brake, so that if there’s any surprises, your foot can slam on the brakes quicker. So I’m a bit up in the air about this feature. I’m wondering if there could be some sort of hybrid, where you can take your foot off the accelerator, the light regenerative braking kicks in, and when you apply some pressure to the brakes, the heavy regenerative braking kicks in.</span></li></ol><p><span>&nbsp;</span></p><p><span>Overall it’s an excellent car. It a lot wider than you expect, it drives quietly and smoothly. And the best part is, that it's brains are upgradable over the air thanks to it's 3G connection. I can't wait to take it for a spin again once Auto Pilot is rolled out.</span></p>]]></content:encoded><media:content type="image/jpeg" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1450263743573-SFT08LF9K9QDTK18GRE1/image-asset.jpeg?format=1500w" medium="image" isDefault="true" width="1500" height="1125"><media:title type="plain">Test Driving the Tesla Model S</media:title></media:content></item><item><title>KendoUI - Grid - Footer Template Formatting</title><category>SSW</category><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Tue, 12 Nov 2013 23:47:35 +0000</pubDate><link>http://ericphan.net/blog/2013/11/13/kendoui-grid-footer-template-formatting</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:5282be27e4b01e8cfd57f537</guid><description><![CDATA[Ran into an issue today whereby I was showing an aggregated Sum in the 
footer of a column. This worked correctly but the number was not formatted 
and showed 6 decimal places.

Looking through the KendoUI docs and forums yielded plenty of results, but 
this was all for client side binding and formatting.]]></description><content:encoded><![CDATA[<p>Ran into an issue today whereby I was showing an aggregated Sum in the footer of a column. This worked correctly but the number was not formatted and showed 6&nbsp;decimal places.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png" data-image-dimensions="378x219" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=1000w" width="378" height="219" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384300351079-NKXGO0LZS2QU0W2SGGV2/13-11-2013+10-51-35+AM.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Figure: Bad - The sum isn&#39;t formatted nicely</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>Looking through the KendoUI docs and forums yielded plenty of results, but this was all for client side binding and formatting.</p>
























  
    <pre class="source-code">.ClientFooterTemplate("Sum: #= kendo.toString(sum, 'n0') #")</pre>
  




  <p>This didn't work for my scenario as I wasn't using AJAX or client side binding, I was using a local binding to an MVC model.</p><p>The trick was to fiddle with the .FooterTemplate fluent method to format the value. So instead of just doing:</p>
























  
    <pre class="source-code">.FooterTemplate(f =&gt; f.Sum)</pre>
  




  <p>You can do:</p>
























  
    <pre class="source-code">.FooterTemplate(f =&gt; { return (object)((decimal)f.Sum.Value).ToString("N0"); })</pre>
  




  <p>The trick here is that the FooterTemplate method takes an Func&lt;GridAggregateResult, object&gt;, so have to cast the GridAggregateResult to our number type, format it and cast it back to an object.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png" data-image-dimensions="342x184" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=1000w" width="342" height="184" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301099131-FXI5F7X8BPH6X4F0CJ1R/13-11-2013+11-04-33+AM.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Figure: Good Example - Our footer value is nicely formatted</p>
          </figcaption>
        
      
        </figure>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1384301195888-4O8JKDDOGRB5JRPHFGC1/13-11-2013+11-06-10+AM.png?format=1500w" medium="image" isDefault="true" width="974" height="647"><media:title type="plain">KendoUI - Grid - Footer Template Formatting</media:title></media:content></item><item><title>Suggestion - Visual Studio 2013 - Team Explorer Home window</title><category>SSW</category><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Fri, 18 Oct 2013 00:12:57 +0000</pubDate><link>http://ericphan.net/blog/2013/10/18/suggestion-visual-studio-2013-team-explorer-home-window</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:5260792ee4b0f18da0d7f7af</guid><description><![CDATA[I have been using Visual Studio 2013 for a while now (Preview, RC and now 
RTM) and one thing that I believe can improve the development experience is 
the Team Explorer - Home window/hub.]]></description><content:encoded><![CDATA[<p>I have been using <a href="http://www.microsoft.com/visualstudio/eng" target="_blank">Visual Studio 2013</a> for a while now (Preview, RC and now RTM) and one thing that I believe can improve the development experience is the <strong>Team Explorer - Home</strong> window/hub. This is what it looks like now:&nbsp;</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png" data-image-dimensions="367x459" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=1000w" width="367" height="459" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382055205087-CXSSS2N13U0W068CBQZ3/18-10-2013+10-00-42+AM.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Figure: The Home hub in VS2013 Team Explorer</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>So these are static elements and not very informational. What I find when I'm using the <strong>Team Explorer</strong> window is that I'm usually in the <strong>My Work</strong> or <strong>Pending Changes</strong> hubs and that I rarely use the <strong>Home </strong>hub. </p><p>I don't see the home screen as being useful at all when I can also get to the hubs using the dropdown menu</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png" data-image-dimensions="371x311" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=1000w" width="371" height="311" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056759310-BPQHIBJQSDP2W814POZU/18-10-2013+11-38-20+AM.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Figure: Bypass the Home hub using the dropdown</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p></p><p></p><p>What would make me use the <strong>Home </strong>hub more is if there was useful information presented on it:</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png" data-image-dimensions="367x536" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=1000w" width="367" height="536" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056216477-JCYPZMFSGMIYKVHEHPZR/VS2013-TeamExplorer-Home-Mockup.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>Figure: Good example - The home dashboard provides useful information at a glance without the user needing to click into each hub</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>What I like about this mockup is that it makes the Home hub more useful for a developer with live information without needing to go into each hub.</p><p>So at a glance I can know:</p><ul><li>what I'm currently working on, </li><li>what changes I have to commit,</li><li>how the last build went and if it's safe to get latest</li><li>who the last person to checkin code was</li></ul><p>I understand that having this live information will impact on performance of this window (which is what the VS team spent a lot of time trying to optimize in VS2012 and VS2013), but I feel that the information is useful enough for this to be an opt in option that can be turned on in <strong>Settings</strong>&nbsp;</p><p>Agree? Disagree? I would love to know your thoughts...</p>


























  <p>EDIT: Added a <a href="http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4692565-team-explorer-home-make-it-more-functional-wit" target="_blank">user voice suggestion</a>. If you agree please vote :)</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1382056903017-UG2Z0EVJBR7699T42R5E/18-10-2013+10-00-42+AM.png?format=1500w" medium="image" isDefault="true" width="367" height="536"><media:title type="plain">Suggestion - Visual Studio 2013 - Team Explorer Home window</media:title></media:content></item><item><title>Javascript Corner - Font Awesome</title><category>SSW</category><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Tue, 15 Oct 2013 09:41:05 +0000</pubDate><link>http://ericphan.net/blog/2013/10/15/javascript-corner-font-awesome</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:525cfce5e4b0e89bfe812306</guid><description><![CDATA[I have been Font Awesome over the last year for all my web projects. It's 
goal is to do away with all the images that you need for a modern web 
application and replace them with a single font.

Why replace images with a font you may ask?

There are several advantages:

    * Fonts are scalable, so they look crisp at whatever size you want them
    * You can use all your font styles on these icons to style them (like
      size and colour)
    * All modern browsers support the download of custom fonts (there is a
      fallback to image sprites for old browsers)

Using it on your project is easy, just add the following stylesheet to your 
app:

<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">

Then you have access to over 350 icons. Here are a few that I use all the 
time: ]]></description><content:encoded><![CDATA[<link rel="stylesheet" href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css">

  




  <p>I have been using&nbsp;<a href="http://fortawesome.github.io/Font-Awesome/" target="_blank">Font Awesome</a> over the last year for all my web projects. It's goal is to do away with all the images that you need for a modern web application and replace them with a single font.</p><p>Why replace images with a font you may ask?</p><p>There are several advantages:</p><ul><li>Fonts are scalable, so they look crisp at whatever size you want them</li><li>You can use all your font styles on these icons to style them (like size and colour)</li><li>All modern browsers support the download of custom fonts (there is a fallback to image sprites for old browsers)</li></ul><p></p><p></p><p>Using it on your project is easy, just add the following stylesheet to your app:</p><p></p><p></p><p></p><p>&nbsp;</p>
























  
    <pre class="source-code"><span class="cm-tag">&lt;link</span> <span class="cm-attribute">href</span>=<span class="cm-string">"//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css"</span> <span class="cm-attribute">rel</span>=<span class="cm-string">"stylesheet"</span><span class="cm-tag">&gt;</span></pre>
  




  <p>Then you have access to over 350 icons. Here are a few that I use all the time:&nbsp;</p><p></p><p></p>
























  
    <i class="icon-edit icon-4x"></i>
<i class="icon-trash icon-4x"></i>
<i class="icon-plus icon-4x"></i>
<i class="icon-refresh icon-4x"></i>
<i class="icon-ok icon-4x"></i>
<i class="icon-remove icon-4x"></i>
<i class="icon-code icon-4x"></i>
<i class="icon-cloud-download icon-4x"></i>
  




  <p>The HTML is easy, just <strong>&lt;i class='icon-edit'&gt;&lt;/i&gt;, &lt;i class='icon-trash'&gt;&lt;/i&gt;</strong>&nbsp;</p><p>You can then add modifiers to control the size, rotation and even animation of the icon</p>
























  
    <ul>
<li><i class="icon-cloud-download"></i>
  &lt;i class='icon-cloud-download'&gt;&lt;/i&gt;  
</li>
<li>
  <i class="icon-cloud-download icon-2x"></i>
  &lt;i class='icon-cloud-download <strong>icon-2x</strong>'&gt;&lt;/i&gt; 
</li>
<li>
  <i class="icon-cloud-download icon-3x"></i>
  &lt;i class='icon-cloud-download <strong>icon-3x</strong>'&gt;&lt;/i&gt; 
</li>
<li>
  <i class="icon-cloud-download icon-4x"></i>
  &lt;i class='icon-cloud-download <strong>icon-4x</strong>'&gt;&lt;/i&gt;  
</li>
<li>
  <i class="icon-cloud-download icon-4x icon-spin"></i>
  &lt;i class='icon-cloud-download <strong>icon-spin</strong>'&gt;&lt;/i&gt;  
</li>
<li>
  <i class="icon-cloud-download icon-4x icon-rotate-90"></i>
  &lt;i class='icon-cloud-download <strong>icon-rotate-90</strong>'&gt;&lt;/i&gt;  
</li>
</ul>
  




  <p>Since it's a font, you can change the colour, simply by applying the "color" css style</p>
























  
    <i class="icon-ok icon-4x"></i>
<i class="icon-remove icon-4x"></i>
<i class="icon-twitter icon-4x"></i>
<i class="icon-facebook icon-4x"></i>
  




  <p>You can even combine icons together:&nbsp;</p>
























  
    <i class="icon-twitter icon-4x"></i> 
 combined with 
<i class="icon-check-empty icon-4x"></i>
makes 
<span class="icon-stack icon-4x">
  <i class="icon-check-empty icon-stack-base"></i>
  <i class="icon-twitter"></i>
</span>


  


  
    <pre class="source-code"><span class="cm-tag">&lt;span</span> <span class="cm-attribute">class</span>=<span class="cm-string">"icon-stack icon-4x"</span><span class="cm-tag">&gt;</span><br>  <span class="cm-tag">&lt;i</span> <span class="cm-attribute">class</span>=<span class="cm-string">"icon-check-empty icon-stack-base"</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;/i</span><span class="cm-tag">&gt;</span><br>  <span class="cm-tag">&lt;i</span> <span class="cm-attribute">class</span>=<span class="cm-string">"icon-twitter"</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;/i</span><span class="cm-tag">&gt;</span><br><span class="cm-tag">&lt;/span</span><span class="cm-tag">&gt;</span><br><br></pre>
  




  <p>These icons also play nicely with Twitter Bootstrap. Here is a practical example where you change the save icon to a spinner to indicate the AJAX call is being made. Click the "Submit Changes" button to see it in action</p>
























  
    <button id='submitButton' class='btn btn-default'><i class="icon-save"></i> Submit Changes</button>


  


  
    <pre class="source-code"><span class="cm-tag">&lt;button</span> <span class="cm-attribute">id</span>=<span class="cm-string">'submitButton'</span> <span class="cm-attribute">class</span>=<span class="cm-string">'btn btn-default'</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;i</span> <span class="cm-attribute">class</span>=<span class="cm-string">'icon-save'</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;/i</span><span class="cm-tag">&gt;</span> Submit Changes<span class="cm-tag">&lt;/button</span><span class="cm-tag">&gt;</span><br> <br><span class="cm-tag">&lt;script</span> <span class="cm-attribute">type</span>=<span class="cm-string">'text/javascript'</span><span class="cm-tag">&gt;</span><br>  <span class="cm-variable">$</span>(<span class="cm-keyword">function</span>() {<br>    <span class="cm-variable">$</span>(<span class="cm-string">"#submitButton"</span>).<span class="cm-property">click</span>(<span class="cm-keyword">function</span>() {<br>     <span class="cm-variable">$</span>(<span class="cm-string">"i"</span>, <span class="cm-variable-2">this</span>).<span class="cm-property">attr</span>(<span class="cm-string">"class"</span>, <span class="cm-string">"icon-refresh icon-spin"</span>);<br>      <span class="cm-variable">setTimeout</span>(<span class="cm-keyword">function</span>() { <span class="cm-variable">$</span>(<span class="cm-string">"#submitButton i"</span>).<span class="cm-property">attr</span>(<span class="cm-string">"class"</span>, <span class="cm-string">"icon-save"</span>); }, <span class="cm-number">2000</span>);<br>    });<br>  });<br><span class="cm-tag">&lt;/script</span><span class="cm-tag">&gt;</span></pre>
  




  <p>You can use these icons to spice up your forms:&nbsp;</p>
























  
    <form>
  
    <span class="add-on"><i class="icon-envelope"></i></span>
    <input placeholder="Email address" type="text" class="span2">
  
  
    <span class="add-on"><i class="icon-key"></i></span>
    <input placeholder="Password" type="password" class="span2">
  
</form>
  


  
    <pre class="source-code"><span class="cm-tag">&lt;form</span><span class="cm-tag">&gt;</span><br>  <span class="cm-tag">&lt;div</span> <span class="cm-attribute">class</span>=<span class="cm-string">"input-prepend"</span><span class="cm-tag">&gt;</span><br>    <span class="cm-tag">&lt;span</span> <span class="cm-attribute">class</span>=<span class="cm-string">"add-on"</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;i</span> <span class="cm-attribute">class</span>=<span class="cm-string">"icon-envelope"</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;/i</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;/span</span><span class="cm-tag">&gt;</span><br>    <span class="cm-tag">&lt;input</span> <span class="cm-attribute">class</span>=<span class="cm-string">"span2"</span> <span class="cm-attribute">type</span>=<span class="cm-string">"text"</span> <span class="cm-attribute">placeholder</span>=<span class="cm-string">"Email address"</span><span class="cm-tag">&gt;</span><br>  <span class="cm-tag">&lt;/div</span><span class="cm-tag">&gt;</span><br>  <span class="cm-tag">&lt;div</span> <span class="cm-attribute">class</span>=<span class="cm-string">"input-prepend"</span><span class="cm-tag">&gt;</span><br>    <span class="cm-tag">&lt;span</span> <span class="cm-attribute">class</span>=<span class="cm-string">"add-on"</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;i</span> <span class="cm-attribute">class</span>=<span class="cm-string">"icon-key"</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;/i</span><span class="cm-tag">&gt;</span><span class="cm-tag">&lt;/span</span><span class="cm-tag">&gt;</span><br>    <span class="cm-tag">&lt;input</span> <span class="cm-attribute">class</span>=<span class="cm-string">"span2"</span> <span class="cm-attribute">type</span>=<span class="cm-string">"password"</span> <span class="cm-attribute">placeholder</span>=<span class="cm-string">"Password"</span><span class="cm-tag">&gt;</span><br>  <span class="cm-tag">&lt;/div</span><span class="cm-tag">&gt;</span><br><span class="cm-tag">&lt;/form</span><span class="cm-tag">&gt;</span></pre>
  




  <p>This library is a must for all web projects :)&nbsp;</p>]]></content:encoded><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1381830715083-ORVTT2BHDQLZQGGHV0M4/Screen+Shot+2013-10-15+at+8.51.29+pm.png?format=1500w" medium="image" isDefault="true" width="1216" height="421"><media:title type="plain">Javascript Corner - Font Awesome</media:title></media:content></item><item><title>Javascript Corner - jquery.lazyload</title><dc:creator>Eric Phan</dc:creator><pubDate>Fri, 26 Apr 2013 04:58:25 +0000</pubDate><link>http://ericphan.net/blog/2013/4/24/javascript-corner-jquerylazyload</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:51773d71e4b084b94e4a31f9</guid><description><![CDATA[<p>I've used this usefully little plugin on several projects, and <a target="_blank" href="http://www.hanselman.com/">Scott Hansleman</a> recently highlighted it in his <a target="_blank" href="http://www.hanselman.com/blog/PinchingPenniesWhenScalingInTheCloud.aspx">Pinching pennies when scaling in The Cloud</a> blog post. It's useful for situations where:</p><ul><li>ou want to load images based on some convention but aren't sure if they exist</li><li>You want to load only images that the use is able to see on their page</li></ul><h2>&nbsp;</h2><p>ake this example that I've been working on this week. It's a leader board for our timesheeting application that shows the current top biller for the year</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
              
              
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg" data-image-dimensions="1630x660" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=1000w" width="1630" height="660" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366932005799-WH27T1RHPPP600LTRCM0/missing-images.jpg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
            
          
        

        
      
        </figure>
      

    
  


  





  <p>Figure: Bad Example - Broken images everywhere</p><p>n this instance, the employee profile images are being loaded by convention, and not all employees have photos, that's why you see broken images here. Now there's a few ways of solving this:</p><ol><li>heck the file system for the employee file (this has a few problems)</li><li>heck via HTTP the image exists on the external server</li></ol><p>The problem with checking the file system is, that the file can still be broken if it is trying to get an image served from a CDN instead,&nbsp;</p><p>Checking via <a href="http://stackoverflow.com/questions/830435/how-to-check-if-a-file-exists-on-a-server-using-c-sharp-and-the-webclient-class">HTTP headers is possible</a> and can be done without downloading the file but as always, if you have lots of files this can slow down the rending of your page.</p><p>jQuery.LazyLoad is a great client side solution as we first render a placeholder image and then (on the client side) request the actual image and then replace the placeholder with the downloaded image. It's very lightweight and simple to use.</p><ol></ol><ul><li>Reference the jquery.lazyload.min.js file</li></ul><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
























  
    <pre class="prettyprint linenums">
&lt;script src="@Url.Content("~/Scripts/jquery.lazyload.min.js")"&gt;&lt;/script&lt;
</pre>
  




  <ul><li>Render the image tags as follows:</li></ul>
























  
    <pre class="prettyprint linenums">
 &lt;img class="full lazy" data-original="@emp.PhotoUrl" src="@Url.Content("~/Content/EmpPhotos/placeholder.png")" /&gt;
</pre>
  




  <ul><li>Call the lazyload() method on document ready</li></ul>
























  
    <pre class="prettyprint linenums">
   &lt;script&gt;
        $(function() {
            $("img.lazy").lazyload();
        });
    &lt;/script&gt;
</pre>
  




  <p>Now all the broken images have a place holder image by default, and the client downloads and replaces the employee photos for employees who actually do have a photo.</p>


































































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg" data-image-dimensions="1636x620" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=1000w" width="1636" height="620" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366952914052-Z6ZPPUNW6OSB17UIICAK/26-04-2013+9-04-48+AM.jpg?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
      
        </figure>
      

    
  


  





  <p>Figure: Good Example - Image placeholders show up instead of broken images</p>]]></description></item><item><title>Javascript Corner - jquery.cookie</title><dc:creator>Eric Phan</dc:creator><pubDate>Mon, 22 Apr 2013 08:30:30 +0000</pubDate><link>http://ericphan.net/blog/2013/4/18/javascript-corner-jquerycookie</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:516fe52de4b06eef91809473</guid><description><![CDATA[<p>​I'm trying to do a regular post on useful javascript libraries and plugins to existing frameworks such as <a href="http://jquery.com" target="_blank">jQuery</a>, <a href="http://knockoutjs.com" target="_blank">knockoutJs</a> etc...</p><p>​So to kick things off, let me introduce <a href="https://github.com/carhartl/jquery-cookie" target="_blank">jquery.cookie</a>. This usefully little library allows you to get and set cookies on the client side. Now why might you want to do this?</p><ul><li>​Serve up a generic cached page and personalize based on cookie information (a lot of sites do this, like eBay shows your name, but will still require you to sign in)</li><li>Retrieve some information via AJAX and save it to a cookie</li></ul><p>​I've used this on several projects in the past, and it's nice and easy to use.</p><ol></ol><ul><li>Reference the script in your page</li><li>Grab a copy from ​<a href="https://github.com/carhartl/jquery-cookie">https://github.com/carhartl/jquery-cookie</a></li></ul><p>​</p>
























  
    <pre class="prettyprint linenums">
&lt;script src="/path/pto/jquery.cookie.js"&gt;&lt;/script&gt;
</pre>
  




  <ul><li>.Set a cookie</li></ul>
























  
    <pre class="prettyprint linenums">
var userProfile = {
    Name: 'Eric Phan',
    Age: 28,
    LastLogin: '2013-04-22 11:24 PM' 
};

var cookieOptions = {
    expires: 7, // expire in 7 days	
    path: '/', // path of the cookie
    domain: 'ericphan.net', // domain the cookie is valid for
    secure: false // whether to transmit the cookie over HTTPS
};

// Need to store the JSON data as string
$.cookie('UserProfile', JSON.stringify(userProfile), cookieOptions);
</pre>
  












































  

    
  
    

      

      
        <figure class="
              sqs-block-image-figure
              intrinsic
            "
        >
          
        
        

        
          
            
              
              
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png" data-image-dimensions="1213x95" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=1000w" width="1213" height="95" sizes="(max-width: 640px) 100vw, (max-width: 767px) 100vw, 100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1366604005086-ERV0I9P0KAMJU0WKVCYK/setting-a-cookie.png?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
            
          
        

        
      
        </figure>
      

    
  


  





  <ul><li>Get a cookie</li></ul>
























  
    <pre class="prettyprint linenums">
var cookie = $.cookie('UserProfile');

// Convert the string value back to JSON
var userProfileData = JSON.parse(cookie);

console.log(userProfileData.Name)
</pre>
  




  <ul><li>Delete a cookie</li></ul>
























  
    <pre class="prettyprint linenums">
$.removeCookie('UserProfile', { path: '/', domain: 'ericphan.info'});
</pre>
  




  <p>​Really simple and easy to use. Props to <a href="http://twitter.com/carhartl" target="_blank">Klaus Hartl</a> for developing such a handy little plugin.</p>]]></description></item><item><title>Switching to Javascript and CSS Bundling in MVC 4</title><dc:creator>Eric Phan</dc:creator><pubDate>Mon, 15 Apr 2013 02:15:11 +0000</pubDate><link>http://ericphan.net/blog/2013/4/15/switching-to-javascript-and-css-bundling-in-mvc-4</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:516b436be4b0af9d19e64c2d</guid><description><![CDATA[<p>I was working an an internal project that started on MVC 2, and has recently been upgraded to MVC 4. There's a lot of house keeping to do to keep the codebase maintainable.</p><p>One custom piece of code that was implemented to make sure assets like javascript and css were not cached when a new version was released was implemented as follows:​</p>
























  
    <pre class="prettyprint linenums">
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;@Url.Content(&quot;~/Content/themes/base/jquery-ui.css&quot; + Versioning.Latest)&quot; /&gt;        
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;@Url.Content(&quot;~/Content/kendo/2012.2.913/kendo.common.min.css&quot; + Versioning.Latest)&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;@Url.Content(&quot;~/Content/kendo/2012.2.913/kendo.metro.min.css&quot; + Versioning.Latest)&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;@Url.Content(&quot;~/Content/Site.css&quot; + Versioning.Latest)&quot; /&gt;    
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/kendo/2012.2.913/jquery.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/kendo/2012.2.913/kendo.all.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/kendo/2012.2.913/kendo.aspnetmvc.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/jquery-ui-1.9.2.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/jquery.formatCurrency-1.4.0.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;   
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/date.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/jquery.watermark.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;   
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/jquery.cross-slide.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;    
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/jquery.cookie.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/browser.support.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;@Url.Content(&quot;~/Scripts/handlebars.min.js&quot; + Versioning.Latest)&quot;&gt;&lt;/script&gt;
</pre>
  




  <p>Where Versioning.Latest is defined as follows:​</p>
























  
    <pre class="prettyprint lang=cs linenums:1"> 
public class Versioning
{
    public static string Latest
    {
        get
        {
            return "?v=" + typeof(Versioning).Assembly.GetName().Version;
        }
    }
}
</pre>
  




  <p>This works, however, it will cause a redownload of all javascript/css files when a new version is deployed, even if the file hasn't changed. Third party javascript libraries such as KendoUI, jQuery and date.js are unlikely to change (particularly if you're referencing a particular version of the library)​.</p><p>​I updated this code to use the new content bundling features that were introduced in MVC 4. Here's the steps:</p><p>1. In the NuGet Pageage Manager Console, grab Microsoft.AspNet.Web.Optimization</p><p></p>
























  
    <pre class="source-code">Install-Package Microsoft.AspNet.Web.Optimization</pre>
  




  <p>2. Create a BundleConfig.cs and define your bundles</p>
























  
    <pre class="prettyprint lang=cs linenums:1">
public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        // Scripts
        bundles.Add(new ScriptBundle("~/bundles/kendoui").Include(
            "~/Scripts/kendo/2012.2.913/jquery.min.js",
            "~/Scripts/kendo/2012.2.913/kendo.all.min.js", 
            "~/Scripts/kendo/2012.2.913/kendo.aspnetmvc.min.js"));

        bundles.Add(new ScriptBundle("~/bundles/thirdparty").Include(
           "~/Scripts/jquery-ui-*",
           "~/Scripts/jquery.formatCurrency-*",
           "~/Scripts/jquery.watermark.min.js",
           "~/Scripts/jquery.cross-slide.min.js",
           "~/Scripts/jquery.cookie.js",
           "~/Scripts/date.js",
           "~/Scripts/browser.support.js",
           "~/Scripts/handlebars.min.js"));
               
        // Stylesheets
        bundles.Add(new StyleBundle("~/Content/css").Include(
            "~/Content/themes/base/jquery-ui.css",
            "~/Content/Site.css"));

        bundles.Add(new StyleBundle("~/Content/kendoui-css").Include(
            "~/Content/kendo/2012.2.913/kendo.common.min.css",
            "~/Content/kendo/2012.2.913/kendo.metro.min.css"));
    }
}
</pre>
  




  <p>3. Call the bundle config from Global.asax Application_Start to register the bundles</p>
























  
    <pre class="prettyprint lang=cs linenums:1">
protected void Application_Start()
{
   :  
   BundleConfig.RegisterBundles(BundleTable.Bundles);
   :
}
</pre>
  




  <p>4. Update your _layout.cshtml to reference the bundles</p>
























  
    <pre class="prettyprint lang=xhtml linenums:1">
&lt;link href=&quot;@Scripts.Url(&quot;~/Content/css&quot;)&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
&lt;link href=&quot;@Scripts.Url(&quot;~/Content/kendoui-css&quot;)&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
&lt;script src=&quot;@Scripts.Url(&quot;~/bundles/kendoui&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;@Scripts.Url(&quot;~/bundles/thirdparty&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</pre>
  




  <p>5. Update your (root)\web.config and Views\web.config to register the System.Web.Optimization namespace</p>
























  
    <pre class="prettyprint lang=xhtml linenums:1">
&lt;pages pageBaseType=&quot;System.Web.Mvc.WebViewPage&quot;&gt;
  &lt;namespaces&gt;
    &lt;add namespace=&quot;System.Web.Mvc&quot; /&gt;
    &lt;add namespace=&quot;System.Web.Mvc.Ajax&quot; /&gt;
    &lt;add namespace=&quot;System.Web.Mvc.Html&quot; /&gt;
    &lt;add namespace=&quot;System.Web.Routing&quot; /&gt;
    &lt;add namespace=&quot;System.Web.Optimization&quot; /&gt;
  &lt;/namespaces&gt;
&lt;/pages&gt;
</pre>
  




  <p>6. And you're done!​</p><p>​Run your application and look at the generated URLs for your CSS and JS. They contain a hash in the URL that updates when the bundle changes:</p>
























  
    <pre class="prettyprint lang=xhtml linenums:1">
&lt;link href=&quot;/Content/css?v=DW4VA8QHWz0lpg-1xgEkBu9a2jl0u21oskVI8gjXdO81&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
&lt;link href=&quot;/Content/kendoui-css?v=NOcY8mlFVB5YWf-VVYSPB17Ov0AXjKcYHOg76QV3vqQ1&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
        
&lt;script src=&quot;/bundles/kendoui?v=YbNJGKtU_KjafyxKAw3U4QVNX021Qk1BCIWYBvui2n41&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;/bundles/thirdparty?v=kArVyDzIkXBQ9DtFhv4FWSKAx1YfHKB4UlIG_6cJmVY1&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</pre>
  




  <p>​If we update the Site.css and rebuild, only the /Content/css has changes, all the other hashes remain the same.</p>
























  
    <pre class="prettyprint lang=xhtml linenums:1">
&lt;link href=&quot;/Content/css?v=tynpQ3xqzP2PGlfCEDcWZa9rnxNaQPSPSBl2yxmF_gI1&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
&lt;link href=&quot;/Content/kendoui-css?v=NOcY8mlFVB5YWf-VVYSPB17Ov0AXjKcYHOg76QV3vqQ1&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
        
&lt;script src=&quot;/bundles/kendoui?v=YbNJGKtU_KjafyxKAw3U4QVNX021Qk1BCIWYBvui2n41&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;/bundles/thirdparty?v=kArVyDzIkXBQ9DtFhv4FWSKAx1YfHKB4UlIG_6cJmVY1&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</pre>]]></description><media:content type="image/jpeg" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365993318967-6RDUK1KSG1KIZ8BEEVTS/ASP.NET-MVC-4-Bundling-and-Minification.jpg?format=1500w" medium="image" isDefault="true" width="503" height="170"><media:title type="plain">Switching to Javascript and CSS Bundling in MVC 4</media:title></media:content></item><item><title>Cleaning up your client side javascript with a templating engine</title><dc:creator>Eric Phan</dc:creator><pubDate>Fri, 12 Apr 2013 06:09:57 +0000</pubDate><link>http://ericphan.net/blog/2013/4/12/cleaning-up-your-client-side-javascript-with-a-templating-engine</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:5167a625e4b00ee22f2293be</guid><description><![CDATA[<p>​Today, I was working on a code base for a time sheeting system. It does a lot of rendering on client side like retrieving appointments and source code comments from third party system and then renders it onto the page.</p><p>​Unfortunately, the javascript that did the rendering post ajax call was something like this:</p><p></p><p></p>
























  
    <pre class="source-code"><span class="cm-keyword">for</span> (<span class="cm-keyword">var</span> <span class="cm-variable">i</span> = <span class="cm-number">0</span>; <span class="cm-variable">i</span> &lt; <span class="cm-variable">wi</span>.<span class="cm-property">CheckinHistory</span>.<span class="cm-property">length</span>; <span class="cm-variable">i</span>++) {<br>        <span class="cm-variable">history</span> += <span class="cm-string">"&lt;li&gt;&lt;i class=\"add-note\" title=\"Add this checkin comment to the Notes field\"&gt;"</span> + <span class="cm-variable">wi</span>.<span class="cm-property">CheckinHistory</span>[<span class="cm-variable">i</span>] + <span class="cm-string">"&lt;/i&gt;&lt;/li&gt;"</span>;<br>    }<br>    <span class="cm-keyword">var</span> <span class="cm-variable">item</span> = <span class="cm-string">"&lt;span class=\"wi-link\"&gt;&lt;a href=\""</span> + <span class="cm-variable">wi</span>.<span class="cm-property">Url</span> + <span class="cm-string">"\" target=\"_blank\"&gt;["</span> + <span class="cm-variable">wi</span>.<span class="cm-property">Id</span> + <span class="cm-string">"]&lt;/a&gt;&lt;/span&gt;"</span> +<br>        <span class="cm-string">"&lt;span class=\"wi-title\"&gt;"</span> + <span class="cm-variable">wi</span>.<span class="cm-property">Title</span> + <span class="cm-string">"&lt;/span&gt;"</span> +<br>        <span class="cm-string">"&lt;span class=\"wi-state\"&gt;"</span> + <span class="cm-variable">wi</span>.<span class="cm-property">State</span> + <span class="cm-string">"&lt;/span&gt;"</span> +<br>        <span class="cm-string">"&lt;span class=\"wi-project\"&gt;"</span> + <span class="cm-variable">wi</span>.<span class="cm-property">ProjectName</span> + <span class="cm-string">"&lt;/span&gt;"</span> +<br>        <span class="cm-string">"&lt;span class=\"wi-checkins\"&gt;&lt;ul&gt;"</span> + <span class="cm-variable">history</span> + <span class="cm-string">"&lt;/ul&gt;&lt;/span&gt;"</span> +<br>        <span class="cm-string">"&lt;span class=\"wi-modified\"&gt;"</span> + <span class="cm-string">"(Last Modified "</span> + <span class="cm-variable">modDate</span> + <span class="cm-string">" by "</span> + <span class="cm-variable">wi</span>.<span class="cm-property">ChangedBy</span> + <span class="cm-string">")&lt;/span&gt;"</span>;<br>    <span class="cm-keyword">return</span> <span class="cm-variable">item</span>;<br></pre>
  




  <p>​This is obviously not maintainable as it's not really readable and prone to error.&nbsp;</p><p>I refactored this code and re-implemented it using a javascript templating engine. There are several around and <a href="http://engineering.linkedin.com/frontend/client-side-templating-throwdown-mustache-handlebars-dustjs-and-more" target="_blank">LinkedIn has a good smackdown of several options</a>.&nbsp;</p><p>I chose to use <a href="http://handlebarsjs.com/" target="_blank">Handlebars</a>​ because of the easy to read syntax and&nbsp;extensible&nbsp;(but mainly because it has an awesome logo).</p><h2>Installing and using Handlebars</h2><p>Grab it from NuGet using :</p><blockquote>Install-Package Handlebars.js</blockquote><p>​Reference the handlebars.min.js in your layout/master page.</p><p> Create your template, the javascript that builds html above will become nice and readable:​</p>
























  
    <pre class="source-code">    <span class="cm-tag">&lt;script</span> <span class="cm-attribute">id</span>=<span class="cm-string">"tfsChangeSetTemplate"</span> <span class="cm-attribute">type</span>=<span class="cm-string">"text/x-handlebars-template"</span><span class="cm-tag">&gt;</span><br>        &lt;<span class="cm-variable">h3</span>&gt;<span class="cm-variable">Changesets</span> ({{<span class="cm-variable">count</span> <span class="cm-variable">result</span>}})&lt;<span class="cm-string-2">/h3&gt;</span><br>        {{<span class="cm-error">#each result}}</span><br>        &lt;<span class="cm-variable">div</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-item"</span>&gt;<br>            &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-link"</span>&gt;&lt;<span class="cm-variable">a</span> <span class="cm-variable">href</span>=<span class="cm-string">"{{Url}}"</span> <span class="cm-variable">target</span>=<span class="cm-string">"_blank"</span>&gt;[<span class="cm-variable">Changeset</span> {{<span class="cm-variable">Id</span>}}]&lt;<span class="cm-string-2">/</span><span class="cm-variable">a</span>&gt;&lt;<span class="cm-string-2">/span&gt;</span><br>            &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-title"</span>&gt;<span class="cm-variable">Checked</span> <span class="cm-variable">In</span> {{<span class="cm-variable">CommitDateFormatted</span>}} <span class="cm-variable">by</span> {{<span class="cm-variable">CommittedBy</span>}} &lt;<span class="cm-string-2">/span&gt;</span><br>            &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-state"</span>&gt;{{<span class="cm-variable">Changes</span>}} <span class="cm-variable">file</span>(<span class="cm-variable">s</span>) <span class="cm-variable">changed</span>&lt;<span class="cm-string-2">/span&gt;</span><br>            &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-checkins"</span>&gt;<br>                &lt;<span class="cm-variable">ul</span>&gt;<br>                    &lt;<span class="cm-variable">li</span>&gt;{{<span class="cm-error">#if Comment}}</span><br>                        &lt;<span class="cm-variable">i</span> <span class="cm-variable">class</span>=<span class="cm-string">"add-note"</span> <span class="cm-variable">title</span>=<span class="cm-string">"Add this checkin comment to the Notes field"</span>&gt;{{<span class="cm-variable">html</span> <span class="cm-variable">Comment</span>}}<br>                        &lt;<span class="cm-string-2">/i&gt;</span><br>                        {{<span class="cm-keyword">else</span>}}<br>                        &lt;<span class="cm-variable">i</span>&gt;<span class="cm-variable">No</span> <span class="cm-variable">comment</span> <span class="cm-variable">was</span> <span class="cm-variable">entered</span><br>                        &lt;<span class="cm-string-2">/i&gt;</span><br>                        {{<span class="cm-string-2">/if}}</span><br>                    &lt;<span class="cm-string-2">/li&gt;</span><br>                &lt;<span class="cm-string-2">/ul&gt;</span><br>            &lt;<span class="cm-string-2">/span&gt;</span><br>            {{<span class="cm-error">#if WorkItems}}</span><br>            &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-workitems"</span>&gt;<br>                &lt;<span class="cm-variable">ul</span> <span class="cm-variable">style</span>=<span class="cm-string">"list-style: none; margin-left: 20px;"</span>&gt;<br>                    {{<span class="cm-error">#each WorkItems}}</span><br>                    &lt;<span class="cm-variable">li</span>&gt;<br>                        &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-link"</span>&gt;&lt;<span class="cm-variable">a</span> <span class="cm-variable">href</span>=<span class="cm-string">"{{Url}}"</span> <span class="cm-variable">target</span>=<span class="cm-string">"_blank"</span>&gt;[<span class="cm-variable">WI</span> {{<span class="cm-variable">this</span>.<span class="cm-variable">Id</span>}}]&lt;<span class="cm-string-2">/</span><span class="cm-variable">a</span>&gt;&lt;<span class="cm-string-2">/span&gt;</span><br>                        &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-title"</span>&gt;{{<span class="cm-variable">Title</span>}}&lt;<span class="cm-string-2">/span&gt;</span><br>                        &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-state"</span>&gt;{{<span class="cm-variable">State</span>}}&lt;<span class="cm-string-2">/span&gt;</span><br>                        &lt;<span class="cm-variable">span</span> <span class="cm-variable">class</span>=<span class="cm-string">"wi-project"</span>&gt;{{<span class="cm-variable">ProjectName</span>}}&lt;<span class="cm-string-2">/span&gt;</span><br>                    &lt;<span class="cm-string-2">/li&gt;</span><br>                    {{<span class="cm-string-2">/each}}</span><br>                &lt;<span class="cm-string-2">/ul&gt;</span><br>            &lt;<span class="cm-string-2">/span&gt;</span><br>            {{<span class="cm-string-2">/if}}</span><br>        &lt;<span class="cm-string-2">/div&gt;</span><br>        {{<span class="cm-string-2">/each}}</span><br>    <br>    <br>    <span class="cm-tag">&lt;/script</span><span class="cm-tag">&gt;</span><br></pre>
  




  <p>You'll notice I put in some conditional logic using the <strong>IF </strong>block and made extensive use of the <strong>EACH</strong> block to loop through the JSON data.​</p><p>The javascript to get and render the template is:​</p>
























  
    <pre class="source-code"><span class="cm-keyword">if</span> (<span class="cm-variable">data</span>.<span class="cm-property">length</span> &gt; <span class="cm-number">0</span>) {<br>    <span class="cm-keyword">var</span> <span class="cm-variable">tfsWorkItemTemplate</span> = <span class="cm-variable">Handlebars</span>.<span class="cm-property">compile</span>(<span class="cm-variable">$</span>(<span class="cm-string">"#tfsChangeSetTemplate"</span>).<span class="cm-property">html</span>());<br>    <span class="cm-keyword">var</span> <span class="cm-variable">html</span> = <span class="cm-variable">tfsWorkItemTemplate</span>({ <span class="cm-property">result</span>: <span class="cm-variable">data</span> });<br>    <span class="cm-variable">$tasks</span>.<span class="cm-property">append</span>(<span class="cm-variable">html</span>);<br>}</pre>
  




  <p>Nice and simple!​</p>]]></description><media:content type="image/png" url="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365982606722-E6WOP2UA3N80DIUT9XCC/handlebars_logo.png?format=1500w" medium="image" isDefault="true" width="342" height="258"><media:title type="plain">Cleaning up your client side javascript with a templating engine</media:title></media:content></item><item><title>Running a stand-up meeting using Team Foundation Service (tfspreview)</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Mon, 21 May 2012 03:05:34 +0000</pubDate><link>http://ericphan.net/blog/2012/5/21/running-a-stand-up-meeting-using-team-foundation-service-tfs.html</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:515e1b90e4b05ae29adde7d9</guid><description><![CDATA[<p>Here at <a href="http://www.ssw.com.au/">SSW</a>, we've been transitioning all our new projects onto <a href="http://tfspreview.com/">Team Foundation Service</a>. It’s been a pleasure to work with in all aspects of the application lifecycle. It’s main features are:</p><ul><li>A great UI for managing the tasks in a sprint</li><li>Cloud based hosting, so you don’t have to worry about upgrades and server hardware</li><li>It connects to Windows Live for authentication so you don’t need to create an Active Directory account for your clients</li></ul><p>Below is a video of how Microsoft use Team Foundation Service to run their internal scrum teams. It provides great insight into how the tool works, but also shows you how a standup meeting should run. The key takeaways for me are:</p><ul><li>Stand-up meeting happens in a corridor</li><li>Each team member can easily switch the taskboard to their view (showing what they’ve worked on)</li><li>“Parking” issues so the stand-up is quick</li></ul>























<iframe data-image-dimensions="640x360" allowfullscreen="" src="http://www.youtube.com/embed/-UUrLxNBK_g?feature=oembed&amp;wmode=opaque&amp;enablejsapi=1" width="640" data-embed="true" frameborder="0" height="360"></iframe><p>http://tv.ssw.com/1279/daily-scrum-at-microsoft Everybody knows the 3 essential questions.... lets go well beyond that. See the TFS Agile Team do a Daily Scrum What did they do right? ...and wrong? What do you do better? Please tweet me @AdamCogan and give me feedback @AdamCogan www.adamcogan.com Based on tips from the SSW Rule: Do you have daily stand-up meetings (aka a Scrum)?</p>


  <p>Check out <a href="http://rules.ssw.com.au/Management/RulesToSuccessfulProjects/Pages/DailyStandUpScrum.aspx">Methodology - Do you do Daily Scrums (aka stand-up meetings)?</a> for more details about how SSW runs scrums</p>]]></description></item><item><title>CRM 2011 Outlook Client - Stuck in reboot loop installing SQL Express</title><category>Stuff</category><dc:creator>Eric Phan</dc:creator><pubDate>Mon, 07 Nov 2011 22:43:25 +0000</pubDate><link>http://ericphan.net/blog/2011/11/8/crm-2011-outlook-client-stuck-in-reboot-loop-installing-sql.html</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:515e1b90e4b05ae29adde7d4</guid><description><![CDATA[<p>Ran into this issue today when trying to install the <a href="http://www.microsoft.com/download/en/details.aspx?id=27821" target="_blank">Microsoft Dynamics CRM 2011 for Microsoft Office Outlook</a> where the installer would constantly ask for a reboot when trying to install &ldquo;Microsoft SQL Server Express Edition 2008 (CRM)&rdquo;. No matter how many times you rebooted it would always ask to reboot again. Note: This only happens if you use the &ldquo;Offline&rdquo; functionality.</p>
<p><a href="http://ericphan.net/static/5017cfedc4aaa95147c14ef2/515e1b8fe4b05ae29adde700/515e1b90e4b05ae29adde811/1320705797273/Windows-Live-Writer-06026698e27d_84CE-"><img title="SNAGHTML26bc61" src="/static/5017cfedc4aaa95147c14ef2/515e1b8fe4b05ae29adde700/515e1b90e4b05ae29adde812/1320705799069/Windows-Live-Writer-06026698e27d_84CE-" alt="SNAGHTML26bc61" width="625" height="511" /></a></p>
<p>The solution to this is to manually install <a href="http://www.microsoft.com/sqlserver/en/us/editions/express.aspx" target="_blank">Microsoft SQL Server 2008 R2 Express</a> and call the instance &ldquo;CRM&rdquo;. This allows CRM to continue and skip over the installation of SQL Server Express.</p>
<p><a href="http://ericphan.net/static/5017cfedc4aaa95147c14ef2/515e1b8fe4b05ae29adde700/515e1b90e4b05ae29adde813/1320705801963/Windows-Live-Writer-06026698e27d_84CE-"><img title="SNAGHTML324320" src="/static/5017cfedc4aaa95147c14ef2/515e1b8fe4b05ae29adde700/515e1b90e4b05ae29adde814/1320705804039/Windows-Live-Writer-06026698e27d_84CE-" alt="SNAGHTML324320" width="820" height="615" /></a></p>
<p>Hope this helps others who get stuck with the install.</p>]]></description></item><item><title>Use a custom TFS Work Item Query to keep track of what you've worked on today</title><category>Development</category><dc:creator>Eric Phan</dc:creator><pubDate>Thu, 22 Sep 2011 23:39:20 +0000</pubDate><link>http://ericphan.net/blog/2011/9/22/use-a-custom-tfs-work-item-query-to-keep-track-of-what-yours.html</link><guid isPermaLink="false">5017cfedc4aaa95147c14ef2:515e1b8fe4b05ae29adde700:515e1b90e4b05ae29adde7d1</guid><description><![CDATA[<p>At SSW we need to record timesheets for all the work that we do. Normally keeping track of what you've worked on is difficult and you end up writing "Worked on web stuff"</p><p>If you use TFS you can easily keep track of the Work Items that you've completed today</p>


































































  

    
  
    

      

      
        <figure class="sqs-block-image-figure">
          
        
        

        
          
            
          
            
                
                
                
                
                
                
                
                <img data-stretch="false" data-image="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-" data-image-dimensions="" data-image-focal-point="0.5,0.5" alt="" data-load="false" elementtiming="system-image-block" src="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=1000w" width="0" height="0" sizes="100vw" onload="this.classList.add(&quot;loaded&quot;)" srcset="https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=100w 100w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=300w 300w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=500w 500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=750w 750w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=1000w 1000w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=1500w 1500w, https://images.squarespace-cdn.com/content/v1/5017cfedc4aaa95147c14ef2/1365121941160-4U2CP6IDRTJ0F1OUMDA5/Windows-Live-Writer-Use-a-custom-TFS-Work-Item-Query-to-keep_86B0-?format=2500w 2500w" loading="lazy" decoding="async" data-loader="sqs">

            
          
        
          
        

        
          
          <figcaption class="image-caption-wrapper">
            <p>SNAGHTML550b2d</p>
          </figcaption>
        
      
        </figure>
      

    
  


  





  <p>You can then just copy and paste the results into your timesheets</p>]]></description></item></channel></rss>