timjames.me 2023-03-02T16:59:49+00:00 http://www.timjames.me Tim James Copyright (c) Tim James Management Hacks 2023-03-02T00:00:00+00:00 http://timjames.me/blog/2023/03/02/management-hacks/ <ol> <li>You’re NOT an elevated individual contributor</li> <li>Adaptation is your Magic Bullet (not a sponsor)</li> <li>People LIKE Structure &amp; Guidance</li> <li>But not too much Structure &amp; Guidance</li> <li>Let your people lead in their area</li> <li>Listen actively &amp; default to trust</li> <li>Ask “What do you mean by that?”</li> <li>Focus on behaviour</li> <li>Be unapologetically optimistic</li> <li>Your job is to make your people successful</li> </ol> <h2 id="1-youre-not-an-elevated-individual-contributor">1. You’re NOT an elevated individual contributor</h2> <p>You likely made it into a manager position because you proved you could be successful at the job you were doing as an individual contributor, but not because you proved your ability to manage a group of individual contributors.</p> <p>Those are two very different things! Just like you can’t wake up one day and play a concerto on the piano if you’ve never played before, you probably won’t wake up and automatically know what to do to be the world’s best manager. It’s a skill that must develop, just like any other skill.</p> <p>So, consider yourself an apprentice. This is a time to learn how to step into the leadership role your team needs you to take, how to delegate effectively, and how to inspire your team to put in their best every day. If you make a mistake or two along the way, own it and then promise to do better.</p> <h2 id="2-adaptation-is-your-magic-bullet">2. Adaptation is your magic bullet</h2> <!--excerpt--> <p>Want your people to be highly productive? Motivated? Creative? Innovative? Then you need to learn how to adapt your work style to theirs. Everyone you’re managing will bring a different natural work style to the office, which means they all have different things that are going to inspire and motivate them or hold them back from doing their best work.</p> <p>Sometimes you get lucky, have employees who have a very similar working style as you and you gel immediately without much fuss. More often, the opposite is true, and you end up with employees who just approach work differently. You must keep in mind that “different” is not necessarily bad or wrong. Each work style has it’s own set of strengths and challenges, and no work style is fundamentally better or worse than any other.</p> <p>In an ideala world, we would all understand the work styles of our colleagues, and proactively adapt to meet somewhere in the middle. However, most of the time someone needs to take the step first. As a manager, that’s your job. You are the one in the power position, and if your goal is to support your team in performating at their highest level, you must work to understand their needs and adapt your work style to them. Remember, when they are successful, that means you’ve been successful.</p> <h2 id="3-people-like-structure-and-guidance">3. People like structure and guidance</h2> <p>Zappos made headlines several years ago when they restructured to a holacracy and effectively eliminated manager positions. The result? 18% of their workforce left the company, a huge turnover rate by any standard.</p> <p>The idea of getting rid of managers and allowing lower-level employees to be more entrepreneurial sounds great, but rarely works in practice because from a psychological perspective, most people seek out structure and guidance. We’ve been trained to do this from the time we’re small children - we look to our parents, our teachers, our extended family, and our friends to know what to do and what not to do. When you enter the workforce, you can’t turn off 20+ years of programming - people want ongoing feedback.</p> <p>Someone has to be in charge of providing that guidance and saying it’s everyone’s responsibility isn’t good enough. When something is everyone’s responsibility, it’s really no one’s responsibility. So it rests on managers to do it. In fact, 65% of people say they want more feedback from their boss that they are currently getting, even in traditional structures. As a manager, your job is to provide the structure and guidance your team members need to do their best work on an ongoing basis.</p> <h2 id="4-but-people-will-sink-under-too-much-structure-and-guidance">4. But people will sink under too much structure and guidance</h2> <p>All that said from the last point, it’s important to know that managers need to walk the tightripe between providing guidance and micromanagement. Here are some critical differences between effective managers and micromanagers:</p> <ul> <li>Effective managers lead through influence. Micromanagers lead through control.</li> <li>Effective managers know that experience (and the occasional failure) is the only way to learn, grow, and push beyond business as usual. Micromanagers fear failure of any kind, no matter how small or insignificant.</li> <li>Effective managers ask questions that guide their team members to a solution. Micromanagers dictate a solution without exploring different options or opportunities.</li> <li>Effective managers empower their team members to do their work on their own, provide updates and ask for help when needed. Micromanagers need to be involved in every meeting and CC’d on every email.</li> <li>Effective managers keep their cards always face up. They share information openly and transparently. Micromanagers keep their cards very close to their chest as if they are in competition with everyone they work with.</li> <li>Effective managers remain open to new ideas, willing to explorer them if they seem reasonable. Micromanagers default to doing the things the way they’ve always done them before.</li> </ul> <p>Managers get bad reputation because of all the micromanagers out there who refuse to let go of the control and empower their employees to succeed on their own. But remember that it is your job to delegate because that is the only way for your team members to learn and grow.</p> <h2 id="5-let-your-people-lead-in-their-area-even-if-you-dont-always-agree-with-where-they-are-going">5. Let your people lead in their area, even if you don’t always agree with where they are going</h2> <p>If you want your employees to be empowered to do their best work, that requires taking a step back. Remember, your role is to provide guidance, you cna do this by asking questions to make sure your team member has fully considered their approach.</p> <p>But if their ideas are different that the way you would have done it, most of the time the best way to go is to let them go try what they want to do and see what happens. There’s always more than one way to meet a goal, and very few of us work in jobs that are truly life and death. If they fail, it’s a teaching moment, and if they succeed using a strategy that you wouldn’t have picked, that’s still a win for you!</p> <h2 id="6-schedule-regular-one-to-one-meetings">6. Schedule regular one-to-one meetings</h2> <p>Very few people want more meetings in their lives, but for managers, a monthly one-to-one meeting with every direct report is an absolute must. Think about it: If you can’t give each of your direct reports 30 minutes of your time every month, then you either have too many people reporting to you, or you haven’t fully embraced your role as a manager rather than an individual contributor.</p> <ul> <li>Their update of the things they’ve been working on, and what they need from you to help them succeed.</li> <li>Your update for them of all the information they need to know to do their job well.</li> <li>A quick brainstorm of future goals, ideas they have and development they might need. This is also a great place to integrate coaching.</li> </ul> <p>Frequently, one-to-one meetings are the first meeting to be canceled with the excuse of “I have nothing to talk about.” Unless you have a valid reason, you should not cancel your one-to-one meetings. This face time is a critical component of building a relationship with each of your employees that is grounded in trust. It’s one of the most important things you can do to drive their success.</p> <h2 id="7-listen-actively-and-default-to-trust">7. Listen actively, and default to trust</h2> <p>When you have your monthly one-to-one meetings, the most critical component is not what you have to say - it’s what your team members are contributing to it.</p> <p>You’re going to head the good and the bad because that’s what happens when you have open communication. It’s essential that you hear your employees out and always assume they are coming to you with positive intent - they are complaining about the problems because they want your help in solving them. If your boss approaches you from the vein of distrust when you’re making a good faith effort to do the right thing, that can be incredibly demotivating.</p> <p>Your goal should always be to have them leave that one-to-one meeting in a better, more empowered place than when they arrive. Listen carefully to what they’re asking for, read between the lines to get to the core of what’s going on, and then do your best to provide the support they are looking for.</p> <p>A good rule of thumb to follow is this: Behavior + Impact + Expectation. You state the problematic behaviour, explain why it’s a problem, and set the expectation for future behaviour. For example:</p> <blockquote> <p>When you come late to a standup (behaviour), you throw off our agenda andit takes 10 minutes longer than it needs to (impact). Please make it on time in the future (expectation)</p> </blockquote> <p>And then, to the next point, thank them and provide positive feedback when they meet the expectation!</p> <h2 id="8-be-unapologetically-optimistic">8. Be unapologetically optimistic</h2> <p>The previous example explains how to give ciritical feedback well, but the reality is that you should give out much more positive feedback than negative feedback for one simple reason: Positive feedback is significantly more motivating that critical feedback. In fact, every single business outcome that can be tested for rises when your brain is in a state of positivity.</p> <p>And the fact is that most employees are doing most things right on any day, but they only get feedback when they are doing wrong. The way you give feedback will set the tone for your management style. If you’re consistently looking for reasons to offer praise, even with the little things, that will keep your team in the right headspace to give it their best.</p> <h2 id="9-your-job-is-to-make-your-people-successful">9. Your job is to make your people successful</h2> <p>At the end of the day, you will be judged based on the success of your team. That means that they are your priority. The minute you start deviating from that path is the minute you wander into “bad boss” territory. It might be helpful to do a quick exercise at the end of every day and make a list of the ways you set your employees up for success that day. It will help you to take stock, hold yourself accountable, and make sure you are focusing on the things that matter most.</p> Resizing Images with Azure Functions 2017-06-13T00:00:00+00:00 http://timjames.me/blog/2017/06/13/resizing-images-with-azure-functions/ <p>A new Azure Functions project template is available, in Visual Studio Preview (currently on June 13 2017), for working with Azure Functions. In order to be able to select the project and file types, you will eed to also install VS2017 Tools for Aszure Functions extension. This blog has the steps required to install <a href="https://blogs.msdn.microsoft.com/webdev/2017/05/10/azure-function-tools-for-visual-studio-2017/">https://blogs.msdn.microsoft.com/webdev/2017/05/10/azure-function-tools-for-visual-studio-2017/</a></p> <p>After installing, follow the instructions on creating a new Azure Functions project, and then add a “BlobTrigger” function. This will then create a basic blob trigger with the following code:</p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="nf">FunctionName</span><span class="p">(</span><span class="s">"BlobTriggerCSharp"</span><span class="p">)]</span> <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">Run</span><span class="p">([</span><span class="nf">BlobTrigger</span><span class="p">(</span><span class="s">"samples-workitems/{name}"</span><span class="p">,</span> <span class="n">Connection</span> <span class="p">=</span> <span class="s">""</span><span class="p">)]</span><span class="n">Stream</span> <span class="n">myBlob</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">TraceWriter</span> <span class="n">log</span><span class="p">)</span> <span class="p">{</span> <span class="n">log</span><span class="p">.</span><span class="nf">Info</span><span class="p">(</span><span class="s">$"C# Blob trigger function Processed blob\n Name:</span><span class="p">{</span><span class="n">name</span><span class="p">}</span><span class="s"> \n Size: </span><span class="p">{</span><span class="n">myBlob</span><span class="p">.</span><span class="n">Length</span><span class="p">}</span><span class="s"> Bytes"</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>The BlobTrigger takes in the name of your blob container, and the Connection is the name of your storage account. If you then follow the instructions on publishing this to your Azure instance, you can then watch this run. For managing files within my blob container, I downloaded <a href="http://storageexplorer.com/">http://storageexplorer.com/</a> which then allows me to upload a file and then watch, via the Azure portal, the function trigger.</p> <!--excerpt--> <p><strong><em>Now for setting up a trigger that will resize an image and then write it to another blob folder</em></strong></p> <p>I initially had looked on github at a resize example template <a href="https://github.com/Azure/azure-webjobs-sdk-templates/blob/dev/Functions.Templates/Templates/ImageResizer-CSharp/run.csx">https://github.com/Azure/azure-webjobs-sdk-templates/blob/dev/Functions.Templates/Templates/ImageResizer-CSharp/run.csx</a>. This works well, however, the output file has the contentType as <code class="language-plaintext highlighter-rouge">application/octet-stream</code> and ideally I was wanting this to be <code class="language-plaintext highlighter-rouge">image/jpeg</code>.</p> <p>For resizing of the image, I am going to install ImageResizer via nuget <code class="language-plaintext highlighter-rouge">install-package ImageResizer</code>. I am then going to make use of the input blob and an output of type CloudBlockBlob. Now with the output type, you also need to provide both the blob container and the name of the storage account. It is also important to provide file access for the CloudBlockBlob. Without the file access, you will see an error about write access.</p> <p>So make sure to give it <code class="language-plaintext highlighter-rouge">FileAccess.ReadWrite</code>. With this, you are effectively changing the “direction” to “inout”.</p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">ImageResizer</span><span class="p">;</span> <span class="k">using</span> <span class="nn">Microsoft.Azure.WebJobs</span><span class="p">;</span> <span class="k">using</span> <span class="nn">Microsoft.Azure.WebJobs.Host</span><span class="p">;</span> <span class="k">using</span> <span class="nn">Microsoft.WindowsAzure.Storage.Blob</span><span class="p">;</span> <span class="k">using</span> <span class="nn">System.IO</span><span class="p">;</span> <span class="k">namespace</span> <span class="nn">MyProject</span> <span class="p">{</span> <span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">Function1</span> <span class="p">{</span> <span class="p">[</span><span class="nf">FunctionName</span><span class="p">(</span><span class="s">"resize-func"</span><span class="p">)]</span> <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">Run</span><span class="p">(</span> <span class="p">[</span><span class="nf">BlobTrigger</span><span class="p">(</span><span class="s">"images/{name}"</span><span class="p">,</span> <span class="n">Connection</span> <span class="p">=</span> <span class="s">"fakeconnection_STORAGE"</span><span class="p">)]</span> <span class="n">Stream</span> <span class="n">myBlob</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="p">[</span><span class="nf">Blob</span><span class="p">(</span><span class="s">"resized-images/{name}"</span><span class="p">,</span> <span class="n">FileAccess</span><span class="p">.</span><span class="n">ReadWrite</span><span class="p">,</span> <span class="n">Connection</span> <span class="p">=</span> <span class="s">"fakeconnection_STORAGE"</span><span class="p">)]</span> <span class="n">CloudBlockBlob</span> <span class="n">outputBlob</span><span class="p">,</span> <span class="n">TraceWriter</span> <span class="n">log</span><span class="p">)</span> <span class="p">{</span> <span class="n">log</span><span class="p">.</span><span class="nf">Info</span><span class="p">(</span><span class="s">$"C# Blob trigger function Processed blob\n Name:</span><span class="p">{</span><span class="n">name</span><span class="p">}</span><span class="s"> \n Size: </span><span class="p">{</span><span class="n">myBlob</span><span class="p">.</span><span class="n">Length</span><span class="p">}</span><span class="s"> Bytes"</span><span class="p">);</span> <span class="kt">var</span> <span class="n">instructions</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Instructions</span> <span class="p">{</span> <span class="n">Width</span> <span class="p">=</span> <span class="m">570</span><span class="p">,</span> <span class="n">Mode</span> <span class="p">=</span> <span class="n">FitMode</span><span class="p">.</span><span class="n">Crop</span><span class="p">,</span> <span class="n">Scale</span> <span class="p">=</span> <span class="n">ScaleMode</span><span class="p">.</span><span class="n">Both</span> <span class="p">};</span> <span class="n">Stream</span> <span class="n">stream</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">MemoryStream</span><span class="p">();</span> <span class="n">ImageBuilder</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="nf">Build</span><span class="p">(</span><span class="k">new</span> <span class="nf">ImageJob</span><span class="p">(</span><span class="n">myBlob</span><span class="p">,</span> <span class="n">stream</span><span class="p">,</span> <span class="n">instructions</span><span class="p">));</span> <span class="n">stream</span><span class="p">.</span><span class="nf">Seek</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">SeekOrigin</span><span class="p">.</span><span class="n">Begin</span><span class="p">);</span> <span class="n">outputBlob</span><span class="p">.</span><span class="n">Properties</span><span class="p">.</span><span class="n">ContentType</span> <span class="p">=</span> <span class="s">"image/jpeg"</span><span class="p">;</span> <span class="n">outputBlob</span><span class="p">.</span><span class="nf">UploadFromStream</span><span class="p">(</span><span class="n">stream</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>When publised to Azure, and then clicking on the function from within your Function Apps, you will see that it creates a <code class="language-plaintext highlighter-rouge">function.json</code> file with the following code:</p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> <span class="s">"bindings"</span><span class="p">:</span> <span class="p">[</span> <span class="p">{</span> <span class="s">"type"</span><span class="p">:</span> <span class="s">"blobTrigger"</span><span class="p">,</span> <span class="s">"connection"</span><span class="p">:</span> <span class="s">"fakeconnection_STORAGE"</span><span class="p">,</span> <span class="s">"path"</span><span class="p">:</span> <span class="s">"images/{name}"</span><span class="p">,</span> <span class="s">"direction"</span><span class="p">:</span> <span class="s">"in"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">:</span> <span class="s">"myBlob"</span> <span class="p">},</span> <span class="p">{</span> <span class="s">"type"</span><span class="p">:</span> <span class="s">"blob"</span><span class="p">,</span> <span class="s">"path"</span><span class="p">:</span> <span class="s">"resized-images/{name}"</span><span class="p">,</span> <span class="s">"connection"</span><span class="p">:</span> <span class="s">"fakeconncetion_STORAGE"</span><span class="p">,</span> <span class="s">"direction"</span><span class="p">:</span> <span class="s">"inout"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">:</span> <span class="s">"outputBlob"</span> <span class="p">}</span> <span class="p">],</span> <span class="s">"disabled"</span><span class="p">:</span> <span class="k">false</span><span class="p">,</span> <span class="s">"scriptFile"</span><span class="p">:</span> <span class="s">"..\\bin\\MyProject.dll"</span><span class="p">,</span> <span class="s">"entryPoint"</span><span class="p">:</span> <span class="s">"MyProject.Function1.Run"</span> <span class="p">}</span> </code></pre></div></div> <p>This code will take in the image, resize it and then save to the output blob container. With using the CloudBlockBlob, you then have access to it’s properties and can set the content type before then saving. This is something that was missing from the official github code.</p> <p><strong><em>Something to note</em></strong> is that a lot of the examples that I read online seems to be setting the output blob container the same as the input trigger. When I did this, the blob trigger would react to the new saved file, so basically just sit in a loop of input and output. I initially looked into ignoring file names, e.g. anything starting with <code class="language-plaintext highlighter-rouge">r-</code>, however my attempts failed, so I found it easier to save the output to another folder. The next step I have is that I will delete the original file so that I am not taking up storage that will not be used.</p> <p><strong><em>Another note</em></strong> I found that when creating my function within Visual Studio and then publishing to Azure, it would only work when the class was named <code class="language-plaintext highlighter-rouge">Function1</code>? I tried changing it, but was then seeing an error in the Azure portal.</p> Webpack final loader didn't return a buffer or string 2017-04-03T00:00:00+00:00 http://timjames.me/blog/2017/04/03/webpack-final-loader-didnt-return-a-buffer-or-string/ <p>Is the world of web development in a state of being permanently broken? Have you ever been able to follow one tutorial these days without then having to find why you are getting a errors?</p> <p>I have been looking at the best/fastest module builder/bundler for our ReactJS project which is written in TypeScript. Currently we are using Gulp, however we feel the bundler is not really where we want it to be. So I am looking at using either Webpack or Brunch.io.</p> <p>I found this tutorial online as a starter for 10 (https://www.typescriptlang.org/docs/handbook/react-&amp;-webpack.html)[https://www.typescriptlang.org/docs/handbook/react-&amp;-webpack.html]. Fairly simple tutorial and written well.</p> <p>Follow all the instructions to the letter, copy the configs into my configs, and then run webpack to get this error;</p> <p><code class="language-plaintext highlighter-rouge">Module build failed: Error: Final loader didn't return a Buffer or String</code></p> <p><img src="/img/webpack/failedtoloadfinal.JPG" alt="webpack" /></p> <!--excerpt--> <p>O FFS! Come on man! Does nothing work these days?! I know it is not the tutorial is wrong, so there must be a dependency within a dependency within a depenency that is faulty. The <code class="language-plaintext highlighter-rouge">bundle.js</code> is being created, however it only includes bundle code and not your files bundled in. So after a quick search online, I believe the issue lies with the <code class="language-plaintext highlighter-rouge">awesome-typescript-loader</code> and specific versions of this, and there is a quick fix.</p> <p>Update your <code class="language-plaintext highlighter-rouge">tsconfig.json</code> file to include the following code;</p> <div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">awesomeTypescriptLoaderOptions</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span> <span class="dl">"</span><span class="s2">useWebpackText</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="dl">"</span><span class="s2">useTranspileModule</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="dl">"</span><span class="s2">doTypeCheck</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="dl">"</span><span class="s2">forkChecker</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}</span> </code></pre></div></div> <p>Thankfully now you can run webpack and see the bundle being created.</p> dotnet aspnet codegenerator 2017-03-31T00:00:00+00:00 http://timjames.me/blog/2017/03/31/dotnet-aspnet-codegenerator/ <p>I am starting to get a bit annoyed with web development using Visual Studio these days. A lot of the work I have been doing is on the frontend using TypeScript and React, and trying to debug and compile currently involves the use of 3 tools.</p> <p>On top of this, I have been looking at moving our existing .net core project from Visual Studio 2015 to 2017. So while playing around with a Web Application in VS17, I just want to add a simple MVC Controller. Simples eh? Well not with VS17 it would seem!</p> <p><img src="/img/vs17/dotnet-aspnet-codegenerator.JPG" alt="codegenerator" /></p> <p><code class="language-plaintext highlighter-rouge">There was an error running the selected code generator: No executable found matching command "dotnet-aspnet-codegenetor"</code></p> <p>I have read that you need to “hack” the csproj file to get it to work;</p> <pre><code class="language-C#">&lt;ItemGroup&gt; &lt;DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" /&gt; &lt;/ItemGroup&gt; </code></pre> <p>Does this work? Heck no. I am going home.</p> <p><strong>Update</strong></p> <p>Ok so this only seems to be a problem when you right click on the Controllers folder and select Add &gt; Controller. If you just select Add &gt; New Item, then select MVC Controller Class, it lets you add one. Annoying.</p> <!--excerpt--> Typescript Interfaces and Optional Properties 2017-02-22T00:00:00+00:00 http://timjames.me/blog/2017/02/22/typescript-interfaces-and-optional-properties/ <p>I love TypeScript after working with it (on an enterprise system) for well over a year now. Using it with ReactJS makes things easier and very type safe. No more issues with case sensitivity Javascript errors, or accidentally assigning a string to a number. Or so I thought!</p> <p>Recently, we came across an issue with the type safety on some of our interfaces. These were interfaces that included only optional properties within them.</p> <p>e.g.</p> <pre><code class="language-TypeScript">interface IInvoiceFilter { invoiceDate?: Date; invoiceNo?: number; } </code></pre> <p>We would then use this interface for what ever we were doing, and using intellisense to see what the properties were on it. Then use it something like this;</p> <pre><code class="language-TypeScript">const invoiceFilter: IInvoiceFilter = { invoiceNo: 1 }; let otherFilter: IInvoiceFilter = {}; otherFilter.invoiceNo = 1; </code></pre> <p>There would then be a method that would take the filter;</p> <pre><code class="language-TypeScript">const filterInvoices = (invoiceFilter: IInvoiceFilter) =&gt; { // do something here with it }; </code></pre> <p>You would then call this with;</p> <pre><code class="language-TypeScript">filterInvoices(invoiceFilter); </code></pre> <!--excerpt--> <p>During some coding, one of the developers wasn’t thinking and did this;</p> <pre><code class="language-TypeScript">filterInvoices('some string value'); </code></pre> <p>Neither Visual Studio intelisense, Gulp Build or Resharper complained about this! We then discovered you could also do this;</p> <pre><code class="language-TypeScript">let invoiceFilter: IInvoiceFilter = {}; invoiceFilter = 'Random string'; </code></pre> <p>Again there was no issue with this? Why is there no issue?</p> <p>This was quick to spot, so we were able to fix it, but I then noticed the same thing again in an interface that we do not have control over. We are using React Router to control our routes in a SPA. Within React Router, there is a component called <code class="language-plaintext highlighter-rouge">Link</code>.</p> <pre><code class="language-TypeScript">&lt;Link to={ internalUrls.Invoice.List }&gt;View Invoices&lt;/Link&gt; </code></pre> <p>The component would render an anchor tag with the correct href which works fine. However, I had to change <code class="language-plaintext highlighter-rouge">internalUrls.Invoice.List</code> from a string property, to a function that returned a string. Once I updated the property, I build the project and ran it. Everything looked fine until I noticed an error in the console. <code class="language-plaintext highlighter-rouge">Warning: Failed propType: Invalid prop 'to' supplied to 'Link'. Check the render method of...</code>. After a quick inspection, I noticed that the <code class="language-plaintext highlighter-rouge">to</code> property is:</p> <p><img src="/img/reactjs/link-interface.jpg" alt="Correct" /></p> <p>So it can either be a string value OR it is an interface with all optional properties.</p> <p>Is this a bug in TypeScript? Or is it a valid feature? I can see that there will be many issues from this when developers make changes like I have. If you know, then please comment below.</p> UmbracoApplicationBase Application shutdown. Details ConfigurationChange 2017-01-13T00:00:00+00:00 http://timjames.me/blog/2017/01/13/umbracoapplicationbase-application-shutdown-configurationchange/ <p>Wow! Has it been so long since my last blog post?! Seems to be! Well why not stick one up on Friday 13th! I have been exceptionally busy for the past year, with a really large project in work which has eaten up all development my time, then family life has taken up the rest.</p> <p>One of the projects I have been working on recently in work involved using the latest version of Umbraco hosted on an Azure VM (Windows Server 2012 R2). The Umbraco installation is just a standard one, and there is nothing fancy within it. Just some datatypes, templates, views and some macros. The dynamic data of the site is loaded via a separate API on the same Azure VM.</p> <p>My client was complaining that the site was slow to load, which I had just put down to it being a test site and the application pool recycling due to inactivity. However I then started to notice that it was exceptionally slow after creating/editing pages in the CMS. I had mentioned this to another developer in the office, and he had said he had a similar issue with another client’s installation, but when the site went live, it all sorted itself out.</p> <p>Today though, I was speaking to another developer who manages another client using Umbraco on another Azure VM, and he was having a similar problem to me on a live site. So we decided to look deeper into this issue and found this nice little error in the Umbraco log file.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2017-01-13 09:52:11,148 [P5216/D2/T4] INFO Umbraco.Core.UmbracoApplicationBase - Application shutdown. Details: ConfigurationChange _shutDownMessage=IIS configuration change HostingEnvironment initiated shutdown HostingEnvironment caused shutdown _shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace() at System.Web.Hosting.HostingEnvironment.InitiateShutdownInternal() at System.Web.Hosting.HostingEnvironment.InitiateShutdownWithoutDemand() at System.Web.Hosting.PipelineRuntime.StopProcessing() </code></pre></div></div> <!--excerpt--> <p>Now that we had noticed the error and talking about it in the office, one of our contractors mentioned that it might be a known issue in that Umbraco updates files in the App_Data folder, which then causes IIS to freak out and restart the Application Pool. The issue is being tracked on umbraco.org <a href="http://issues.umbraco.org/issue/U4-6338">High IO operations on Windows 2012 R2/Windows 8, application shuts down with the ConfigurationChange reason</a></p> <p>Right at the top of this issue, there is a link to a Microsoft hotfix <a href="https://support.microsoft.com/en-us/kb/3052480">support.microsoft.com/en-us/kb/3052480</a>. I installed this to my Azure VM, restarted, and straight away you could see the difference in the site.</p> <p>Why am I writing this blog post about something that is already readily available on the umbraco website? Well, mainly to get out of under the rock and start blogging again, also to make a point. Developers, make sure you are talking amoungst yourselves in your office/community. If you are having issues, talk about them with everyone, as the chances are someone else has experienced the problem and has a solution, or others are seeing the same thing.</p> Project.deps.json could not be found 2017-01-13T00:00:00+00:00 http://timjames.me/blog/2017/01/13/project-debs-json-could-not-be-found/ <p>So you are creating a new ASP.NET Core Web Application (.Net Framework) through visual studio, so select “New Project &gt; Select Template &gt; Name &gt; Ok”, then select the Template you want to use. Then run your shiny new website.</p> <p>BOOM! Build Error</p> <p><img src="/img/vnext/build-error.JPG" alt="Build Error" /></p> <p>There are no errors in the Error List, no warnings and no messages? So you check the build ouput to find</p> <blockquote> <p>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Common.Targets(262,5): error : C:\Projects\My Project\error CS2001: Source file ‘C:\Projects\My Project\Project.deps.json’ could not be found.</p> </blockquote> <!--excerpt--> <p>So what is this? Well in my instance, I created the project with the name “My Project” and it turns out that currently you can’t have spaces in the folder name! So you will need to recreate your project without spaces in the name.</p> AspNet VNext TSX Debugging 2015-12-08T00:00:00+00:00 http://timjames.me/blog/2015/12/08/aspnet-vnext-tsx-debugging/ <p>Following on from my recent post <a href="/2015/12/02/reactjs-with-typescript-in-aspnet-vnext/">ReactJs with TypeScript in AspNet VNext</a>, I have been playing about with .TSX + ReactJS more, and one of the first things I noticed was that I was unable to debug the JavaScript files in the browser.</p> <p>This is down to the way in which Visual Studio + the <code class="language-plaintext highlighter-rouge">tsconfig.json</code> are generating the <code class="language-plaintext highlighter-rouge">.js</code> files which are linked to <code class="language-plaintext highlighter-rouge">.js.map</code> files.</p> <p>From my previous post, we created a simple <code class="language-plaintext highlighter-rouge">App.tsx</code> file that simple output <code class="language-plaintext highlighter-rouge">&lt;h1&gt;Hello World&lt;/h1&gt;</code>. Now if you investigate the generated <code class="language-plaintext highlighter-rouge">.js</code> file, you will see the following in the last two lines;</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ReactDOM.render(React.createElement(MyApp, null), document.getElementById('appMountNode')); //# sourceMappingURL=app.js.map </code></pre></div></div> <!--excerpt--> <p>The <code class="language-plaintext highlighter-rouge">sourceMappingURL</code> is a way to map a combined/minified file back to a “debuggable” file. In this case, the <code class="language-plaintext highlighter-rouge">.js</code> file is being mapped back to <code class="language-plaintext highlighter-rouge">app.js.map</code> which then holds information about the original file. Looking into the <code class="language-plaintext highlighter-rouge">app.js.map</code> file, you will then see the following;</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../scripts/React/app.tsx"],"names":["MyApp","MyApp.constructor","MyApp.render"],"mappings":"....."} </code></pre></div></div> <p>This is informing the browser that the file <code class="language-plaintext highlighter-rouge">app.js</code> should be mapped back to the source <code class="language-plaintext highlighter-rouge">app.tsx</code> with the relative path information. This is great! However, in our folder structure, our <code class="language-plaintext highlighter-rouge">.tsx</code> files are all out with the running website. So if you are to try and debug the JavaScript, you will not be able to as the source file will not be found.</p> <h3 id="one-solution">One Solution</h3> <p>I had a quick search of the internet, and discovered a solution which involved writing a MVC controller which would match the path, check the existence of the file, and then serve this file. However, I didn’t think this was the best solution. So in the end I decided to make use of Gulp.</p> <p>Gulp is already included in the asp.net 5 MVC project templates, and is generating minified js and css for me, so why not use it to allow me to debug my <code class="language-plaintext highlighter-rouge">.tsx</code> files. So I have added this new Task to the <code class="language-plaintext highlighter-rouge">gulpfile.js</code></p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gulp.task("copy", function () { return gulp.src('./scripts/**/*.tsx').pipe(gulp.dest('./wwwroot/scripts/')); }); </code></pre></div></div> <p>This is now copying out my <code class="language-plaintext highlighter-rouge">.tsx</code> files into the wwwroot folder which can then be seen by the browser. Well, they should be seen! However this is a MVC site which has set routes by default. So if you were to run the project now, your <code class="language-plaintext highlighter-rouge">.tsx</code> files would still not be seen. So the next step is to add a static file provider to your default static files. Some good information on this can be found here <a href="http://docs.asp.net/en/latest/fundamentals/static-files.html">Working with Static Files</a>.</p> <p>Open up your Startup.cs file, then go down to the line <code class="language-plaintext highlighter-rouge">app.UseStaticFiles();</code> and replace this with;</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// add .tsx files as static files var provider = new FileExtensionContentTypeProvider(); provider.Mappings.Add(".tsx", "application/javascript"); app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider }); </code></pre></div></div> <p>Save this, and then run the project now. Your <code class="language-plaintext highlighter-rouge">.tsx</code> file will now be served by your app and allow you to debug!</p> <p>This is no way the best way to do this, so if you know of a better/alternative way, then please comment below and let me know.</p> ReactJs with TypeScript in Asp.Net VNext 2015-12-02T00:00:00+00:00 http://timjames.me/blog/2015/12/02/reactjs-with-typescript-in-aspnet-vnext/ <p>Now that the ASP.NET 5 Release Candidate 1 has been <a href="http://blogs.msdn.com/b/webdev/archive/2015/11/18/announcing-asp-net-5-release-candidate-1.aspx">announced</a> and <a href="https://get.asp.net/">released</a>, now is a great time to start playing around with it. So why not start playing around with ReactJs using TypeScript at the same time!</p> <h2 id="background">Background</h2> <p>For those that are not in the know:</p> <h3 id="react"><a href="https://facebook.github.io/react/">React</a></h3> <blockquote> <p>A library for building user interfaces.</p> </blockquote> <p>It was developed by the facebook guys as they started to run into problems, with other JS frameworks, when building their Apps section. So they invented their own!</p> <h3 id="typescript"><a href="http://www.typescriptlang.org/">TypeScript</a></h3> <blockquote> <p>TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.</p> </blockquote> <p>It was developed by Microsoft, more specifically I think it was Mads Kristensen and his team? I might be wrong!</p> <h2 id="getting-started">Getting Started</h2> <p>To begin with, we want to create a new Project in Visual Studio 2015. I am using .Net Framework 4.6.1 and then selecting the ASP.Net Web Application. Then from the ASP.NET 5 Templates, I am going to select the Web Application. This will then create the new Asp.net 5 solution structure for you.</p> <!--excerpt--> <p>If you are not yet familiar with the folder structure, then I suggest you read <a href="http://docs.asp.net/en/latest/tutorials/your-first-aspnet-application.html">Year First ASP.NET 5 Web App Using Visual Studio</a>. This is a great post for creating the app and understanding the new structure.</p> <p>What I noticed, and something which might catch you out, is that there is a new file called <code class="language-plaintext highlighter-rouge">bower.json</code> (controls your JavaScript dependencies), however this file was hidden by default, so I had to select “Show All Files”.</p> <p>Now that you have your Asp.Net 5 Web Application solution, the next step is to add a dependency to react js using the <code class="language-plaintext highlighter-rouge">bowser.json</code> file. This file works pretty much the same as the <code class="language-plaintext highlighter-rouge">project.json</code> file for adding dependencies, in that as you start typing, you get intellisense. So start typing <code class="language-plaintext highlighter-rouge">react</code>, select it from the list, and then tab out. This will then display the version, so select the version you want and tab out again. You will end up with;</p> <p><img src="/img/vnext/react/add-react-to-bower-config.JPG" alt="bower.json structure" /></p> <p>This will then download the react dependencies and add to your Bower dependencies list along with all the required files into the wwwroot &gt; lib folder</p> <p><img src="/img/vnext/react/react-dependencies-added.JPG" alt="dependencies added" /></p> <p>So we don’t forget later, lets add a reference to the core reactjs scripts to our _Layout page just now. So open up Views &gt; Shared &gt; _Layout.cshtml and add script references to both react.js and react-dom.js.</p> <p><img src="/img/vnext/react/dev-app-script-references.JPG" alt="script references" /></p> <h2 id="adding-typescript">Adding TypeScript</h2> <p>Now that we have our react dependencies and scripts sorted, we want to move onto adding TypeScript to our project. Now I already had TypeScript installed into Visual Studio 2015 and I am not sure if TypeScript is automatically included in the VS2015 Update 1, so you might need to go and download and install. Lets assume you already have TypeScript installed, and are ready to add to the project. I followed the instructions here <a href="https://github.com/Microsoft/typescript/wiki/Using-TypeScript-With-ASP.NET-5">Using TypeScript with Asp.Net 5</a> So just follow the instructions on setting up and configuring to generate on save.</p> <p>Once you have created your first little app.tsx file, you are then going to want to add the typed definitions for react. I am adding them to a folder within the Scripts folder named <code class="language-plaintext highlighter-rouge">Typings</code>. You can find them all at <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/react">github.com/DefinitelyTyped</a></p> <p>At this point, add typed definitions for jQuery also. My folder structure now looks like this:</p> <p><img src="/img/vnext/react/folder-structure.JPG" alt="script references" /></p> <h2 id="creating-our-app">Creating our App</h2> <p>You are now ready to start writing some code! yey! By this point, if you have been following the instructions, you should have an app.ts file. You will now want to delete this file and create a new `app.tsx’ file. TSX is the TypeScript version of JSX. If you are familiar with react, then you will have heard of JSX.</p> <p>Once you have your <code class="language-plaintext highlighter-rouge">app.tsx</code> file, add the following code.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// References to our typings file to get intellisense /// &lt;reference path="typings/jquery/jquery.d.ts" /&gt; /// &lt;reference path="typings/react/react-global.d.ts" /&gt; // A '.tsx' file enables JSX support in the TypeScript compiler, // for more information see the following page on the TypeScript wiki: // https://github.com/Microsoft/TypeScript/wiki/JSX /** Properties to be used within our MyApp class */ interface IAppProps { } /** State to be used within our MyApp class */ interface IAppState { } /** MyApp class that is extending the React Component passing in the properties and state */ class MyApp extends React.Component&lt;IAppProps, IAppState&gt; { /** * Default contructor. * @param props */ constructor(props: any) { super(props); } /** * React Render function */ render() { return (&lt;h1&gt;Hello World&lt;/h1&gt;); } } // jQuery on ready //$(() =&gt; { // get our mount node where we want our component to be rendered //var $mountNode = $('#appMountNode'); // render the component to our mound node //ReactDOM.render(&lt;MyApp /&gt;, $mountNode[0]); //}); // based on feedback from davepermen, ignore the jQuery ready code and just have; ReactDOM.render(&lt;myapp/&gt;, document.getElementByID('appMountNode')); </code></pre></div></div> <p>As soon as you click save on the file, you should then see an app.js file be created within your wwwroot &gt; js &gt; mylibs filder (or what ever path you had in your “outDir” within the tsconfig.json file)</p> <p>Build the app, and you should see some errors appear <code class="language-plaintext highlighter-rouge">Build: Cannont use JSX unless the '--jsx' flag is provided</code>. If you have used .tsx files in Visual Studio prior to Asp.Net 5, then you will know that there was a TypeScript Build section within the project properties. This is no longer there, but it is as easy as adding this to your tsconfig.json file. So update your tsconfig.json to include this new line;</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{ "compilerOptions": { "noImplicitAny": false, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "target": "es5", "outDir": "../wwwroot/js/mylibs", "jsx": "react" }, "exclude": [ "node_modules", "wwwroot" ] } </code></pre></div></div> <p>The new `“jsx”: “react” line tells the app to use change the TSX files into JSX files so that they will work with react.</p> <p>Build the app again, and everything should now be fine! So you are ready to run the app. Before you run the app, you will want to add a reference to your app.js file in the _Layout file below your references to the react scripts. Then add your mount html element to somewhere in your views. I added it to the layout page just for testing.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;div class="container body-content"&gt; @RenderBody() &lt;div id="appMountNode"&gt;&lt;/div&gt; &lt;hr /&gt; &lt;footer&gt; &lt;p&gt;&amp;copy; 2015 - VNextStacks&lt;/p&gt; &lt;/footer&gt; &lt;/div&gt; </code></pre></div></div> <p>Run the app and you should now see your “Hello World” header tag!</p> <h3 id="feedback">Feedback</h3> <p>I always try to put together working demos! So if you find anything that isn’t working, or suggestions, then please comment below. :)</p> Changing the Password length in Asp.Net 5 Identity 2015-08-21T00:00:00+00:00 http://timjames.me/blog/2015/08/21/password-length-in-aspnet-vnext/ <p>A while ago I wrote a blog post regarding <a href="http://timjames.me/mvc-3-password-length-dataannotation/">MVC 3 Password Length DataAnnotation</a> in order to easily change the length of the password required to register for an account within your website.</p> <p>This blog post is about how you can easily manage your password password strength in an Asp.Net vNext project (Asp.Net 5) when using the Microsoft.AspNet.Identity framework.</p> <p>If you create a new Asp.Net 5 Web Application in Visual Studio 15 you will see that it is set up to use Microsoft.AspNet.Identity for handling user Authentication.</p> <p>By default it will come with a <code class="language-plaintext highlighter-rouge">RegisterViewModel</code> that has the Password property and various DataAttributes</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } </code></pre></div></div> <p>Similar to my <a href="http://timjames.me/mvc-3-password-length-dataannotation/">MVC 3 Password Length DataAnnotation</a> post, the length of the password is controlled from within the Model, so if you want to change this length then you will have to edit code.</p> <!--excerpt--> <p>So lets get started with how you go about changing the length (and strength) of the password required to register within your website.</p> <h2 id="configuring-identity">Configuring Identity</h2> <p>In order to change the settings for your password, you can configure the Identity service from within the startup.cs file. This is pretty simlple, and is just a matter of adding in a new section of code within the <code class="language-plaintext highlighter-rouge">ConfigureServices(IServiceCollection services)</code> section.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>services.ConfigureIdentity(options =&gt; { options.Password.RequireDigit = true; options.Password.RequiredLength = 10; options.Password.RequireLowercase = true; options.Password.RequireNonLetterOrDigit = true; options.Password.RequireUppercase = true; }); </code></pre></div></div> <p>Now if you try to register, you will be forced to use these tight password rules.</p> <p>This works, but if you want to put these settings into a configuration file, then you can use the <code class="language-plaintext highlighter-rouge">config.json</code> file.</p> <h2 id="using-aspnet-5-configjson">Using Asp.Net 5 config.json</h2> <p>In Asp.Net 5, projects now use a <code class="language-plaintext highlighter-rouge">config.json</code> file which replaces the web.config file that we are so used to using. The config.json file separates out all the configuration from the project.json file which controls dependencies and various other important project setup configuration.</p> <p>By defaut, your config.json should look like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{ "AppSettings": { "SiteTitle": "MyProject" }, "Data": { "DefaultConnection": { "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-MyProject-c2f24376-91a1-48b9-a3ae-5b045044ccfc;Trusted_Connection=True;MultipleActiveResultSets=true" } } } </code></pre></div></div> <p>It is here that we will want to add a new section which you can then use to control the password options within the Identity service. So add the following to your config.json file:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"Identity": { "Password": { "RequireDigit": "false", "RequireLowercase": "false", "RequiredLength": "10", "RequireUppercase": "true", "RequireNonLetterOrDigit": "false" } } </code></pre></div></div> <p>Now back to your <code class="language-plaintext highlighter-rouge">Startup.cs</code> file, and update your configuration options to 1 of two ways. 1st way is to bind each property individually:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>services.ConfigureIdentity(options =&gt; { options.Password.RequireDigit = bool.Parse(Configuration["Identity:Password:RequireDigit"].ToString()); options.Password.RequiredLength = int.Parse(Configuration["Identity:Password:RequiredLength"].ToString()); options.Password.RequireLowercase = bool.Parse(Configuration["Identity:Password:RequireLowercase"].ToString()); options.Password.RequireNonLetterOrDigit = bool.Parse(Configuration["Identity:Password:RequireNonLetterOrDigit"].ToString()); options.Password.RequireUppercase = bool.Parse(Configuration["Identity:Password:RequireUppercase"].ToString()); }); </code></pre></div></div> <p>However there is a much simpler way to actually set your password properties from the <code class="language-plaintext highlighter-rouge">config.json</code> file without having to specify each property in code. Simply change your code to:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>services.ConfigureIdentity(Configuration.GetConfigurationSection("Identity")); </code></pre></div></div> <p>This will automagically load in the config section and bind it to your Password options.</p> <h2 id="still-to-do">Still to do</h2> <p>If you now run your project, as long as the password is more than 6 characters long (set in the <code class="language-plaintext highlighter-rouge">RegisterViewModel</code>) you will then be validated against the Identity Password settings, however if you enter a password less than 6 chars, you will get the error message set in your model. So the next step is to do what we did back in MVC3 and create a custom data attribute for the password which will read in the configuration section.</p> <p><em>Coming soon - the next step!</em></p> My Top 10 Dad Jokes 2015-08-21T00:00:00+00:00 http://timjames.me/blog/2015/08/21/my-top-10-dad-jokes/ <p>I have a bit of a reputation for sharing bad dad jokes. So I thought I would compile a list of my top 10 for you to enjoy!</p> <p>In reverse order</p> <p><strong>10.</strong></p> <blockquote> <p>A lot of people cry when they cut onions. The trick is to not form an emotional bond.</p> </blockquote> <p><strong>9.</strong></p> <blockquote> <p>Sometimes I use words I don’t understand so I can sound more Photosynthesis.</p> </blockquote> <p><strong>8.</strong></p> <blockquote> <p>I cut my finger chopping cheese, but I think that I may have grater problems.</p> </blockquote> <p><strong>7.</strong></p> <blockquote> <p>What would you catch if you had sex with Harry Potter? Genital Hogwarts.</p> </blockquote> <p><strong>6.</strong></p> <blockquote> <p>My pet mouse Elvis died last night. He was caught in a trap.</p> </blockquote> <!--excerpt--> <p><strong>5.</strong></p> <blockquote> <p>I told my wife she was drawing her eyebrows too high. She looked surprised.</p> </blockquote> <p><strong>4.</strong></p> <blockquote> <p>Donald trump better not be president or there will be hell toupee</p> </blockquote> <p><strong>3.</strong></p> <blockquote> <p>We have a genetic predisposition for diarrhoea. Runs in our jeans</p> </blockquote> <p><strong>2.</strong></p> <blockquote> <p>I had a horrible dream last night that I was being chased by Eddie Stobart. It was a logistical nightmare.</p> </blockquote> <p><strong>1.</strong></p> <blockquote> <p>How come Barbie never got pregnant? Because Ken always came in another box</p> </blockquote> <h2 id="just-outside-the-top-10">Just outside the top 10</h2> <h3 id="dream-jokes">Dream Jokes</h3> <blockquote> <p>I had a dream that I was a muffler last night. I woke up exhausted!</p> </blockquote> <h3 id="doctor-jokes">Doctor Jokes</h3> <blockquote> <p>Me: “Doctor, I can’t stop singing the Green Green Grass of Home” Dr: “Sounds like you have Tom Jones syndrome” Me: “Is it common?” Dr: “It’s not unusual”</p> </blockquote> <p><em>If you have some good <strong>dad jokes</strong> then please comment below and let me know!</em></p> Handy Git command reference 2015-08-14T00:00:00+00:00 http://timjames.me/blog/2015/08/14/handy-git-command-reference/ <p>Sooooo like a lot of developers out there, you probably have moments where you completely forget what git command you need to use for the correct job. There are hundreds even thousands of websites out there all with the same information, so I thought I would write another!</p> <p>This is primarily just for my own reference though, so I have everything in one place that I can easily find without hunting through my many document locations.</p> <!--excerpt--> <h2 id="git-command-reference">Git command reference</h2> <h3 id="status">Status</h3> <p><code class="language-plaintext highlighter-rouge">git status</code> - BOOM current status of your repository branch.</p> <h3 id="add">Add</h3> <p><code class="language-plaintext highlighter-rouge">git add --all</code> - Adds tracked and untracked files that have been updated since last commit.</p> <h3 id="commit">Commit</h3> <p><code class="language-plaintext highlighter-rouge">git commit -m 'commit message'</code> - Commits what you have just added</p> <p><code class="language-plaintext highlighter-rouge">git commit -am 'add and commit in one go'</code> - Adds tracked files and commits in one quick line.</p> <h3 id="push">Push</h3> <p><code class="language-plaintext highlighter-rouge">git push origin master</code> - Pushes changes on branch “master” to your remote “origin”.</p> <h3 id="pull">Pull</h3> <p><code class="language-plaintext highlighter-rouge">git pull origin master</code> - Pulls latest version on branch “master” to your local repository from your remote “origin”.</p> <h3 id="branching">Branching</h3> <p><code class="language-plaintext highlighter-rouge">git branch</code> - Lists all the current branch’s within the repository.</p> <p><code class="language-plaintext highlighter-rouge">git branch newbranch</code> - Creates a new branch named “newbranch”.</p> <p><code class="language-plaintext highlighter-rouge">git checkout newbranch</code> - Switches to the “newbranch” branch. All changes and commits will now be to this branch.</p> <p><code class="language-plaintext highlighter-rouge">git checkout master</code> - Switches to the “master” branch. All changes and commits will now be to this branch.</p> <p><code class="language-plaintext highlighter-rouge">git branch -d newbranch</code> - Deletes the branch “newbranch” from your local repository.</p> <p><code class="language-plaintext highlighter-rouge">git push origin :newbranch</code> - Deletes the branch “newbranch” from your remote “origin”.</p> <h3 id="merging">Merging</h3> <p><code class="language-plaintext highlighter-rouge">git merge newbranch</code> - Merges the changes in “newbranch” into the current branch you have checked out.</p> <h3 id="deleting">Deleting</h3> <p><code class="language-plaintext highlighter-rouge">git rm file.txt</code> - Deletes the file from your local repository <strong>AND</strong> deletes the file from your file system.</p> <p><code class="language-plaintext highlighter-rouge">git rm --cached file.txt</code> - Deletes the file from your local repository but not the file system.</p> <h3 id="undoing-file-changes">Undoing file changes</h3> <p><code class="language-plaintext highlighter-rouge">git checkout file.txt</code> - Reverts back to the file from the latest commit on the current branch.</p> <p>For a full and indepth reference see <a href="http://gitref.org/">gitref.org</a></p> <p>Learn <a href="http://learngitbranching.js.org/">Git Branching</a> with a fun interactive tutorial.</p> Me right now bug fixing 2015-08-10T00:00:00+00:00 http://timjames.me/blog/2015/08/10/me-right-now-bug-fixing/ <video src="/media/videos/devlife/debugging.mp4" controls="" preload="" autoplay="" loop="" style="width: 100%;"></video> <!--excerpt--> <p>You fix one bug, another bug appears!</p> <p><em>*I don’t know who originally created this, so if you know comment below and let me know. I would like to give credit. :)</em></p> Sharing an Asp.Net Machine Key for Authentication 2015-08-06T00:00:00+00:00 http://timjames.me/blog/2015/08/06/sharing-an-aspnet-machine-key-for-authentication/ <p>In a recent project that I have been working on, one of the requirements was that we use our client’s Machine Key so that we can authenticate user’s passwords if their users had to login directly into our system. This was mainly to handle a situation where the main website would go down then users could open up our system directly and login.</p> <p>So the client would send us the user details, username/password/passwordsalt and then they supplied us with the Machine Key that they are using in their various environments. The encryption which was being used was the standard out of the box asp.net Membership encryption, so in order to encrypt the typed in password against what is in the database, i used the following code:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public string EncryptPassword(string password, string passwordSalt) { byte[] bytePass = Encoding.Unicode.GetBytes(password); byte[] byteSalt = Convert.FromBase64String(passwordSalt); byte[] byteResult = new byte[byteSalt.Length + bytePass.Length]; Buffer.BlockCopy(byteSalt, 0, byteResult, 0, byteSalt.Length); Buffer.BlockCopy(bytePass, 0, byteResult, byteSalt.Length, bytePass.Length); HashAlgorithm ha = HashAlgorithm.Create("SHA1"); return Convert.ToBase64String(ha.ComputeHash(byteResult)); } </code></pre></div></div> <p>While testing in a c# app this worked great, however when I then ported the code over to vb.net (yes our system is partially in vb.net), the generated encrypted password no longer matched.</p> <!--excerpt--> <p>I had ported over the c# code into this snippet of vb.net</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Public Shared Function MachineKeyEncodePassword(format As Integer, password As String, passwordSalt As String) Dim bytePass As Byte() = Encoding.Unicode.GetBytes(password) Dim byteSalt As Byte() = Convert.FromBase64String(passwordSalt) Dim byteResult As Byte() = New Byte(byteSalt.Length + bytePass.Length) {} System.Buffer.BlockCopy(byteSalt, 0, byteResult, 0, byteSalt.Length) System.Buffer.BlockCopy(bytePass, 0, byteResult, byteSalt.Length, bytePass.Length) Dim ha As HashAlgorithm = HashAlgorithm.Create("SHA1") Return Convert.ToBase64String(ha.ComputeHash(byteResult)) End Function </code></pre></div></div> <p>To me this looked correct and was working, however the Base64String that was being generated was not the same as when running the c# app? What was I doing wrong?</p> <p>Well it turns out that when you are creating a byte array in vb.net, e.g. <code class="language-plaintext highlighter-rouge">New Byte(10) {}</code> you indicate that it’s upper bound will be 10 this it contains 11 elements. In c# if you create a new byte array e.g. <code class="language-plaintext highlighter-rouge">new byte[10];</code> it will create an array of 10 elements from 0-9. So my byte array length was 1 off in the vb.net code.</p> <p>###Solution</p> <p>The very very simple solution to this was to take away this extra element in the array, so I changed one line:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Dim byteResult As Byte() = New Byte((byteSalt.Length + bytePass.Length) - 1) {} </code></pre></div></div> <p>This will create the same length byte array as the c# code and result in the same encrypted password which validates correctly against that in the database!</p> <p>###Side note</p> <p>While working on this little project update, the machine key that had been sent over was in the format</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;machineKey decryptionKey="{hex-key value},IsolateApps" validationKey="{hex-key value},IsolateApps" /&gt;; </code></pre></div></div> <p>Now this was working well on the encryption part, but had now broken my code when trying to set the FormsAuthentication cookie <code class="language-plaintext highlighter-rouge">FormsAuthentication.SetAuthCookie(username, False)</code> and was giving me the error:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>System.Configuration.ConfigurationErrorsException: Decryption key specified has invalid hex characters. </code></pre></div></div> <p>The problem here is that when you include <code class="language-plaintext highlighter-rouge">IsolateApps</code> within the Machine Key config, this cuases ASP.Net to generate a unique key for each application on your server. After reading this blog post <a href="http://blogs.msdn.com/b/webdev/archive/2012/10/23/cryptographic-improvements-in-asp-net-4-5-pt-2.aspx">Cryptographic Improvements in ASP.NET 4.5, pt. 2</a> I read that if you add <code class="language-plaintext highlighter-rouge">compatibilityMode="Framework20SP1"</code> to the Machine Key config, then this would work. It did, I was not able to set the authencation cookie, however this then opened up a can of worms with Microsoft.AspNet.SignalR! So I discovered that just removing <code class="language-plaintext highlighter-rouge">IsolateApps</code> from the config seemed to work.</p> <p>Not sure if this will raise an ugly head later on, so if you have any advice, then please comment below and let me know :)</p> Github Pages with Jekyll and Markdown 2015-07-31T00:00:00+00:00 http://timjames.me/blog/2015/07/31/github-pages-and-jekyll/ <p>I had originally planned on adding this post when I first launched my website on Github Pages, but for some strange reason the post sat in a half-written state and unpublished. It could have also been because I had never managed to get Jekyll running on Windows at that time! I have now though, so see below on how to get this up and running. :)</p> <p>##Github Pages</p> <p>If you have never heard about Github pages before and are looking for somewhere to host your own personal blog, then I would suggest checking it out now. <a href="https://pages.github.com/">pages.github.com</a> host static html websites using your own repository to manage the files. You get one site per GitHub account and unlimited project sites. Simply create a new repository named [username].github.io and you are away!</p> <!--excerpt--> <p>Once you have your repository, you can then start to create static html pages, e.g. <code class="language-plaintext highlighter-rouge">index.html</code> that will then display when navigating to [username].github.io</p> <p>##Blogging with Jekyll</p> <p>Not only does GitHub Pages support static html pages, but it also has support for <a href="https://github.com/jekyll/jekyll">Jekyll</a></p> <blockquote> <p>Jekyll is a blog-aware, static site generator in Ruby <a href="http://jekyllrb.com">http://jekyllrb.com</a></p> </blockquote> <p>Using Jekyll to generate your static html pages makes managing your website layout/headers/footers/menus much easier than manually editing multiple html files. Along with generating html pages from templates, it also makes blogging a lot easier. Jekyll will take your blog post content pages, the layout pages, and various other pages, process them when you push your files up to your repository and then output all the static pages.</p> <p>##Markdown</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Markdown is a lightweight markup language with plain text formatting syntax designed so that it can be converted to HTML and many other formats using a tool by the same name.[5][6] Markdown is often used to format readme files, for writing messages in online discussion forums, and to create rich text using a plain text editor. </code></pre></div></div> <p><a href="https://en.wikipedia.org/wiki/Markdown">Source</a></p> <p>##Running Jekyll on Windows</p> <p>If you are wanting to try this out and run Jekyll on Windows like me, then a SUPER GREAT step by step guide can be found here <a href="http://jekyll-windows.juthilo.com/">Run Jekyll on Windows - A step-by-step guide to setting up Jekyll on Windows by @juthilo</a></p> <p><strong><em>Note</em></strong></p> <p>I found that after installing the Ruby DevKit and running the command <code class="language-plaintext highlighter-rouge">ruby dk.rb init</code> I was unclear as to the next step. In the guide, it simply says:</p> <blockquote> <p>Install the DevKit, binding into your Ruby installation ruby dk.rb install</p> </blockquote> <p>However after trying this it was giving me the error <code class="language-plaintext highlighter-rouge">Invalid configuration or no Rubies listed. Please fix 'config.yml' and rerun 'ruby dk.rb install'</code>. At this point my config.yml file looked like this:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># This configuration file contains the absolute path locations of all # installed Rubies to be enhanced to work with the DevKit. This config # file is generated by the 'ruby dk.rb init' step and may be modified # before running the 'ruby dk.rb install' step. To include any installed # Rubies that were not automagically discovered, simply add a line below # the triple hyphens with the absolute path to the Ruby root directory. # # Example: # # --- # - C:/ruby19trunk # - C:/ruby192dev # --- </code></pre></div></div> <p>It turned out that I had to add the path to my Ruby installation folder to the end of the config.yml file so it now looked like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># This configuration file contains the absolute path locations of all # installed Rubies to be enhanced to work with the DevKit. This config # file is generated by the 'ruby dk.rb init' step and may be modified # before running the 'ruby dk.rb install' step. To include any installed # Rubies that were not automagically discovered, simply add a line below # the triple hyphens with the absolute path to the Ruby root directory. # # Example: # # --- # - C:/ruby19trunk # - C:/ruby192dev # --- - "C:/Ruby22-x64" </code></pre></div></div> NuGet pack fails with exited with code 1 2015-07-29T00:00:00+00:00 http://timjames.me/blog/2015/07/29/nuget-pack-fails-with-exited-with-code-1/ <p>We had a very annoying issue in the office recently regarding building a NuGet package with a Post-build event command line. One of our developers had created a Utilities project which would be installed via our local NuGet store, and had added the Post-build event to create the NuGet package.</p> <p>The Post-build command was pretty simple and worked. It is the command which is referenced on the <a href="https://docs.nuget.org/create/creating-and-publishing-a-package">nuget.org Creating and Publishing</a> a Package website</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$(SolutionDir).nuget\nuget.exe pack $(ProjectDir)$(ProjectFileName) -Prop Configuration=$(ConfigurationName) </code></pre></div></div> <p>Everything was working great on the original developer’s machine, also on another guys machine, but not on mine or the 4th developer’s. Both I and the other developer are on Windows 7, the other two guys are on Windows 8. The Windows 7 machines were getting the error:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The command "C:\Projects\SolutionFolder\.nuget\nuget.exe pack C:\Projects\SolucationFolder\ProjectFolder\project.csproj -Prop Configuration=Debug" exited with code 1. </code></pre></div></div> <!--excerpt--> <p>This error didn’t really give much information, so after a bit of searching the web I <a href="http://stackoverflow.com/questions/22151402/how-can-i-resolve-the-error-the-command-exited-with-code-1">read</a> that it would be useful to turn on Diagnostic build output verbosity. So I switched this on, built the project and looked through the Build output to see a line:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Task "Exec" (TaskId:83) Task Parameter:WorkingDirectory=bin\Debug\ (TaskId:83) Task Parameter:Command=C:\Projects\SolutionFolder\.nuget\nuget.exe pack C:\Projects\SolucationFolder\ProjectFolder\project.csproj -Prop Configuration=Debug (TaskId:83) C:\Projects\SolutionFolder\.nuget\nuget.exe pack C:\Projects\SolucationFolder\ProjectFolder\project.csproj -Prop Configuration=Debug (TaskId:83) Attempting to build package from 'project.csproj'. (TaskId:83) Packing files from ''. (TaskId:83) Using 'project.nuspec' for metadata. (TaskId:83) The path is not of a legal form. (TaskId:83) C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(4713,5): error MSB3073: The command "C:\Projects\SolutionFolder\.nuget\nuget.exe pack C:\Projects\SolucationFolder\ProjectFolder\project.csproj -Prop Configuration=Debug" exited with code 1. Done executing task "Exec" -- FAILED. (TaskId:49) </code></pre></div></div> <p>This again didnt’t really give much information either. So we decided to see what would happen if we ran the command straight through a Command Prompt window. This then gave us another error <code class="language-plaintext highlighter-rouge">Unable to find 'project.dll'. Make sure the project has been built</code></p> <p>WTF! The project was being built, and the dll’s were in the bin/debug folder!</p> <p>###Solution</p> <p>After spending a couple of hours on this, what we really needed was a beauty sleep. The next morning within 5 mins the original developer <a href="http://stackoverflow.com/questions/21583070/nuget-pack-fails-with-unable-to-find-outputpathitem-fullpath">discovered</a> the solution.</p> <p>All it took was adding an extra <code class="language-plaintext highlighter-rouge">-Prop</code> at the end of the command line:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$(SolutionDir).nuget\nuget.exe pack $(ProjectDir)$(ProjectFileName) -Prop Configuration=$(ConfigurationName) -Prop Platform=AnyCPU </code></pre></div></div> <p>We are still not sure what the issue was and why this fixes it. It must be something to do with Win7 vs Win8 mixed with NuGet.exe and the command line (I am not 100% sure what though, so if you know why, <strong>comment below and let me know</strong>).</p> DNX SDK version 'dnx-clr-win-x86.1.0.0-beta5' failed to install. 2015-07-27T00:00:00+00:00 http://timjames.me/blog/2015/07/27/stepping-into-visual-studio-2015/ <p>I have been playing around with Visual Studio 2015 preview for a while now (nothing hard core), so naturally I want to install the final version when it was released. Straight away I came across a couple little issues which made the install/startup not so simple.</p> <!--excerpt--> <p>Firstly, when trying to install the final version, it will not install side-by-side with the preview version, so you will need to uninstall this. This seemed to take quite a while to do, so ended up just leaving this running overnight.</p> <p>Secondly, and much more of an issue, was when I decided to create a new asp.net 5 Web Application. I recieved this error:</p> <p><img src="/img/vnext/dnx-sdk.jpg" alt="DNX SDK Version" /></p> <p><code class="language-plaintext highlighter-rouge">DNX SDK version 'dnx-clr-win-x86.1.0.0-beta5' failed to install</code></p> <p>Now this is a known issue already, but I thought I would just put a little post up on my website for future reference.</p> <p><strong><em>Solution</em></strong></p> <p>The problem is down to not having Powershell 3.0 installed on your machine, so just head on over to <a href="https://www.microsoft.com/en-gb/download/details.aspx?id=34595">Windows Management Framework 3.0</a> and download the version for you. I downloaded version <code class="language-plaintext highlighter-rouge">Windows6.1-KB2506143-x64.msu</code>. Notice at this point, and I am not sure if it just me, but the download option doesn’t work as the link is blocked due to some files on the page being loaded via http rather than https. I just opened up my Network console and opened the download link directly in the browser. When installing, you will go through the standard installation process, so just follow the instructions on screen. Once installed you might have to reboot your machine, I do…</p> <p>Once rebooted, open VS2015 and create a new asp.net 5 project. Hopefully everything will now be ok!</p> Working with MVC Areas in Asp.Net vNext (MVC 6) 2014-12-13T00:00:00+00:00 http://timjames.me/blog/2014/12/13/mvc-areas-with-vnext/ <p>I have recently started to play around Visual Studio 2015 Preview and Asp.Net vNext. As usual, I jump into new stuff like this with the mindset of building projects the same way that I would have with other versions. So in this case, I was trying to build a MVC 6 website the same way that I would build a MVC 3/4/5 website.</p> <p>Straight away I wanted to add an Area to the project. In Visual Studio 2013, I would have right clicked on the MVC project, selected “Add” and then “Area”, typed in the name for the Area and then Visual Studio would scaffold this for me.</p> <!--excerpt--> <p>The output would be a new folder called Area, then within this you would have your standard MVC folders (Controllers, Models, Views) along with some other files that would automagically register the area within the project.</p> <p>Within Visual Studio 2015 Preview, this Add &gt; Area option is currently not there. I am not sure if it will be added in at some point, but for now the process is more manual but very very simple.</p> <p>##Adding an Area to your project</p> <p>Assuming you have created a new Asp.Net 5 Web Application, and can see all the lovely new file types like bower.json, config.json, project.json along with the new folder structure that includes the new wwwroot folder.</p> <p>###Step 1</p> <p>Right click on your MVC project and add a new Folder named “Areas”, then right click on this new folder and create a new folder to match the name of your area, e.g. “MyArea”. Right click again on this new folder and add a Controllers and Views folder. You want to end up with this;</p> <p><img src="/img/vnext/areas/areas-folder-structure.jpg" alt="Areas folder structure" /></p> <p>###Step 2</p> <p>Add a new MVC Controller Class to your Controllers folder named <code class="language-plaintext highlighter-rouge">HomeController</code>. By default VS will add the basic code for your controller + and Index view. Now once you have this, decorate the <code class="language-plaintext highlighter-rouge">HomeController</code> class with a new Attribute called <code class="language-plaintext highlighter-rouge">Area</code>. Name this after your area which in this case is “MyArea”.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Area("MyArea")] public class HomeController : Controller { // GET: /&lt;controller&gt;/ public IActionResult Index() { return View(); } } </code></pre></div></div> <p>###Step 3</p> <p>You will now need to tell your MVC app to use a new Area route similar to AreaRegistration in MVC 4/5 but much simpler. Open up the <code class="language-plaintext highlighter-rouge">Startup.cs</code> file and then Map a new route within the existing <code class="language-plaintext highlighter-rouge">app.UseMvc(routes =&gt;</code> code.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Add MVC to the request pipeline. app.UseMvc(routes =&gt; { // add the new route here. routes.MapRoute(name: "areaRoute", template: "{area:exists}/{controller}/{action}", defaults: new { controller = "Home", action = "Index" }); routes.MapRoute( name: "default", template: "{controller}/{action}/{id?}", defaults: new { controller = "Home", action = "Index" }); }); </code></pre></div></div> <p>Your new route will work exactly the same as the “default” route with the addition of the area. So if you now create an Index view for your <code class="language-plaintext highlighter-rouge">HomeController</code> and navigate to <code class="language-plaintext highlighter-rouge">/MyArea/Home</code> or <code class="language-plaintext highlighter-rouge">/MyArea/Home/Index</code> you will see your index view.</p> <p>Job Done!</p> <p>Many thanks to <a href="https://twitter.com/davidfowl">@davidfowl</a> for helping me out over in the <a href="https://jabbr.net/#/rooms/AspNetvNext">AspNetvNext Jabbr room</a> and pointing me in the direction of a sample on GitHub <a href="https://github.com/aspnet/Mvc/tree/dev/samples/MvcSample.Web">MvcSample.Web</a></p> Stopping and Starting your Application Pool with Octopus Deploy 2014-11-06T00:00:00+00:00 http://timjames.me/blog/2014/11/06/octopusdeploy-stop-start-apppool/ <p>Depending on your Web Server set up, you might not be able to overwrite the Bin folder without some manually intervention. Usually it is because there is a process using files within the Bin folder and you will have to stop the application pool first.</p> <p>Octopus will soon inform you if this is the case when deploying your package to the server, and will give you the error message:</p> <p><span color="red"><code class="language-plaintext highlighter-rouge">One or more files in the directory may be locked by another process. You could use a PreDeploy.ps1 script to stop any processes that may be locking the file. Error details follow.</code></span></p> <!--excerpt--> <p>There is a pretty easy solution for this. You can run some Custom PowerShell scripts during Pre/Post deployment.</p> <p>To set up the Pre/Post deployment scripts within the deployment of a NuGet package step, select the step and click on Configure features. This will then give you the option to Enable Custom PowerShell scripts.</p> <p><img src="/img/custom-scripts.jpg" alt="Export Layers to files options" /></p> <p>This will then give you the option to enter pre-deployment, deployment and post-deployment scripts. You will want to enter the <a href="http://library.octopusdeploy.com/#!/step-template/actiontemplate-iis-apppool-stop">Stop PowerShell script</a> in the pre box.</p> <p><img src="/img/pre-deploy.png" alt="Export Layers to files options" /></p> <p>And then the <a href="http://library.octopusdeploy.com/#!/step-template/actiontemplate-iis-apppool-start">Start PowerShell script</a> in the post box.</p> <p><img src="/img/post-deploy.png" alt="Export Layers to files options" /></p> <p>In both scripts, you will notice <span style="color: red;"><code class="language-plaintext highlighter-rouge">appPoolName</code></span>, this is a Variable which you will need to set up with the name of the application pool named <code class="language-plaintext highlighter-rouge">AppPoolName</code>.</p> <p>In your next release you will see two additional steps in the Task Log. If you see these and everything is green then you know everything is ok!</p> <p><img src="/img/pre-deploy-success.png" alt="Export Layers to files options" /> <img src="/img/post-deploy-success.png" alt="Export Layers to files options" /></p> <p>Job Done!</p> <p>Many thanks to <a href="https://twitter.com/ahandersson">@ahandersson</a> for helping me out over in the <a href="https://jabbr.net/#/rooms/octopus">Octopus Jabbr room</a></p> Entity Connection String within Octopus Deploy 2014-11-06T00:00:00+00:00 http://timjames.me/blog/2014/11/06/entity-connectionstring-octopusdeploy/ <p>I have been using Octopus Deploy more and more recently and it is quickly becoming my deployment tool of choice. If you haven’t heard about it, then I would highly recommend that you go and check it out now! <a href="https://octopusdeploy.com/">Octopus Deply</a></p> <p>One of the projects I have been working on uses the EntityFramework for data access, so there is a <code class="language-plaintext highlighter-rouge">System.Data.EntityClient</code> connection string within the web.config. The EntityClient connection string differs from the standard SqlClient string in that it contains metadata along with the connection string. It also contains <code class="language-plaintext highlighter-rouge">&amp;quot;</code> within this string.</p> <!--excerpt--> <p>##Problem</p> <p>Here lies the problem. If you want to replace the connection string using variables within Octopus deploy, then the connection string (by default) will not be replaced correctly. What ends up happening is that <code class="language-plaintext highlighter-rouge">&amp;quot;</code> is replaced with <code class="language-plaintext highlighter-rouge">&amp;amp;quot;</code> which results in a broken EntityClient!</p> <p>Now this is by design within Octopus deploy and there is an argument whether this is actually a <a href="http://help.octopusdeploy.com/discussions/problems/3609-ampersand-and-escaping-of-environment-variables">bug or a feature</a>.</p> <p>##Solution</p> <p>The solution to this is pretty simple actually. If you copy your EntityClient connection string, then paste into an Octopus deploy varaible, replace <code class="language-plaintext highlighter-rouge">&amp;quot;</code> with <code class="language-plaintext highlighter-rouge">"</code>. When Octopus replaces the connection string in the web.config it automatically translates <code class="language-plaintext highlighter-rouge">"</code> back into <code class="language-plaintext highlighter-rouge">&amp;quot;</code>!</p> <p>Job done!</p>