<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>2017 on Funky Si's Blog (Dev)</title><link>https://blog-dev.funkysi1701.com/2017/</link><description>Recent content in 2017 on Funky Si's Blog (Dev)</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><managingEditor>funkysi1701@gmail.com (Simon Foster)</managingEditor><webMaster>funkysi1701@gmail.com (Simon Foster)</webMaster><lastBuildDate>Thu, 28 Dec 2017 20:00:45 +0000</lastBuildDate><atom:link href="https://blog-dev.funkysi1701.com/2017/index.xml" rel="self" type="application/rss+xml"/><item><title>Looking back at 2017</title><link>https://blog-dev.funkysi1701.com/posts/2017/looking-back-at-2017/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Thu, 28 Dec 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/looking-back-at-2017/</guid><category term="StarTrek">StarTrek</category><category term="Goals">Goals</category><category term="Azure">Azure</category><category term="Baby">Baby</category><category term="C-Sharp">C-Sharp</category><description>&lt;p&gt;As 2017 starts to draw to a close let’s look at some of the highlights from the past year.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Edward" src="https://blog-dev.funkysi1701.com/images/2017/DSC_0376-e1510563039193-225x300.jpg" loading="lazy"
width="225" height="300"
/&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Edward&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In November I became a father again and celebrated the arrival of Edward into the world. Before the birth I was worried how well my first son James would adapt to the new arrival but I am happy to say I didn’t need to, he mostly ignores the new arrival.&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Star Trek&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In September the latest Star Trek TV series Discovery arrived on Netflix. I have been very positive so far about the show, I am still positive however there are things that annoy me about the new show, however I am keen to see the next episode each week so they are definitely doing something right.&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Office move&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In May I helped my employer move to brand new &lt;a href="https://www.funkysi1701.com/posts/2017/office-move/" target="_blank" rel="noopener noreferrer"&gt;offices&lt;/a&gt;
. This was a lot of hard work, but everything went as planned and our new home is great.&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Side projects
&lt;img class="img-fluid" alt="Google Play" src="https://blog-dev.funkysi1701.com/images/2017/googleplay.jpg" loading="lazy"
width="512" height="512"
/&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I blogged in February about having a side project but it wasn’t until later in the year that this solidified into what I am working on now. It started as a way to understand &lt;a href="https://www.funkysi1701.com/posts/2017/interfaces/" target="_blank" rel="noopener noreferrer"&gt;interfaces&lt;/a&gt;
this then led to learning Xamarin and creating an android app to help promote this blog. Troy Hunt expanded his HIBP API to include passwords that have been in data breaches, I then started working on pwned passwords which is a simple android frontend for this.&lt;/p&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Learning R&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In Feb I also experimented with a new programming language &lt;a href="https://www.funkysi1701.com/posts/2017/learning-r/" target="_blank" rel="noopener noreferrer"&gt;R&lt;/a&gt;
. It started with a problem about converting exchange rates and ended with a SQL stored procedure that executed some R code, I still want to learn lots more but it was a good example of the sorts of thing you can build with R.&lt;/p&gt;
&lt;ol start="6"&gt;
&lt;li&gt;DNS programmatically&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;One of my most successful blogs was about how you can create &lt;a href="https://www.funkysi1701.com/posts/2017/creating-dns-records-programmatically/" target="_blank" rel="noopener noreferrer"&gt;dns&lt;/a&gt;
records within your application eg sites that have yourname.domain in the url. It was a great chance to look at how dns works and learn more about what azure can do to manage this. I want to expand on this and build something.&lt;/p&gt;
&lt;p&gt;So that was 2017, for some ideas about what 2018 might have in store for me look out for my next blog post.&lt;/p&gt;</description></item><item><title>Getting started with Azure Tables</title><link>https://blog-dev.funkysi1701.com/posts/2017/azure-table-storage/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sun, 17 Dec 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/azure-table-storage/</guid><category term="Azure">Azure</category><category term="SQL">SQL</category><category term="TableStorage">TableStorage</category><category term="Database">Database</category><description>&lt;p&gt;Azure Table storage is cheap way to store data, however it has some drawbacks that you should be aware of.&lt;/p&gt;
&lt;p&gt;Azure Table storage is a simple way to store NoSQL data with key/attribute pairs. I am very familiar with storing data in SQL databases and would still choose SQL over Table storage, however Table storage is significantly cheaper so could be worth investigating depending on your project.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.troyhunt.com/working-with-154-million-records-on/" target="_blank" rel="noopener noreferrer"&gt;Troy Hunt&lt;/a&gt;
makes use of Table storage for his Have I been pwned? website so there are projects out there that make use of it to great affect.&lt;/p&gt;
&lt;p&gt;To work with Table storage you need to use a nuget package &lt;strong&gt;WindowsAzure.Storage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Install-Package WindowsAzure.Storage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To load data from a Table in Azure Table storage I use the following code&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CloudTable table = tableClient.GetTableReference(&lt;span style="color:#e6db74"&gt;&amp;#34;tablename&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TableOperation retrieveOperation = TableOperation.Retrieve&amp;lt;Entity&amp;gt;(PartitionKey, Rowkey);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;table.CreateIfNotExists();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TableResult retrievedResult = table.Execute(retrieveOperation);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Example eg = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Example();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (retrievedResult.Result != &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; eg.ID = ((Entity)retrievedResult.Result).Id;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; eg.Date = ((Entity)retrievedResult.Result).Date;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; eg;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You need to create a class (called Entity in the example above) derived from TableEntity which defines the Partitionkey and Rowkey, plus and other columns you want to store in table storage. The row key and partition key uniquely identify the data in the table, think of this as the primary key of the table if you are used to SQL. This class must also contain a parameterless constructor.&lt;/p&gt;
&lt;p&gt;This is the only way to retrieve data, using the partitionkey and rowkey. If you want to retrieve a specific piece of data you would need to retrieve all rows and then search them for what you need. For me this is not a big problem as I only have 150 rows but if you have millions of rows you may need to think carefully how to use this.&lt;/p&gt;
&lt;p&gt;To save data I use a very similar piece of code&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CloudStorageAccount storageAccount = CloudStorageAccount.Parse(path);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CloudTable table = tableClient.GetTableReference(&lt;span style="color:#e6db74"&gt;&amp;#34;tablename&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Entity post = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Entity(ID, DateTime.Now);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TableOperation insertOperation = TableOperation.InsertOrReplace(post);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;table.CreateIfNotExists();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;table.Execute(insertOperation);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I create a Entity object and then pass this as a parameter into the InsertOrReplace method.&lt;/p&gt;
&lt;p&gt;To delete data it is also very similar, you create an entity object and pass this as a parameter to the Delete method.&lt;/p&gt;
&lt;p&gt;When debugging my table storage code I found the &lt;a href="https://azure.microsoft.com/en-gb/features/storage-explorer/" target="_blank" rel="noopener noreferrer"&gt;Azure Storage Explorer&lt;/a&gt;
very useful for seeing what data actually existed in the table and what might be throwing an error, usually something wrong with my Entity.&lt;/p&gt;
&lt;p&gt;I mentioned earlier that Table Storage was cheaper than SQL Azure. Well for my simple playing about with things I have found my monthly charge of £10+ has been reduced to £1+ If I were to build anything that is more than just me learning about how it works I would probably continue to use SQL but for the cost of learning new tech it is well worth giving table storage a try.&lt;/p&gt;</description></item><item><title>Zero code changes outside of git</title><link>https://blog-dev.funkysi1701.com/posts/2017/get-zero-code-changes-outside-source-control/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 13 Nov 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/get-zero-code-changes-outside-source-control/</guid><category term="Git">Git</category><category term="SQL">SQL</category><category term="VisualStudio">VisualStudio</category><category term="SourceCode">SourceCode</category><description>&lt;p&gt;Source control is bread and butter for web developers, however not so much for SQL developers and other business people. One of my goals for the coming year is to get the whole of my team using source control processes.&lt;/p&gt;
&lt;p&gt;One of the arguments against using source control is there will always be a few exceptions where it won’t be used. Lets look at a few scenarios to help make the case for source control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scenario One&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Web Dev 1 makes a change in production to fix an issue and doesn’t use source control. Web Dev 2 is working on a new feature and makes use of source control. He is given the sign-off to deploy his new feature and in the process undoes Web Dev 1’s fix.&lt;/p&gt;
&lt;p&gt;Management blames Web Dev 2 as they “broke” stuff during the deployment. Web Dev 2 doesn’t understand what happened and Web Dev 1 is oblivious to the entire scenario despite in reality being part of the problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scenario Two&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A SQL Dev works all night to fix a problem. He deploy to production and doesn’t notice a missed where clause due to lack of sleep.&lt;/p&gt;
&lt;p&gt;—&lt;/p&gt;
&lt;p&gt;Let’s look at these two scenarios done with the whole team buying into source control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scenario One&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Web Dev 1 makes a change in production to fix an issue and also commits to source control. This takes him an extra 5 minutes (if that!) Web Dev 2 is working on a new feature and makes use of source control. He is given the sign-off to deploy his new feature and in the process merges Web Dev 1’s fix before he deploys to production.&lt;/p&gt;
&lt;p&gt;Management is happy with Web Dev 1, nothing is broken and new functionality has made the website better not worse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scenario Two&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A SQL Dev works all night to fix a problem. He deploy to production and doesn’t notice a missed where clause due to lack of sleep, he also commits to source control this takes him an extra 5 minutes (if that!).&lt;/p&gt;
&lt;p&gt;In the morning a colleague looks through the commits made during the night and queries the missing where clause. A fix is made in source control and deployed, management and the client are unaware that a problem was created and fixed.&lt;/p&gt;
&lt;p&gt;—&lt;/p&gt;
&lt;p&gt;These are simple scenarios but I cannot think of any situation where the outcome would be better to not use source control. These examples assume no continuous deployment, adding this to the system before every team has bought into source control would cause bugs and issues all over the place.&lt;/p&gt;
&lt;p&gt;However with a team that is 100% behind source control continuous deployment can achieve an amazing productivity boost. After every commit code could be automatically tested, reviewed by other members of the team and deployed to test environments for further analysis. Only tested code that has been reviewed can get anywhere near production environments.&lt;/p&gt;
&lt;p&gt;Having said all this there are ways especially on the SQL side to mitigate loosing changes while you work on training individuals and convincing management. Before any code is deployed to production do a schema compare. If you only see changes you have made you can proceed, if you don’t shout at your team.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Code Reviews&lt;br&gt;
Team awareness of what is being changed&lt;br&gt;
History of changes&lt;br&gt;
Smoother Deployments&lt;br&gt;
Automation&lt;br&gt;
Better Teamwork&lt;br&gt;
Diff changes between different versions&lt;br&gt;
Many more&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Time to learn tools&lt;br&gt;
Remember to commit changes&lt;br&gt;
Technologies that use binary files harder to version control&lt;/p&gt;</description></item><item><title>SQL with Visual Studio Code</title><link>https://blog-dev.funkysi1701.com/posts/2017/sql-with-visual-studio-code/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 06 Nov 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/sql-with-visual-studio-code/</guid><category term="Database">Database</category><category term="SQL">SQL</category><category term="VisualStudio">VisualStudio</category><description>&lt;p&gt;Writing SQL queries is typically done with SQL Management Studio (SSMS). However this tool is a bit of a beast so let’s look at how you could use Visual Studio Code instead.&lt;/p&gt;
&lt;p&gt;Visual Studio Code is a free text editor but it is so much more than just a text editor. VS Code can be downloaded from &lt;a href="https://code.visualstudio.com/Download" target="_blank" rel="noopener noreferrer"&gt;https://code.visualstudio.com/Download&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;To work with SQL Server download the mssql extension. Press &lt;strong&gt;CTRL+SHIFT+P&lt;/strong&gt; and then Select &lt;strong&gt;Install Extension&lt;/strong&gt; and type &lt;strong&gt;mssql&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Intellisense in Visual Studio Code is brilliant, better than SSMS. Lets look at how to get it all set up.&lt;/p&gt;
&lt;p&gt;Create a new file and set the language type to SQL (Press &lt;strong&gt;CTRL+K,M&lt;/strong&gt; )&lt;/p&gt;
&lt;p&gt;Open the command palette, &lt;strong&gt;CTRL+SHIFT+P&lt;/strong&gt; and type SQL to show the mssql commands. Select the Connect command.&lt;/p&gt;
&lt;p&gt;Then select &lt;strong&gt;Create Connection Profile&lt;/strong&gt; , this creates a profile to connect with your SQL Server. Follow the prompts to get it all setup.&lt;/p&gt;
&lt;p&gt;Look in the bottom right corner of the status bar and you should see you are connected.&lt;/p&gt;
&lt;p&gt;Now if you type sql you will see a long list of SQL code snippets that you could use.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="SQL Code snippets" src="https://blog-dev.funkysi1701.com/images/2017/vscode-sql-snippets.png" loading="lazy"
width="1016" height="534"
/&gt;
&lt;/p&gt;
&lt;p&gt;Choose a snippet to create, and edit it as required. When you are happy press **CTRL+SHIFT+E ** to execute.&lt;/p&gt;
&lt;p&gt;This is basically all there is to it. However this is an incredibly powerful way of working, the intellisense instantly tells you what database objects you can use in your query and there is a wealth of different snippets you can use.&lt;/p&gt;
&lt;p&gt;When returning data you get a similar view to SSMS but you can save as Excel, CSV or JSON.&lt;/p&gt;
&lt;p&gt;SSMS is a very graphical way of doing things, you can double click a table and see its columns or indexes. VS Code relies on TSQL commands but you have access to exactly the same information.&lt;/p&gt;
&lt;p&gt;For more information about VS Code and the mssql extension check out &lt;a href="https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-develop-use-vscode" target="_blank" rel="noopener noreferrer"&gt;https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-develop-use-vscode&lt;/a&gt;
&lt;/p&gt;</description></item><item><title>Interfaces are cool!</title><link>https://blog-dev.funkysi1701.com/posts/2017/interfaces-are-cool/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 31 Oct 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/interfaces-are-cool/</guid><category term="BadDesign">BadDesign</category><category term="Interface">Interface</category><description>&lt;p&gt;A while back I &lt;a href="https://www.funkysi1701.com/posts/2017/interfaces/" target="_blank" rel="noopener noreferrer"&gt;blogged&lt;/a&gt;
about learning about interfaces as I didn’t really understand the value of them. I do now.&lt;/p&gt;
&lt;p&gt;I created an application that used interfaces so I could learn how it worked. I created a Logger Interface and created multiple classes that implemented that interface so I could swap out the different implementations easily. I created a SQL Logger and a File Logger and my code could be written and be completely unaware of which implementation it was using.&lt;/p&gt;
&lt;p&gt;This application uses SQL Azure and so I have a monthly bill to pay. Wouldn’t it be cool if I could reduce this bill? How about using the cheaper table storage instead?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Easy!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Create a new class that implements my interface and all I need to do is write the three methods defined in my interface and I can swap from SQL Azure to table storage.&lt;/p&gt;
&lt;p&gt;Another benefit to interfaces is testing. Say I have an interface called inotification for sending notifications, I can have several implementations of this email, twitter, slack etc&lt;/p&gt;
&lt;p&gt;None of these implementations should be used in unit tests, as you don’t want a tweet being sent every time you run your tests. Why not create an implementation that simply returns something for each method call and doesn’t actually do anything. I can then run my tests with my fake implementation which tests my code logic but not the implementation I have chosen (this can be tested later on with integration tests or user testing if required).&lt;/p&gt;
&lt;p&gt;This is pretty much all I have to say about interfaces. I just like how I can swap different implementations.&lt;/p&gt;
&lt;p&gt;It does take a bit of work to get the interface setup. I found that when writing the second implementation the interface would need to change slightly, mostly as it was badly designed to begin with. I think for beginners there may be some value to writing multiple implementations of an interface so you can be sure your interface is good, however I am sure with experience this will not be required.&lt;/p&gt;</description></item><item><title>Create DNS records programmatically</title><link>https://blog-dev.funkysi1701.com/posts/2017/creating-dns-records-programmatically/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 16 Oct 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/creating-dns-records-programmatically/</guid><category term="Azure">Azure</category><category term="DNS">DNS</category><description>&lt;p&gt;DNS is the backbone of the internet. It converts domain names into IP addresses. But how can we do clever things with it?&lt;/p&gt;
&lt;p&gt;Making DNS changes has always been a pain. You have to remember what company you registered your domain name with, then locate the login details for their website, login and fill in some web form and wait for the changes to replicate across the internet.&lt;/p&gt;
&lt;p&gt;There are various websites that assign you a custom subdomain name like name.domain.com, obviously they must do this programmatically, they don’t have a guy following the above process.&lt;/p&gt;
&lt;p&gt;Lets see how we could do this.&lt;/p&gt;
&lt;p&gt;My first thought was to make use of the DNSimple API. &lt;a href="https://developer.dnsimple.com/v2/" target="_blank" rel="noopener noreferrer"&gt;https://developer.dnsimple.com/v2/&lt;/a&gt;
The API allows all sort of DNS changes to be made, however this is a paid service so let’s look at other options.&lt;/p&gt;
&lt;p&gt;Azure now has a DNS section. You can go to the portal, add a DNS zone, and then add as many A, CNAME and MX records as you need. This is of course no better than doing it manually.&lt;/p&gt;
&lt;p&gt;Azure offers a &lt;a href="https://learn.microsoft.com/en-us/azure/dns/dns-sdk" target="_blank" rel="noopener noreferrer"&gt;SDK&lt;/a&gt;
and an example Visual Studio project. Let&amp;rsquo;s look at how it works.&lt;/p&gt;
&lt;p&gt;First you need to setup some credentials to use your Azure subscription. The easiest way to do this is with powershell.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Login&lt;span style="color:#960050;background-color:#1e0010"&gt;–&lt;/span&gt;AzureRmAccount
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$sp = New-AzureRmADServicePrincipal &lt;span style="color:#960050;background-color:#1e0010"&gt;–&lt;/span&gt;DisplayName exampleapp &lt;span style="color:#960050;background-color:#1e0010"&gt;–&lt;/span&gt;Password &lt;span style="color:#e6db74"&gt;&amp;#34;{provide-password}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Sleep &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;New-AzureRmRoleAssignment &lt;span style="color:#960050;background-color:#1e0010"&gt;–&lt;/span&gt;RoleDefinitionName Contributor &lt;span style="color:#960050;background-color:#1e0010"&gt;–&lt;/span&gt;ServicePrincipalName $sp.ApplicationId
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will create a AD Service Principal which has access to your Azure subscription.&lt;/p&gt;
&lt;p&gt;You need to get the following IDs from the Azure portal.&lt;/p&gt;
&lt;p&gt;subscriptionId for your subscription&lt;br&gt;
tenantId or the Azure AD Directory ID&lt;br&gt;
applicationId of the service principal created above&lt;br&gt;
password you entered into the powershell script above&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; serviceCreds = &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; ApplicationTokenProvider.LoginSilentAsync(tenantId, clientId, secret);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; dnsClient = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; DnsManagementClient(serviceCreds);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dnsClient.SubscriptionId = subscriptionId;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; recordSetParams = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; RecordSet();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;recordSetParams.TTL = &lt;span style="color:#ae81ff"&gt;3600&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;recordSetParams.ARecords = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; List&amp;lt;ARecord&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;recordSetParams.ARecords.Add(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ARecord(&lt;span style="color:#e6db74"&gt;&amp;#34;1.2.3.4&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; recordSet = &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; dnsClient.RecordSets.CreateOrUpdateAsync(resourceGroupName, &lt;span style="color:#e6db74"&gt;&amp;#34;funkysi1701.com&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;, RecordType.A, recordSetParams);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above code connects to Azure and creates an A record for test.funkysi1701.com that points at the ip address 1.2.3.4.&lt;/p&gt;
&lt;p&gt;Other DNS records can be created in a similar way.&lt;/p&gt;
&lt;p&gt;The above example creates a new RecordSet but you can use the following to delete or get existing records.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; recordSet = dnsClient.RecordSets.Get(resourceGroupName, &lt;span style="color:#e6db74"&gt;&amp;#34;funkysi1701.com&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;, RecordType.A);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dnsClient.RecordSets.Delete(resourceGroupName, &lt;span style="color:#e6db74"&gt;&amp;#34;funkysi1701.com&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;, RecordType.A);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now I have found out that I can write a console app to edit my DNS records I need to change the nameservers for all my domains so I can take advantage of this new feature.&lt;/p&gt;</description></item><item><title>Discovery – My thoughts so far</title><link>https://blog-dev.funkysi1701.com/posts/2017/discovery-my-thoughts-so-far/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 10 Oct 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/discovery-my-thoughts-so-far/</guid><category term="StarTrek">StarTrek</category><category term="Discovery">Discovery</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/2017/DAD0hTKUAAAUkTP.jpg"/><description>&lt;p&gt;I tried to resist but I am going to have to write about the new Star Trek series Discovery. Warning this post is going to include SPOILERS. If you read on you have been warned.&lt;/p&gt;
&lt;p&gt;I watched the first two episodes of the brand new Star Trek TV show. As I am an international viewer I used Netflix, if you are from the US you need to use CBS All Access.
&lt;img class="img-fluid" alt="Promotional image from Star Trek Discovery" src="https://blog-dev.funkysi1701.com/images/2017/DAD0hTKUAAAUkTP.jpg" loading="lazy"
width="1199" height="663"
/&gt;
&lt;/p&gt;
&lt;p&gt;I have heard a lot of complaining that the show is not free to watch. CBS is making Star Trek Discovery to make money, if they don’t make money they will stop making it. Its as simple as that.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.netflix.com" target="_blank" rel="noopener noreferrer"&gt;Netflix&lt;/a&gt;
costs £5.99 per month and &lt;a href="https://www.paramountplus.com/home/" target="_blank" rel="noopener noreferrer"&gt;CBS All Access&lt;/a&gt;
costs $5.99 per month. I don’t believe this is a lot of money. The 5.99 above allows you to watch any of the 726 Star Trek episodes at any time of day whenever you want as many times as you want, plus you have access to all the other movies or TV shows available. I don’t think this is too much to ask.&lt;/p&gt;
&lt;p&gt;Back to Discovery. I loved it! It felt like Star Trek. I had feared it might only share the name and would be an action filled TV show that had little in common with what he had seen before. I was wrong this is definitely a show that can proudly call itself Star Trek.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Klingons&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When it was first announced that the Klingons would feature in the new show I was a bit “meh”. We had done lots with the Klingons before and they had never been my favourite alien race.
&lt;img class="img-fluid" alt="Redesigned Klingons from Star Trek Discovery" src="https://blog-dev.funkysi1701.com/images/2017/star-trek-discovery-klingons-1002567-1280x0.jpg" loading="lazy"
width="1280" height="704"
/&gt;
&lt;/p&gt;
&lt;p&gt;The look of the Klingons was also going to be changed, I have to admit this didn’t bother me. Klingons have had their look updated before. In 1966 Klingons had dark faces and smooth foreheads, in 1979 the forehead ridges were added as the first Star Trek movie was made, and now Discovery has removed all hair from Klingons. I can explain it away as productional changes, I don’t need an on screen explanation like we had on Enterprise (or even DS9).&lt;/p&gt;
&lt;p&gt;What I have seen so far is a menacing alien race that fits with what we have seen before with lots of references to honor, Kahless and speaking Klingon. I must admit reading all the subtitles is getting a bit tiresome, but that is a minor issue.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conflict&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Historically Star Trek has not featured conflict between the main starfleet characters due to the idea that humanity has evolved beyond this. DS9 got round this by having Odo and Kira who are not starfleet characters so can have a little bit of conflict. Discovery has completely abandoned this idea.&lt;/p&gt;
&lt;p&gt;In the pilot episode, the Michael Burnham commits mutiny on her captain, even attacking her with a vulcan nerve pinch. In the third episode we finally meet the discovery crew. Gone are the TNG days where the ships crew are like a family, I am not sure I can think of a single character that would call another character “friend”. We are in a time of war so this would be expected, however I do hope we see deepening friendships form between characters.&lt;/p&gt;
&lt;p&gt;I am OK with the change to feature more conflict. I must admit the darkness of the third episode, did stop to make me think a bit, however by the fourth episode I was won over.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cast&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The story is concentrated around Michael Burnham, so I do worry that other characters won’t get a look in. However from what I have seen Michael Burnham is a great character. She is a strong female character, with a intriguing back story relating to Sarek and possibly also Spock.&lt;/p&gt;
&lt;p&gt;Saru the alien character on the show, played by the very tall Doug Jones is great. From the trailers he was all about sensing death, but there is far more to him than that. I am looking forward to learn more about him and his threat ganglia.&lt;/p&gt;
&lt;p&gt;As the show has gone on we have started to learn about the other characters like Captain Lorca, Tilly and Paul Stamets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Title Sequence&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I don’t like the opening title sequence, it feels very cheap like a draft version which hasn’t been finished yet. I was looking forward to a title sequence that would show off the USS Discovery, maybe like TNG where it warps around our own solar system. What we see is some of the tech that features in Star Trek which is nice but I want more. The theme tune while great that it features parts from the classic theme doesn’t stand on its own. I can hum all the other TV shows themes, and now after 4 episodes would struggle to do that.&lt;/p&gt;
&lt;p&gt;However I expect that after a while I will grow to like this more.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overall&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I like Discovery and I will keep watching it. I want to find out what happens to the characters. There are no annoying characters like other shows have had. There is character development, none of the characters are going to finish where they started. I want more friendship between characters, but I expect that will come, I want more exploring and doing Star Trek stuff, but most of all I want more episodes, roll on next weeks show.&lt;/p&gt;
&lt;p&gt;Other things I noticed&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sound effects on the bridge are awesome, it makes me feel at home&lt;/li&gt;
&lt;li&gt;The USS Discovery doesn’t feature in the first two episodes despite being the title of the show.&lt;/li&gt;
&lt;li&gt;Others have noted that Captain Georgiou has books on her shelf which feature classic episode titles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Did you know you can track episodes from Star Trek Discovery in &lt;a href="https://www.episodeatlas.com/" target="_blank" rel="noopener noreferrer"&gt;Episode Atlas&lt;/a&gt;
.&lt;/p&gt;</description></item><item><title>Star Trek is back with Discovery</title><link>https://blog-dev.funkysi1701.com/posts/2017/star-trek-is-back-with-discovery/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Fri, 22 Sep 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/star-trek-is-back-with-discovery/</guid><category term="StarTrek">StarTrek</category><category term="Discovery">Discovery</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/2017/gqojtfz1dhmxoiri7g8p.png"/><description>&lt;p&gt;In &lt;a href="https://www.funkysi1701.com/posts/2015/star-trek-is-back-in-2017/" target="_blank" rel="noopener noreferrer"&gt;November 2015&lt;/a&gt;
it was announced that a new Star Trek series was going to be launched. It has been a long wait with multiple delays but Star Trek Discovery is finally here.&lt;/p&gt;
&lt;p&gt;Star Trek Discovery launches in the US on 24th September and in the UK on 25th September.&lt;/p&gt;
&lt;iframe title="YouTube video: Star Trek Discovery trailer" src="https://www.youtube.com/embed/UoV3kc05Nwc?rel=0" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;
&lt;p&gt;Lets have a look back how we got here.&lt;/p&gt;
&lt;p&gt;Star Trek was created by Gene Roddenberry in the 1960s. He imagined a show where we would explore the galaxy while also exploring the human condition. He described it as a wagon train to the stars. However it was cancelled after 79 episodes and three seasons due to budget cuts and low viewers.&lt;/p&gt;
&lt;p&gt;After cancellation its popularity boomed in reruns. In the mid 1970s an animated series was created. But demand for Star Trek continued until a new Star Trek show was commissioned called Phase Two.&lt;/p&gt;
&lt;p&gt;In 1977 Star Wars came out, and the phase two idea was cancelled and turned into a movie. In 1979 we got Star Trek The Motion Picture. It went massively over budget and failed to really capture the Star Trek spirit.&lt;/p&gt;
&lt;p&gt;A much cheaper sequel was created in 1982 Star Trek II: The Wrath of Khan with Roddenberry taking more of a back seat. A film widely considered to be one of the best trek films. Four more feature films starring the original cast were made.&lt;/p&gt;
&lt;p&gt;However in 1987 Gene Roddenberry teamed up with Rick Berman and The Next Generation was created with a brand new cast. The series ran for seven seasons set roughly a century after the adventures of Kirk and Spock.&lt;/p&gt;
&lt;p&gt;Popularity of Star Trek soured and this led Rick Berman to help create the spin off series Deep Space 9, Voyager and lastly Enterprise along with four feature films continuing the adventures of the TNG cast. When Enterprise was cancelled in 2005, Star Trek appeared to be dead after 18 years on TV.&lt;/p&gt;
&lt;p&gt;However in 2009 movie creator JJ Abrams recast the classic crew for the big screen. The film was big on action, but took place in an alternative timeline allowing for familiar characters to have new adventures without interfering with events depicted in the TV shows.&lt;/p&gt;
&lt;p&gt;Two sequels to this film have been produced and are bringing Star Trek back into popularity. This has given rise to Discovery. Star Trek is returning to the TV screen and it is going to be great.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Discovery" src="https://blog-dev.funkysi1701.com/images/2017/gqojtfz1dhmxoiri7g8p.png" loading="lazy"
width="800" height="450"
/&gt;
&lt;/p&gt;</description></item><item><title>Azure Friday</title><link>https://blog-dev.funkysi1701.com/posts/2017/azure-friday/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 18 Sep 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/azure-friday/</guid><category term="Azure">Azure</category><category term="ApplicationInsights">ApplicationInsights</category><description>&lt;p&gt;I think Azure is great, but there is loads to it so I can never know about all of its features. There is a video series hosted by Scott Hanselman called &lt;a href="https://learn.microsoft.com/en-us/shows/azure-friday" target="_blank" rel="noopener noreferrer"&gt;Azure Fridays&lt;/a&gt;
which I have started to watch in an effort to keep more up to date about some of its cool features.&lt;/p&gt;
&lt;iframe title="Azure Friday: Debug .NET apps in production with the Snapshot Debugger in Application Insights" src="https://learn.microsoft.com/en-us/shows/azure-friday/debug-net-apps-in-production-snapshot-debugger-in-application-insights/player" width="960" height="540" frameborder="0" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;
&lt;p&gt;I watched this video recently and it is all about application insights and new ways you can debug your web applications by creating snapshots. I am a big fan of application insights so adding extra ways to debug my apps is a big win for me. Once I get this feature working in my code I will no doubt blog about it.&lt;/p&gt;</description></item><item><title>Azure Functions</title><link>https://blog-dev.funkysi1701.com/posts/2017/azure-functions/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 12 Sep 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/azure-functions/</guid><category term="Azure">Azure</category><category term="DevOps">DevOps</category><description>&lt;p&gt;I recently blogged about using &lt;a href="https://www.funkysi1701.com/posts/2017/using-azure-webjobs-to-automate-stuff/" target="_blank" rel="noopener noreferrer"&gt;Azure Web Jobs&lt;/a&gt;
, Azure Function is another way of doing the same thing, lets look at how they work.&lt;/p&gt;
&lt;p&gt;(Sorry its been a while since I blogged but I suspect an erratic schedule will continue for the next few months.)&lt;/p&gt;
&lt;p&gt;To create an Azure Function go to the Azure portal and click add new and search for &amp;ldquo;Function App&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Give your app a name and select the usual resource group and location settings.&lt;/p&gt;
&lt;p&gt;Now when you open Function Apps you should see your new app.&lt;/p&gt;
&lt;p&gt;I want my Function App to run on a schedule so I clicked the + next to functions and selected TimerTrigger. I am a c# programmer so I selected this option as well.&lt;/p&gt;
&lt;p&gt;Give your function a name and specify using the usual cron notation how often it should run. I want mine to run at 9.30pm each night so use 0 30 21 * * *&lt;/p&gt;
&lt;p&gt;Now comes the code bit. By default you get a window with the following code in it&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; System;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Run(TimerInfo myTimer, TraceWriter log)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; log.Info(&lt;span style="color:#e6db74"&gt;$&amp;#34;C# Timer trigger function executed at: {DateTime.Now}&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is entirely up to you what you get your function to do. In my case I just wanted to call a URL on a schedule so I created some code that used httpclient.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; System;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; System.Net.Http;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; Task Run(TimerInfo myTimer, TraceWriter log)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; log.Info(&lt;span style="color:#e6db74"&gt;$&amp;#34;Buffer 0 function executed at: {DateTime.Now}&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HttpClient client = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpClient();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; result = &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; client.GetAsync(&lt;span style="color:#e6db74"&gt;&amp;#34;URL&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; resultContent = &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; result.Content.ReadAsStringAsync();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; log.Info(resultContent);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once you have created your app and it has run you can use the monitor section to view success and failures.&lt;/p&gt;
&lt;p&gt;There is loads more you can do with Azure Function but this is a good place to start.&lt;/p&gt;</description></item><item><title>Pwned Pass available on Play Store</title><link>https://blog-dev.funkysi1701.com/posts/2017/pwned-pass-available-from-the-play-store/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 14 Aug 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/pwned-pass-available-from-the-play-store/</guid><category term="Android">Android</category><category term="Mobile">Mobile</category><category term="App">App</category><category term="PwnedPass">PwnedPass</category><description>&lt;p&gt;Pwned Pass is now available from the Google Play Store.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Pwned Pass" src="https://blog-dev.funkysi1701.com/images/2017/Screenshot_20170813-205152.png" loading="lazy"
width="1080" height="1920"
/&gt;
&lt;/p&gt;
&lt;p&gt;Pwned Pass is a simple android app that allows you to type in a password and tells you if it has been used in a data breach.&lt;/p&gt;
&lt;p&gt;Troy Hunt of &lt;a href="https://haveibeenpwned.com/" target="_blank" rel="noopener noreferrer"&gt;Have I Been Pwned?&lt;/a&gt;
recently added a new API to his website which allows you to search his extensive database of pwned passwords, 306 million of them. I have simply created a Android frontend to this API.&lt;/p&gt;
&lt;p&gt;The API itself takes a SHA1 hash of the password and either returns a HTTP 200 if the password is found or a HTTP 404 if the password does not exist in the HIBP database. For more details of how Troy Hunt created this check out his &lt;a href="https://www.troyhunt.com/introducing-306-million-freely-downloadable-pwned-passwords/" target="_blank" rel="noopener noreferrer"&gt;blog post&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;My app simply generates a SHA1 hash of anything that is typed in and then passes this to Troy Hunt’s API. I then get the HTTP return code so I know if the password exists or not.&lt;/p&gt;
&lt;p&gt;It should be noted that: &lt;strong&gt;Do not send any password you actively use to a third-party service – even this one!&lt;/strong&gt; I don’t log anything that you type into my app and all I am then doing is passing a SHA1 hash over SSL to HIBP. However you shouldn’t trust my word alone.&lt;/p&gt;
&lt;p&gt;The app itself is written in Visual Studio with Xamarin Forms in a similar fashion to the app I talked about &lt;a href="https://www.funkysi1701.com/posts/2017/android-app-development-and-the-visual-studio-mobile-centre/" target="_blank" rel="noopener noreferrer"&gt;last week&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;As I am using Xamarin Forms there is the potential that I may develop iPhone or UWP versions of this code in the future. With that in mind I have made use of interfaces for the android specific parts of the code.&lt;/p&gt;
&lt;p&gt;I also make use of the &lt;a href="https://www.nuget.org/packages/modernhttpclient/" target="_blank" rel="noopener noreferrer"&gt;modernhttpclient&lt;/a&gt;
nuget package due to problems I encountered with httpclient and SSL. This is due to limitations of what libraries are available in mono and what has been implemented, I suspect there are better ways to solve this but that is all part of the fun.&lt;/p&gt;
&lt;p&gt;Please do have a look at Pwned Pass and let me know what you think. Especially if it doesn’t work or throws errors. I would like to spend time making this app as good as I can make it.&lt;/p&gt;</description></item><item><title>Android apps with Mobile Centre</title><link>https://blog-dev.funkysi1701.com/posts/2017/android-app-development-and-the-visual-studio-mobile-centre/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 07 Aug 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/android-app-development-and-the-visual-studio-mobile-centre/</guid><category term="App">App</category><category term="Azure">Azure</category><category term="Android">Android</category><description>&lt;p&gt;For the past week or so I have been playing around with Xamarin and creating an android app.&lt;/p&gt;
&lt;p&gt;Well I now have an app in the Google Play Store.
&lt;img class="img-fluid" alt="Screenshot of my Android app listing in the Google Play Store" src="https://blog-dev.funkysi1701.com/images/2017/Screenshot_20170806-190053.png" loading="lazy"
width="1080" height="1920"
/&gt;
&lt;/p&gt;
&lt;p&gt;Before you rush and download the app I must warn you that it doesn’t do much yet. It displays some content that is on my website and there are a few links to allow sharing of content. I have some ideas to display content from my blog and allow sharing. I also have some other ideas for apps that might actually be useful to people that are not me. If you have ideas or feature requests do let me know.&lt;/p&gt;
&lt;p&gt;Ok how did I go about creating this app and getting it in the app store?&lt;/p&gt;
&lt;p&gt;Xamarin is now part of Visual Studio so step one is install all the Xamarin features to Visual Studio and build an app.&lt;/p&gt;
&lt;p&gt;Next I wanted to monitor my app. Now I know Application Insights doesn’t support apps so what tools are out there? HockeyApp is something I had heard of but they are in the process of being replaced with &lt;code&gt;https://appcenter.ms/apps&lt;/code&gt;. (Edit: Visual Studio App Center was retired on March 31, 2025)&lt;/p&gt;
&lt;p&gt;It was relatively easy to hook up my app to Visual Studio Mobile Centre. First install the required nuget packages. Then add using statements and the following line to your MainActivity.cs file (these instructions are available on the Mobile Centre)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; Microsoft.Azure.Mobile;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; Microsoft.Azure.Mobile.Analytics;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; Microsoft.Azure.Mobile.Crashes;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; Microsoft.Azure.Mobile.Distribute;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; Microsoft.Azure.Mobile.Push;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MobileCenter.Start(&lt;span style="color:#e6db74"&gt;&amp;#34;[Unique ID]&amp;#34;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt;(Analytics), &lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt;(Crashes), &lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt;(Distribute), &lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt;(Push));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now you can connect the Mobile Centre to your source code (VSTS in my case) and get it to run a build for every commit.&lt;/p&gt;
&lt;p&gt;One complexity of the build is that you need to supply a keystore file (basically a certificate to digitally sign your app). I found the best way to do this was to use Visual Studio to create the file.&lt;/p&gt;
&lt;p&gt;In VS2017 there is a option called Archive Manager under the tools menu. In here click the distribute button and select Ad-hoc. In the signing identity section you can create a keystore file. Enter a few details and a keystore file will be created in AppData\Local\Xamarin\Mono for Android\Keystore[keystore name][keystore name.keystore]&lt;/p&gt;
&lt;p&gt;Once you have added the keystore file to your build you can enable the distribute option. Now you will get an email after every build with a link to install your app.&lt;/p&gt;
&lt;p&gt;Every time your app crashes the details will be logged in the crashes section for you to explore and fix the issues.&lt;/p&gt;
&lt;p&gt;The Analytics section allows you to explore how your app is being used. You can also add Analytics.TrackEvent(&amp;ldquo;Feature X&amp;rdquo;) to measure the usage of different features.&lt;/p&gt;
&lt;p&gt;There are more things you can do which I will explore more at another time along with how to get your app into the Google Play Store.&lt;/p&gt;</description></item><item><title>Creating NuGet packages with VSTS</title><link>https://blog-dev.funkysi1701.com/posts/2017/creating-nuget-packages/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 31 Jul 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/creating-nuget-packages/</guid><category term="NuGet">NuGet</category><category term="C-Sharp">C-Sharp</category><category term="VisualStudio">VisualStudio</category><description>&lt;p&gt;For a while I have found myself writing the same bits of code for different web projects. This annoys me as it goes against the DRY principle (don’t repeat yourself).&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Nuget" src="https://blog-dev.funkysi1701.com/images/2017/nuget.png" loading="lazy"
width="444" height="135"
/&gt;
One possible solution is to write your own nuget packages. You can then add this piece of code to any project you work on.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nuget.org/" target="_blank" rel="noopener noreferrer"&gt;nuget.org&lt;/a&gt;
is the public nuget feed where any developer can download nuget packages. You could publish your nuget package here, but your might want to restrict access so better to create a private nuget feed.&lt;/p&gt;
&lt;p&gt;Lets look at how we create a nuget feed in Visual Studio. First thing you need to do is install the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms.feed" target="_blank" rel="noopener noreferrer"&gt;Package Management&lt;/a&gt;
extension to Visual Studio Team Services (its free for less than 5 users), this will add a packages section under the build menu.&lt;/p&gt;
&lt;p&gt;Before you can start using this new feature you need to add a Package Management License in the users hub.&lt;/p&gt;
&lt;p&gt;Once that is done you can create a feed. You need to give your feed a name, decide if only members of the current project or everyone in your account should have access to read and contribute to.&lt;/p&gt;
&lt;p&gt;Now you have a feed you could use the nuget package command to create a nupkg file and then nuget push command to add it to your feed. A better way is to get Visual Studio Team Services to do all the hard work.&lt;/p&gt;
&lt;p&gt;Create a new project in Visual Studio Team Service to house your nuget package. In the build section add an empty build definition. Choose a build agent, I am using the Hosted VS2017. Then add the following steps nuget restore, Visual Studio Build, nuget pack and nuget push.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nuget restore – this step is only needed if your code depends on other packages. If it depends on other packages that are only in your feed you must specify your feed in the feeds and authentication section.&lt;/li&gt;
&lt;li&gt;Visual Studio Build – this builds your code like you would in Visual Studio. The only config I made to this step was to specify Release in configuration.&lt;/li&gt;
&lt;li&gt;nuget pack – this creates the nupkg file from your built project. In configuration to package specify the same as you specified in the previous step (in my case Release)&lt;/li&gt;
&lt;li&gt;nuget push – this publishes to your feed, so of course you need to specify your feed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One last thing to configure is to enable the continuous integration option in triggers. This means whenever you push code all these steps will run and you have a new version of your nuget package.&lt;/p&gt;
&lt;p&gt;In Visual Studio you need to create a *.nuspec file, this contains all the meta data about your nuget package. Let look at an example.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;package&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;metadata&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;$id$&lt;span style="color:#f92672"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.2&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Nuget&lt;span style="color:#f92672"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;authors&amp;gt;&lt;/span&gt;Simon Foster&lt;span style="color:#f92672"&gt;&amp;lt;/authors&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;owners&amp;gt;&lt;/span&gt;Simon Foster&lt;span style="color:#f92672"&gt;&amp;lt;/owners&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;requireLicenseAcceptance&amp;gt;&lt;/span&gt;false&lt;span style="color:#f92672"&gt;&amp;lt;/requireLicenseAcceptance&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;An example of a nuget package.&lt;span style="color:#f92672"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;releaseNotes&amp;gt;&lt;/span&gt;Release Notes&lt;span style="color:#f92672"&gt;&amp;lt;/releaseNotes&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;copyright&amp;gt;&lt;/span&gt;Copyright 2017&lt;span style="color:#f92672"&gt;&amp;lt;/copyright&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;projectUrl&amp;gt;&lt;/span&gt;https://[yourVSaccount].visualstudio.com/nuget/&lt;span style="color:#f92672"&gt;&amp;lt;/projectUrl&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/metadata&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/package&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One last thing to mention is version numbers. You can either change the version number in your *.nuspec file everytime you push changes. This will create stable packages like 1.0, 1.1, 1.2 etc&lt;/p&gt;
&lt;p&gt;However you can use the automatic version number setting in the nuget pack build step. However I have found this only ever creates pre-release packages and I haven’t found a way to upgrade a package from pre-release to stable.&lt;/p&gt;
&lt;p&gt;This is a really neat way to reuse your code in multiple projects. I have only been looking at this for a few days and I have already extracted code to do with emails, creating excel downloads and database related methods. I suspect that doing this will also have a side benefit of forcing me to create code with fewer dependencies so more code can be turned into a nuget package.&lt;/p&gt;</description></item><item><title>Async and Await</title><link>https://blog-dev.funkysi1701.com/posts/2017/async-and-await/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 24 Jul 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/async-and-await/</guid><category term="Async">Async</category><category term="Await">Await</category><category term="C-Sharp">C-Sharp</category><description>&lt;p&gt;For a while the Async and Await commands in c# have confused me.&lt;/p&gt;
&lt;p&gt;Like most things the best way to learn about something is to use it in a real world example. I am currently adding an email alert feature to a website. This is an ideal example of something that would benefit from Asynchronous programming. There is no need for the webpage to wait to send 1000s of emails, lets just send a call to get started and allow the browser to carry on as normal.&lt;/p&gt;
&lt;p&gt;This is my first try at using async and await so feel free to suggest best practises in the comments.&lt;/p&gt;
&lt;p&gt;Lets start with a Send method in my EmailController.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; ActionResult Send(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; id, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; pageId, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; userID)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (!Authorize.checkPageIsAuthorised(userID, (Authorize.PageIds)pageId))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Redirect(&lt;span style="color:#e6db74"&gt;&amp;#34;/login&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Task&amp;lt;&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;&amp;gt; t = SendNotifications(id,userID);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Redirect(Request.UrlReferrer.ToString());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This simply checks to see if you have permission to the page. If not redirects to the login page otherwise it makes a method call and redirects back to the page it came from.&lt;/p&gt;
&lt;p&gt;Lets have a look at that method call in more detail.&lt;/p&gt;
&lt;p&gt;Task&lt;string&gt; t = SendNotification(id, userid);&lt;/p&gt;
&lt;p&gt;SendNotification doesn’t return a normal string it returns a Task&lt;string&gt;, so lets look at how we are creating this.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; Task&amp;lt;&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;&amp;gt; SendNotifications(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; id,&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; type,&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; userid)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//logic ommitted&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; ef.SendEmail(model, emailHtmlBody);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;OK&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The return type is set to Task but it has the aysnc keyword appended to it. It also makes a call with the await keyword.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; Task SendEmail(EmailModel model,&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; emailHtmlBody)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//logic removed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; smtp.SendMailAsync(message);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So that is it. My first bit of code that uses Async and Await. My controller calls a method asynchronously which then calls another method asynchronously which sends emails asynchronously.&lt;/p&gt;
&lt;p&gt;Async – This enables the Await keyword to be used in the method&lt;/p&gt;
&lt;p&gt;Await – This is where things get asynchronous. The await keyword allows the code to wait asynchronously for the long running code to complete.&lt;/p&gt;</description></item><item><title>How good is your SSL?</title><link>https://blog-dev.funkysi1701.com/posts/2017/how-good-is-your-ssl/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 17 Jul 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/how-good-is-your-ssl/</guid><category term="SSL">SSL</category><category term="Security">Security</category><description>&lt;p&gt;
&lt;img class="img-fluid" alt="Troy Hunt SSL expert" src="https://blog-dev.funkysi1701.com/images/2017/Troy-Hunt-Profile-Photo.jpg" loading="lazy"
width="800" height="800"
/&gt;
&lt;/p&gt;
&lt;p&gt;I recently watched Troy Hunt’s &lt;a href="https://www.pluralsight.com/courses/https-every-developer-must-know" target="_blank" rel="noopener noreferrer"&gt;What Every Developer Must Know about HTTPS&lt;/a&gt;
course on Pluralsight. Its very good and really make you think about SSL certificates and how to correctly implement them.&lt;/p&gt;
&lt;p&gt;One thing in particular Troy mentions is the website &lt;a href="https://www.ssllabs.com/ssltest/index.html" target="_blank" rel="noopener noreferrer"&gt;SSL Labs&lt;/a&gt;
. This website allows you to test a websites implementation of SSL. A grade of A to F is assigned with A being the best and F being the worst.&lt;/p&gt;
&lt;p&gt;Troy Hunt has a &lt;a href="https://www.troyhunt.com/do-you-really-want-bank-grade-security/" target="_blank" rel="noopener noreferrer"&gt;blog&lt;/a&gt;
post where he discusses how Australian Banks score. Lets look at a few UK banks.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Bank&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;SSL Certificate&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Grade&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Home Page Under SSL&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HSBC&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.hsbc.co.uk" target="_blank" rel="noopener noreferrer"&gt;www.hsbc.co.uk&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nationwide&lt;/td&gt;
&lt;td&gt;onlinebanking.nationwide.co.uk&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NatWest&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.nwolb.com" target="_blank" rel="noopener noreferrer"&gt;www.nwolb.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barclaycard&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.barclaycard.co.uk" target="_blank" rel="noopener noreferrer"&gt;www.barclaycard.co.uk&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;A-&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barclays&lt;/td&gt;
&lt;td&gt;bank.barclays.co.uk&lt;/td&gt;
&lt;td&gt;A-&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lloyds Bank&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.lloydsbank.com" target="_blank" rel="noopener noreferrer"&gt;www.lloydsbank.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Royal Bank of Scotland&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.rbsdigital.com" target="_blank" rel="noopener noreferrer"&gt;www.rbsdigital.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standard Chartered&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.sc.com" target="_blank" rel="noopener noreferrer"&gt;www.sc.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Virgin Money&lt;/td&gt;
&lt;td&gt;uk.virginmoney.com&lt;/td&gt;
&lt;td&gt;A+&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Santander&lt;/td&gt;
&lt;td&gt;retail.santander.co.uk&lt;/td&gt;
&lt;td&gt;A-&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;On the whole the ratings are all quite good with all being in the range A-C. However I have also indicated if they have SSL on the home page. Only 4 out 10 website listed above have the home page load under SSL.&lt;/p&gt;
&lt;p&gt;Why does this matter as long as the login is under SSL? Any page that loads over http is potentially at risk from a man in the middle attack. A fake malicious home page could contain links to any page and trick users into entering personal information.&lt;/p&gt;
&lt;p&gt;If you want to test a bank or other website not listed here. Go to &lt;a href="https://www.ssllabs.com/ssltest/index.html" target="_blank" rel="noopener noreferrer"&gt;https://www.ssllabs.com/ssltest/index.html&lt;/a&gt;
and type the address that is on the SSL certificate in to the search. The good news is that this site scores a A.&lt;/p&gt;
&lt;p&gt;Troy mentions that there is rapid growth in the adoption of SSL, there is also rapid growth in improving ratings. One of these banks went from a C to an A during the course of writing this blog.&lt;/p&gt;</description></item><item><title>Writing your first test</title><link>https://blog-dev.funkysi1701.com/posts/2017/writing-your-first-test/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 10 Jul 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/writing-your-first-test/</guid><category term="Act">Act</category><category term="Arrange">Arrange</category><category term="Assert">Assert</category><category term="Testing">Testing</category><description>&lt;p&gt;Whenever I write a new test I have to think how best to do it. Hopefully I can summarise a few tips here to help get started.&lt;/p&gt;
&lt;h2 id="arrange-act-assert"&gt;Arrange Act Assert&lt;a class="anchor ms-1" href="#arrange-act-assert" aria-label="Permalink: Arrange Act Assert"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first thing I think about when writing a test is Arrange, Act, Assert. Arrange, Act, Assert is a pattern for writing the tests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arrange&lt;/strong&gt; – This gets things in order ready to execute the test.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Act&lt;/strong&gt; – This executes the method you want to test.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Assert&lt;/strong&gt; – This compares the value produced in the Act step with a known value typically with a method similar to the following&lt;/p&gt;
&lt;p&gt;Assert.AreEqual(expected value, actual value)&lt;/p&gt;
&lt;p&gt;Say for example you wanted to test a method called ReturnsTrue() which does nothing but returns a value of true. This method is in a class called ReturnsTrueClass&lt;/p&gt;
&lt;p&gt;The Arrange step in this example would be.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ReturnsTrueClass t = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ReturnsTrueClass();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Act step in this example would be.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; result = t.ReturnTrue();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Assert step in this example would be.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Assert.AreEqual(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;, result);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a stupidly simple example but hopefully you get the idea of how you can build all your tests with these three steps.&lt;/p&gt;
&lt;p&gt;Recently I saw a tweet complaining that someone has mixed up expected and actual in the Assert statement.&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p lang="en" dir="ltr"&gt;There is a minor but special hell reserved for those who mix up the expected and actual parameters in Assert.Equals&lt;/p&gt;&amp;mdash; Keith Williams (@zogface) &lt;a href="https://twitter.com/zogface/status/882737770095149056?ref_src=twsrc%5Etfw"&gt;July 5, 2017&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;
&lt;p&gt;At first glance this probably isn’t the worst mistake to make as if your tests are all passing actual and expected are the same.&lt;/p&gt;
&lt;p&gt;However tests will fail, that is the whole point of them, you can then fix bits of code. If you have mixed up actual and expected it adds extra time to debugging and figuring out what values are produced from your code and what you are expecting it to produce. It may be your test uses a mocking framework and somewhere in there, there is an issue, with mixed up expected/actual you may assume a problem in your code rather than the test.&lt;/p&gt;
&lt;p&gt;Also, how do you make such an error? When I type Assert.AreEquals() in Visual Studio, Visual Studio tells me what each parameter does, it takes a matter of seconds to do this, just by hovering over the code.&lt;/p&gt;
&lt;p&gt;One last tip to say about tests. Write your tests to test the behaviour of your application.&lt;/p&gt;</description></item><item><title>Uploading Files to AWS</title><link>https://blog-dev.funkysi1701.com/posts/2017/uploading-files-to-aws/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 03 Jul 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/uploading-files-to-aws/</guid><category term="AWS">AWS</category><category term="C-Sharp">C-Sharp</category><description>&lt;p&gt;I am a fan of Azure but today I have been looking at AWS. Specifically how to upload and download files.&lt;/p&gt;
&lt;p&gt;AWS S3 stores files in Buckets. I already had an AWS S3 account setup with a Bucket. I am going to assume you have got a bucket setup and concentrate on the code to get files in and out.&lt;/p&gt;
&lt;p&gt;First step is to use nuget to install the AWS packages. In nuget the packages you want are called AWSSDK.Core and AWSSDK.S3.&lt;/p&gt;
&lt;p&gt;The using statements you want to use are called Amazon.S3 and Amazon.S3.Transfer, not sure why this doesn’t match nuget, this difference caught me out a couple of times.&lt;/p&gt;
&lt;p&gt;Now to the code that uploads files&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AmazonS3Client AWSclient = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; AmazonS3Client(accessKeyID, secretAccessKeyID, Amazon.RegionEndpoint.EUWest1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TransferUtility fileTransferUtility = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TransferUtility(AWSclient);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; (FileStream streamWriter = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileStream(path, FileMode.Open))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TransferUtilityUploadRequest fileTransferUtilityRequest = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TransferUtilityUploadRequest
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BucketName = &lt;span style="color:#e6db74"&gt;&amp;#34;flawlessimages&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InputStream = streamWriter,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Key = fileName
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fileTransferUtility.Upload(fileTransferUtilityRequest);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lets break it down and look at what it does.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AmazonS3Client AWSclient = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; AmazonS3Client(accessKeyID, secretAccessKeyID, Amazon.RegionEndpoint.EUWest1);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This creates an instance of AmazonS3Client, we are passing the Access Key and Secret Access Key both of which can be found from your Amazon S3 account My Security Credentials section. Amazon.RegionEndpoint.EUWest1 specifies the amazon data centres that your bucket is located in.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TransferUtility fileTransferUtility = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TransferUtility(AWSclient);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This creates an instance of TransfterUtility using the AmazonS3Client instance we created in the previous step.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; (FileStream streamWriter = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileStream(path, FileMode.Open))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This opens up a filestream from a files path and specifies that the file should be opened.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TransferUtilityUploadRequest fileTransferUtilityRequest = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TransferUtilityUploadRequest
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BucketName = &lt;span style="color:#e6db74"&gt;&amp;#34;flawlessimages&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InputStream = streamWriter,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Key = fileName
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fileTransferUtility.Upload(fileTransferUtilityRequest);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This last step specifies which bucket to upload to, what input stream to upload and the Key to use. Key is just AWS way of referring to files, more commonly referred to as the filename.&lt;/p&gt;
&lt;p&gt;This is all you need to do to upload a file to your Bucket. The file will be located at &lt;a href="https://s3-eu-west-1.amazonaws.com/[bucketname]/[filename]" target="_blank" rel="noopener noreferrer"&gt;https://s3-eu-west-1.amazonaws.com/[bucketname]/[filename]&lt;/a&gt;
, however by default it will not be downloadable until you set Read permission to everyone, once you do that anyone who has the link will be able to download your file.&lt;/p&gt;
&lt;p&gt;This is the same permission level as any file you have on your webserver, however AWS has a better way.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; (s3Client = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; AmazonS3Client(accessKeyID, secretAccessKeyID, Amazon.RegionEndpoint.USEast1))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GetPreSignedUrlRequest request1 = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; GetPreSignedUrlRequest
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BucketName = bucketName,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Key = filename,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Expires = DateTime.Now.AddMinutes(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; urlString = s3Client.GetPreSignedURL(request1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here we are generating a url to download the file, but we are specifying that it is only valid for 5 minutes. This means that if you share the url it will only work for 5 minutes, after that AWS will give an access denied message.&lt;/p&gt;
&lt;p&gt;This is much better security than you have on a typical web server, and easy to implement, every time a user clicks on a download link you generate a new presigned url and send the download to the browser, as long as this process doesn’t take longer than 5 minutes the user will never know.&lt;/p&gt;</description></item><item><title>Using Azure WebJobs to automate</title><link>https://blog-dev.funkysi1701.com/posts/2017/using-azure-webjobs-to-automate-stuff/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 26 Jun 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/using-azure-webjobs-to-automate-stuff/</guid><category term="Automate">Automate</category><category term="Azure">Azure</category><category term="Cron">Cron</category><description>&lt;p&gt;I keep hearing about Azure WebJobs but I have never used them. Time to change this.&lt;/p&gt;
&lt;p&gt;WebJobs are a feature of Azure App Service that can run a script at a specific time. In my case I would like to hit a specific url of my website at the same time every day.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="WebJobs" src="https://blog-dev.funkysi1701.com/images/2017/addkeepalivewebjob.png" loading="lazy"
width="313" height="615"
/&gt;
To the right you can see an example of the WebJobs form on the Azure portal that you need to fill in.&lt;/p&gt;
&lt;p&gt;You need to supply a name for your webjob.&lt;/p&gt;
&lt;p&gt;You need to upload the script that will run in my case I used a powershell script. My script consisted of which basically just loads the url specified.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$progressPreference = &lt;span style="color:#e6db74"&gt;&amp;#34;silentlyContinue&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$result = Invoke-WebRequest -Uri (&lt;span style="color:#e6db74"&gt;&amp;#34;https://www.google.com&amp;#34;&lt;/span&gt;) -Method Get -UseBasicParsing;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Type refers to if your job will be triggered or run continuously, I want it to be triggered.&lt;/p&gt;
&lt;p&gt;Triggers refers to if you want it to be scheduled or manual, something that you can run on an ad hoc basis. I of course want scheduled.&lt;/p&gt;
&lt;p&gt;If you are familiar with the linux CRON then the next box will make sense to you for everyone else I will try and make sense of it. The box consists of 6 numbers which can either have a value or a *. The numbers correspond to the following {second} {minute} {hour} {day} {month} {day of the week}.&lt;/p&gt;
&lt;p&gt;A hourly job would be expressed as 0 0 * * * *, ie every day of week, every month, every day, every hour and only when minute and second equals zero. For more help with this check out the &lt;a href="https://docs.microsoft.com/en-us/azure/app-service-web/web-sites-create-web-jobs#CreateScheduledCRON" target="_blank" rel="noopener noreferrer"&gt;MSDN docs&lt;/a&gt;
about it. I want to use 0 30 21 * * * to run daily at 9.30pm.&lt;/p&gt;
&lt;p&gt;That’s it everything setup, now time to wait and see if it works.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oh no!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It failed to run at the specified time.&lt;/p&gt;
&lt;p&gt;The reason for this is the scheduler requires the feature Always On to be turned on which is not available in the free App Service. Before you reach for your wallets, I found a solution on this &lt;a href="https://tomssl.com/2016/12/20/how-to-get-azure-webjobs-to-run-indefinitely-for-free/" target="_blank" rel="noopener noreferrer"&gt;blog post&lt;/a&gt;
that allows them to run on the free tier.&lt;/p&gt;
&lt;p&gt;The thinking behind this solution is you need to keep the website alive throughout the day so Tom has created a script that does this. His script can be found on his blog or on his &lt;a href="https://github.com/TomChantler/Self-KeepAlive" target="_blank" rel="noopener noreferrer"&gt;github page&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Set this script up to run every 5 minutes (0 */5 * * * *) like the example above.&lt;/p&gt;
&lt;p&gt;The nextthing you need to do is create a Custom connection string in the Application Settings blade called SecretThing. Tom’s script references this to access the website and keep it alive. The password you need to put in SecretThing can be found in you publish profile (downloaded from the Overview blade in the Azure portal). For more details and a better explanation check out &lt;a href="https://tomssl.com/2016/12/20/how-to-get-azure-webjobs-to-run-indefinitely-for-free/" target="_blank" rel="noopener noreferrer"&gt;Tom’s blog&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;One last thing to mention about WebJobs is that you can see details about when they have run at https://[YourWebAppName].scm.azurewebsites.net/azurejobs/#/jobs and this can be a great place to help debug your scripts.&lt;/p&gt;</description></item><item><title>Fiddler and APIs</title><link>https://blog-dev.funkysi1701.com/posts/2017/fiddler-and-apis/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 19 Jun 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/fiddler-and-apis/</guid><category term=""/><category term=""/><description>&lt;p&gt;A while ago I blogged about &lt;a href="https://www.funkysi1701.com/posts/2017/automation-promotion/" target="_blank" rel="noopener noreferrer"&gt;promoting&lt;/a&gt;
my blog with Buffer. At the time I made use of the nuget package &lt;a href="https://www.nuget.org/packages/BufferAPI/" target="_blank" rel="noopener noreferrer"&gt;BufferAPI&lt;/a&gt;
but lets look at some improvements I can make.&lt;/p&gt;
&lt;p&gt;The BufferAPI package worked great from my console app, but when I tried to use it from a Controller in an MVC app I never got it to work. Lets look at the API docs and see if I can rewrite it.&lt;/p&gt;
&lt;p&gt;There are two main types of API calls GET which gets data from the server and POST which posts data to the server. These come from the types of HTTP requests.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Alt Text" src="https://blog-dev.funkysi1701.com/images/2017/6wozrfdoqvtjaoxs7j1v.jpg" loading="lazy"
width="638" height="359"
/&gt;
&lt;/p&gt;
&lt;p&gt;I quickly figured out how to use the GET API call to authenticate using &lt;a href="https://api.bufferapp.com/1/profiles.json?access_token=XXXX" target="_blank" rel="noopener noreferrer"&gt;https://api.bufferapp.com/1/profiles.json?access_token=XXXX&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;However POST was defeating me. That was until I remembered &lt;a href="https://www.telerik.com/fiddler" target="_blank" rel="noopener noreferrer"&gt;Fiddler&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;I had heard Troy Hunt (and others) talk of using Fiddler to examine what data is being passed among websites. Troy uses it to do a man in the middle test to see what information can be stolen.&lt;/p&gt;
&lt;p&gt;It is really easy to setup, install Fiddler, click yes to a few security warnings and you can see what information is being passed from your code to remote APIs.&lt;/p&gt;
&lt;p&gt;Once I had Fiddler installed I could compare what information is being passed between a successful API call using the BufferAPI nuget package and an unsuccessful API call using my code.&lt;/p&gt;
&lt;p&gt;Fiddler also showed that passing my authentication token in a POST request is much better. Despite both GET and POST being encrypted when using HTTPS, anything at either end that logs URLs will have a log of your username and password.&lt;/p&gt;
&lt;p&gt;If you have not tried Fiddler, give it a try especially if you are doing things with API calls.&lt;/p&gt;</description></item><item><title>Add Power BI data to a webpage</title><link>https://blog-dev.funkysi1701.com/posts/2017/how-do-i-add-power-bi-data-to-a-webpage/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 12 Jun 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/how-do-i-add-power-bi-data-to-a-webpage/</guid><category term="PowerBI">PowerBI</category><category term=""/><description>&lt;p&gt;Last week I talked about &lt;a href="https://www.funkysi1701.com/posts/2017/businessintelligence/" target="_blank" rel="noopener noreferrer"&gt;Power BI&lt;/a&gt;
, what it is and some of the different services you can use with it. This week lets add some of that data to a simple web page.&lt;/p&gt;
&lt;p&gt;For this example I am going to add the google analytics data from this website to this page.&lt;/p&gt;
&lt;p&gt;First login to your Power BI &lt;a href="https://app.powerbi.com/" target="_blank" rel="noopener noreferrer"&gt;https://app.powerbi.com/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Click the get data link at the bottom left.&lt;/p&gt;
&lt;p&gt;Click My Organisation to bring up the app search box.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Alt Text" src="https://blog-dev.funkysi1701.com/images/2017/46c1lyxy053xcq66fowf.jpg" loading="lazy"
width="768" height="406"
/&gt;
&lt;/p&gt;
&lt;p&gt;Click the Apps tab and search for “google” in the search box, you should then see Google Analytics, click into this and then click the get it now button.&lt;/p&gt;
&lt;p&gt;Log into your google account. If you have multiple google accounts I found it worked best to sign out of all of them or run this in an incognito window.&lt;/p&gt;
&lt;p&gt;Once you are signed in you should see a list of the different google analytics data you have, select the one you want to use and click import.&lt;/p&gt;
&lt;p&gt;Power BI will then go away and start loading the data.&lt;/p&gt;
&lt;p&gt;Once loaded go to Reports and select the Google Analytics that has been loaded. If you have more than one, it is a good idea to rename each one eg Corporate Site Google Analytics, Blog Google Analytics so you won’t get mixed up.&lt;/p&gt;
&lt;p&gt;In the file menu select Publish to web and agree that you are OK for this to be made public.&lt;/p&gt;
&lt;p&gt;You will then be given a piece of HTML code that starts with &amp;lt;iframe copy this onto your web page. Reload your webpage and you should see something similar to mine below.&lt;/p&gt;
&lt;p&gt;It should be noted that while you can but the webpage containing the iframe behind a login page, the data could still be accessed if you knew the url contained within the iframe, this is why the link can be emailed and continue to work.&lt;/p&gt;</description></item><item><title>What is Business Intelligence here?</title><link>https://blog-dev.funkysi1701.com/posts/2017/businessintelligence/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 05 Jun 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/businessintelligence/</guid><category term="ApplicationInsights">ApplicationInsights</category><category term="BusinessIntelligence">BusinessIntelligence</category><category term="SQL">SQL</category><description>&lt;p&gt;The term &lt;strong&gt;Business Intelligence (BI)&lt;/strong&gt; refers to technologies, applications and practices for the collection, integration, analysis, and presentation of business information. The purpose of Business Intelligence is to support better business decision making. Essentially, Business Intelligence systems are data-driven Decision Support Systems (DSS). Business Intelligence is sometimes used interchangeably with briefing books, report and query tools and executive information systems.&lt;/p&gt;
&lt;h2 id="what-is-power-bi"&gt;What is Power BI?&lt;a class="anchor ms-1" href="#what-is-power-bi" aria-label="Permalink: What is Power BI?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Power BI&lt;/strong&gt; is a business analytics service provided by Microsoft. It provides interactive visualisations with self-service business intelligence capabilities, where end users can create reports and dashboards by themselves, without having to depend on any information technology staff or database administrator.&lt;/p&gt;
&lt;p&gt;Microsoft describe it as follows: &lt;strong&gt;Power BI&lt;/strong&gt; is a suite of business analytics tools that deliver insights throughout your organisation. Connect to hundreds of data sources, simplify data prep, and drive ad hoc analysis. Produce beautiful reports, then publish them for your organisation to consume on the web and across mobile devices. Everyone can create personalised dashboards with a unique, 360-degree view of their business. And scale across the enterprise, with governance and security built-in.&lt;/p&gt;
&lt;h2 id="what-can-you-do-with-it"&gt;What can you do with it?&lt;a class="anchor ms-1" href="#what-can-you-do-with-it" aria-label="Permalink: What can you do with it?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the first thing you can do with Power Bi is connect some of the apps that you use.&lt;/p&gt;
&lt;p&gt;To sign up to use Power BI go to the &lt;a href="https://www.microsoft.com/en-us/power-platform/products/power-bi/" target="_blank" rel="noopener noreferrer"&gt;Power BI website&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Once you are signed in click the get data link in the bottom left corner and browse through the apps you can use.&lt;/p&gt;
&lt;p&gt;If your website uses google analytics you can connect it up to Power BI and see some cool analytics. The below map was generated from some google analytics data, you can see that this website has had users across the globe, with UK and USA getting a lot of hits.
&lt;img class="img-fluid" alt="Business Intelligence from Google Analytics" src="https://blog-dev.funkysi1701.com/images/2017/Capture.jpg" loading="lazy"
width="1189" height="627"
/&gt;
&lt;/p&gt;
&lt;p&gt;Another thing you can do is connect Azure Application Insights. This provides some similar data to google analytics about who is visiting your site.&lt;/p&gt;
&lt;p&gt;If your code is hosted in Visual Studio Team Services you can get some cool analytics from your commit history.
&lt;img class="img-fluid" alt="Business Intelligence from VSTS" src="https://blog-dev.funkysi1701.com/images/2017/Capture-1.jpg" loading="lazy"
width="1299" height="348"
/&gt;
&lt;/p&gt;
&lt;p&gt;There is a huge long list of apps you can connect to power BI so you can start getting all sorts of analysis very easily. I am hopefully going to talk another time about getting custom data into Power BI.&lt;/p&gt;</description></item><item><title>Have I Been Pwned?</title><link>https://blog-dev.funkysi1701.com/posts/2017/have-i-been-pwned/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 29 May 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/have-i-been-pwned/</guid><category term="Pwned">Pwned</category><category term="DataBreach">DataBreach</category><category term="Security">Security</category><category term="TroyHunt">TroyHunt</category><description>&lt;p&gt;Have you heard of the website &lt;a href="https://haveibeenpwned.com" target="_blank" rel="noopener noreferrer"&gt;https://haveibeenpwned.com&lt;/a&gt;
?&lt;/p&gt;
&lt;p&gt;Well you should have. Have I Been Pwned is a website created by security expert Troy Hunt that keeps track of data breaches and allows you to search and find ones that affect you. As I write this &lt;a href="https://www.troyhunt.com/" target="_blank" rel="noopener noreferrer"&gt;Troy Hunt&lt;/a&gt;
has tracked 3,752,984,562 pwned accounts from 216 pwned websites.&lt;/p&gt;
&lt;h2 id="what-does-pwned-mean"&gt;What does “pwned” mean?&lt;a class="anchor ms-1" href="#what-does-pwned-mean" aria-label="Permalink: What does “pwned” mean?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;pwn means to compromise or control, specifically another computer (server or PC), website, gateway device, or application. (as defined on wikipedia)&lt;/p&gt;
&lt;p&gt;Originally, pwn and its variants were pronounced /ˈoʊn/ in the same way as the verb own, the tail of the p being “silent”.&lt;/p&gt;
&lt;p&gt;In terms of this site Troy Hunt defines it as:&lt;/p&gt;
&lt;p&gt;&lt;quote&gt;A &amp;ldquo;breach&amp;rdquo; is an incident where a hacker illegally obtains data from a vulnerable system, usually by exploiting weaknesses in the software. All the data in the site comes from website breaches which have been made publicly available.&lt;/quote&gt;&lt;/p&gt;
&lt;h2 id="what-can-i-do"&gt;What can I do?&lt;a class="anchor ms-1" href="#what-can-i-do" aria-label="Permalink: What can I do?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As an individual you can search for your email address in Have I Been Pwned, I am in 7 data breaches.&lt;/p&gt;
&lt;p&gt;As a person responsible for an email domain you can search and find which of your users are in a data breach.&lt;/p&gt;
&lt;p&gt;You can also sign up to get notified of any future data breaches you might get caught up in.&lt;/p&gt;
&lt;p&gt;If you are in a data breach change your password. If you use the same password across multiple sites or services change them as well. Consider using a &lt;a href="https://www.troyhunt.com/only-secure-password-is-one-you-cant/" target="_blank" rel="noopener noreferrer"&gt;password manager&lt;/a&gt;
so you can have unique complex passwords for every services you use and not have to worry about forgetting them.&lt;/p&gt;
&lt;p&gt;If you look after a website or service then follow Troy Hunt. Think about security, is your site vulnerable to SQL injection, do you store passwords with reversible encryption?&lt;/p&gt;
&lt;h2 id="how-worried-should-i-be"&gt;How worried should I be?&lt;a class="anchor ms-1" href="#how-worried-should-i-be" aria-label="Permalink: How worried should I be?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Data breaches are happening more and more often. Its not showing any sign of slowing down, in fact I expect there to be lots more in the years to come. However there are things you can do to mitigate the damage of being in a breach.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use a password manager&lt;/li&gt;
&lt;li&gt;Don’t share passwords between sites&lt;/li&gt;
&lt;li&gt;Regularly change your passwords&lt;/li&gt;
&lt;li&gt;Think of passwords as pass phrases and include spaces between the different words&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consider what information a company has about you. How worried would you be if this became public knowledge? Consider if you want this online, weigh up the benefits etc&lt;/p&gt;</description></item><item><title>Star Trek Discovery trailer thoughts</title><link>https://blog-dev.funkysi1701.com/posts/2017/star-trek-discovery/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 22 May 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/star-trek-discovery/</guid><category term="StarTrek">StarTrek</category><category term="Discovery">Discovery</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/2017/DAD0hTKUAAAUkTP.jpg"/><description>&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/UoV3kc05Nwc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;I am really excited a new Star Trek Discovery trailer has just been released, if you haven’t seen it yet, watch it now.&lt;/p&gt;
&lt;p&gt;The rumour mill has been going crazy about Star Trek Discovery but now we have a trailer with actual footage to analyse. In my opinion all the concerns about changes in the production team have gone out the window, this looks to be a polished Star Trek show that can sit alongside our favourites.&lt;/p&gt;
&lt;h2 id="the-ship"&gt;The Ship&lt;a class="anchor ms-1" href="#the-ship" aria-label="Permalink: The Ship"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When images first surfaced of the ship I wasn’t keen, however all the shots of the ship look great. I assume this must be the USS Discovery, although it is hard to tell anything from a two minute advert.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="USS Discovery from the Star Trek Discovery trailer" src="https://blog-dev.funkysi1701.com/images/2017/DAD0hTKUAAAUkTP.jpg" loading="lazy"
width="1199" height="663"
/&gt;
&lt;/p&gt;
&lt;h2 id="the-bridge"&gt;The Bridge&lt;a class="anchor ms-1" href="#the-bridge" aria-label="Permalink: The Bridge"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Bridge looks recognisable as a Star Trek bridge, but also looks fresh and new. I think it feels very JJ Verse. I like it.&lt;/p&gt;
&lt;h2 id="the-uniforms"&gt;The Uniforms&lt;a class="anchor ms-1" href="#the-uniforms" aria-label="Permalink: The Uniforms"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The uniforms look like a mid step between what we saw on Enterprise and what we know as the Classic Trek look. I can’t see any Blue, Red, Gold to signify departments, but it looked like Gold and Silver could well signify something. Really hard to tell at this stage, but I like what I can see.&lt;/p&gt;
&lt;h2 id="characters"&gt;Characters&lt;a class="anchor ms-1" href="#characters" aria-label="Permalink: Characters"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The show feels like it is going to be gritty and real. With characters you can really get behind. I liked what I saw of the captain and lead character. The alien character intrigued me, hopefully his line about death will be explored. It feels like there is a strong link between Vulcans and Sarek with the shows lead (played by Sonequa Martin-Green) Not sure how I feel about this yet, depends on what they do with it. I don’t want them to just redo what they have done with Spock, but again lets wait and see.&lt;/p&gt;
&lt;h2 id="klingons"&gt;Klingons&lt;a class="anchor ms-1" href="#klingons" aria-label="Permalink: Klingons"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;OK I am not sure I like the strong emphasis on the Klingons. I think we have spent a lot of time learning about Klingons, so when I heard the casting news about Klingons I was not excited. The Klingons also have a new look, which doesn’t bother me that much as the Klingons have changed their look before. But lets wait and see what happens.&lt;/p&gt;
&lt;h2 id="star-trek-is-back"&gt;Star Trek is back&lt;a class="anchor ms-1" href="#star-trek-is-back" aria-label="Permalink: Star Trek is back"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After over a decade with no Star Trek on TV, it is finally coming back. I am beyond excited about this. There are lots of things I want from this new show but this advert has definitely rekindled my excitement and hope that we are going to get something good.&lt;/p&gt;</description></item><item><title>Windows Update – don’t turn it off!</title><link>https://blog-dev.funkysi1701.com/posts/2017/windows-update-dont-turn-off/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 15 May 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/windows-update-dont-turn-off/</guid><category term="Windows">Windows</category><category term="Update">Update</category><category term="ITAdmin">ITAdmin</category><description>&lt;p&gt;No blog post this week. However why not check out Troy Hunts blog article about &lt;a href="https://www.troyhunt.com/dont-tell-people-to-turn-off-windows-update-just-dont/" target="_blank" rel="noopener noreferrer"&gt;Windows Update&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Windows Update settings screen showing active updates" src="https://blog-dev.funkysi1701.com/images/2017/ximage7.png.pagespeed.gpjpjwpjwsjsrjrprwricpmd.ic_.OmA4sQpZUA.png" loading="lazy"
width="464" height="288"
/&gt;
&lt;/p&gt;
&lt;p&gt;I am probably fairly unique in that I like installing updates whether it be on my phone, my PC or for one of my favourite programs. One of my tasks when I used to work in a sysadmin role was ensuring all windows updates got installed on all servers and client machines. It was a never ending task, as soon as you got almost all updates done, it would be update Tuesday and a new set of updates would be released.&lt;/p&gt;
&lt;p&gt;I can think of a couple of times an update got installed that caused a problem and needed to be rolled back. However I have no way of measuring how often it fixed a problem or improved the security of the OS or other software. If you compare the annoyance of waiting for updates to install against having a computer (or worse a server) be hacked or otherwise compromised I think it is fairly clear what you need to do.&lt;/p&gt;
&lt;p&gt;As someone who works in IT I feel it is my duty to share the importance of keeping your devices updated. Don’t turn automatic updates off or disable it. It is there to help you and keep your computer safe and secure.&lt;/p&gt;</description></item><item><title>HighCharts</title><link>https://blog-dev.funkysi1701.com/posts/2017/highcharts/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 08 May 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/highcharts/</guid><category term="HighCharts">HighCharts</category><category term="Graphs">Graphs</category><category term="JavaScript">JavaScript</category><category term="SQL">SQL</category><description>&lt;p&gt;High Charts is a javascript library that allows graphs and charts to easily be added to web pages.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Highcharts line chart showing solar employment growth by sector" src="https://blog-dev.funkysi1701.com/images/2017/chart.jpeg" loading="lazy"
width="1200" height="800"
/&gt;
&lt;/p&gt;
&lt;p&gt;A chart like this can easily be added with a few lines of html and javascript.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://code.highcharts.com/highcharts.js&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://code.highcharts.com/modules/exporting.js&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;container&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This adds the highcharts library and a container for the chart to be displayed in.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Highcharts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;chart&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;container&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Solar Employment Growth by Sector, 2010-2016&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;subtitle&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Source: thesolarfoundation.com&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;yAxis&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Number of Employees&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;legend&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;layout&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;vertical&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;align&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;right&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;verticalAlign&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;middle&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;plotOptions&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;series&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;pointStart&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2010&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;series&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Installation&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;43934&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;52503&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;57177&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;69658&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;97031&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;119931&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;137133&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;154175&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Manufacturing&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;24916&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;24064&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;29742&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;29851&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32490&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;30282&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;38121&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;40434&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Sales &amp;amp; Distribution&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;11744&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;17722&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;16005&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;19771&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20185&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;24377&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32147&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;39387&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Project Development&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;7988&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;12169&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;15112&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;22452&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;34400&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;34227&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Other&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;12908&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;5948&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;8105&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;11248&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;8989&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;11816&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;18274&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;18111&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This adds the data and sets up various options for the charts. More details about the different charts and options you can set can be found at &lt;a href="https://www.highcharts.com" target="_blank" rel="noopener noreferrer"&gt;https://www.highcharts.com&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I am quite a fan of the different gauges that you can put on your site, as you can add a bit of animation and make the needles bounce around. &lt;a href="https://www.highcharts.com/demo/gauge-solid" target="_blank" rel="noopener noreferrer"&gt;https://www.highcharts.com/demo/gauge-solid&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Highcharts solid gauge chart example" src="https://blog-dev.funkysi1701.com/images/2017/chart-1.jpeg" loading="lazy"
width="1200" height="400"
/&gt;
&lt;/p&gt;
&lt;p&gt;As most of the data I deal with lives in a SQL Server database, I have been spending quite a bit of time writing Stored Procedures and functions to mould the data so I can easily pass data from the database to javascript.&lt;/p&gt;
&lt;p&gt;Highcharts are very flexible with lots of different options that allow you to display charts of almost any data you have, these charts are also exportable as PNG, JPEG, CSVs etc&lt;/p&gt;</description></item><item><title>Office Move</title><link>https://blog-dev.funkysi1701.com/posts/2017/office-move/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 01 May 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/office-move/</guid><category term="ITAdmin">ITAdmin</category><category term="Routers">Routers</category><category term="Servers">Servers</category><category term="OfficeMove">OfficeMove</category><description>&lt;p&gt;
&lt;img class="img-fluid" alt="New Rack" src="https://blog-dev.funkysi1701.com/images/2017/20170422_191127-e1493403982560-169x300.jpg" loading="lazy"
width="169" height="300"
/&gt;
For the past few weeks my software developing has been taking a back seat as I planned and coordinated the IT requirements of an office move.&lt;/p&gt;
&lt;p&gt;The company I work for has been working out of a converted barn, but as the company has grown we have outgrown the building and for quite a while it has been a real squeeze to get everyone in. We now have a shiny new offices with plenty of room for growth.&lt;/p&gt;
&lt;p&gt;It was at the start of the year when I first started getting involved with the new office. At that time building work was about to begin. The office had concrete floors so in order to get network and power points in the floor, channels would have to be cut into the concrete for the floor boxes and cable runs.&lt;/p&gt;
&lt;p&gt;At the old office our servers were in a cabinet in the corner of the room which meant they could be quite loud especially when the fans were going full pelt. Our American owners were supplying brand new IT equipment and we would have a dedicated server room.&lt;/p&gt;
&lt;p&gt;Soon a weekly conference call was setup so we could coordinate with the IT people in America and the various different contractors that would help deliver our new office.&lt;/p&gt;
&lt;p&gt;One thing I was particularly proud of was YDS. York Data Services (YDS) is an ISP I have worked with in the past at a previous job and I was able to continue my relationship with them and they were contacted and became our primary internet supplier.&lt;/p&gt;
&lt;p&gt;Unfortunately most ISPs have to deal with BTOpenreach who have a bit of a monopoly on getting phone lines or leased lines installed. The initial estimate we were given was two weeks after we were due to move in. It was looking like we would move in and two weeks later we would get an internet connection. We were in the process of getting quotes for a temporary internet connection when BT contacted us and could get us connected up.
&lt;img class="img-fluid" alt="New Office" src="https://blog-dev.funkysi1701.com/images/2017/18121045_1302238519862436_8711390769620542649_o.jpg" loading="lazy"
width="2048" height="1536"
/&gt;
&lt;/p&gt;
&lt;p&gt;Soon afterwards a huge cabinet and two pallets full of equipment was delivered. Two days later a team was dispatched to rack everything up. On the rack we had the following equipment: 4 x UPS, 4 x Network Switches, 2 x Routers (for 2 x Leased Lines from different providers, the secondary connection has not been installed yet), 2 x Palo Alto Firewall devices, 2 x New Servers.&lt;/p&gt;
&lt;p&gt;Just prior to our move we had a rack full of equipment but no patch cables, nothing connected up and I was beginning to get concerned that we would not be ready in time.&lt;/p&gt;
&lt;p&gt;Thankfully a team was dispatched to help out over the weekend of the move, with the patch cables being delivered only hours beforehand. I worked closely with them and we worked late into the night. By the end of the Friday night our domain controller had been moved and its IP address updated. DHCP scopes had been setup for the new network. Once that was done we could get the WiFi points connected up (These had already been fitted to the ceiling).&lt;/p&gt;
&lt;p&gt;The following day we moved our existing servers and updated their IP addresses and got everything patched up. Furniture started arriving so desks could start being setup and phones connected up. Everything was slotting into place, and for the first time our new office was starting to look like an office.&lt;/p&gt;
&lt;p&gt;By the time it got to Monday the only problem was the phone number had not transferred as requested (something else to blame on BT) All staff could either connect via an Ethernet cable or connect to our brand new WiFi network and had access to all the IT services they had at the old office. Another minor issue was the NAS we used for backups had to be reset as it couldn’t communicate with the domain so no one could login, luckily this didn’t affect the data on it.&lt;/p&gt;
&lt;p&gt;From my perspective the move was a massive success considering how complex and how many different people had been involved.&lt;/p&gt;</description></item><item><title>GitHub history</title><link>https://blog-dev.funkysi1701.com/posts/2017/github-history/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 24 Apr 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/github-history/</guid><category term="Git">Git</category><category term="GitHub">GitHub</category><category term="Code">Code</category><description>&lt;p&gt;I created my GitHub account in August 2010, lets look at what I have done with it.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="GitHub contribution graph for 2010" src="https://blog-dev.funkysi1701.com/images/2017/git10.jpg" loading="lazy"
width="1471" height="331"
/&gt;
&lt;/p&gt;
&lt;p&gt;In 2010 I started by committing the code for an old php website I had created. Then in December I committed some other php sites.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="GitHub contribution graph showing daily commits between late 2010 and 2011" src="https://blog-dev.funkysi1701.com/images/2017/git11.jpg" loading="lazy"
width="1484" height="331"
/&gt;
&lt;/p&gt;
&lt;p&gt;Between 12 December 2010 and 29 September 2011 I must have created some automated process which is why there is a commit every day. Looking at the diff it appears to be related to tracking visitors to a site. I assume back then I hadn’t heard of the .gitignore file!&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="GitHub contribution graph for 2014" src="https://blog-dev.funkysi1701.com/images/2017/git14.jpg" loading="lazy"
width="1479" height="336"
/&gt;
&lt;/p&gt;
&lt;p&gt;Nothing for a few years until 2014, when I started compiling a code samples collection, this is bits of code that I want to show off, I have added to this since 2015 so I really should go back to this as my skills have developed a bit since then.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="GitHub contribution graph for 2015" src="https://blog-dev.funkysi1701.com/images/2017/git15.jpg" loading="lazy"
width="1471" height="331"
/&gt;
&lt;/p&gt;
&lt;p&gt;In 2015 I really started to think of myself as a developer, I added repositories for Raspberry Pi, and a few C# ideas I had. I ended the year taking part in Advent of Code&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="GitHub contribution graph for 2016" src="https://blog-dev.funkysi1701.com/images/2017/git16.jpg" loading="lazy"
width="1470" height="332"
/&gt;
&lt;/p&gt;
&lt;p&gt;What did I do last year? Well I started going to York Code Dojo and this meant lots of forks from their code examples and also my first pull request. I also did a fair bit of looking at other repositories trying to find a good open source project to contribute to, still not found one for me yet. Lastly I ended 2016 with a bit of Advent of Code.&lt;/p&gt;
&lt;p&gt;Not sure how enthralling a blog post this is, but fascinating to see the different commit histories.&lt;/p&gt;</description></item><item><title>Automating promotion of my blog</title><link>https://blog-dev.funkysi1701.com/posts/2017/automation-promotion/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 17 Apr 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/automation-promotion/</guid><category term="Buffer">Buffer</category><category term="Blogging">Blogging</category><category term="XML">XML</category><category term="RSS">RSS</category><description>&lt;p&gt;I would like to automate the promotion of this blog. Currently to promote this blog on social media I use a few different services.
&lt;img class="img-fluid" alt="Buffer social media scheduling hub illustration" src="https://blog-dev.funkysi1701.com/images/2017/img-buffer-illustration-hub-960@2x.png" loading="lazy"
width="1780" height="794"
/&gt;
&lt;/p&gt;
&lt;p&gt;Buffer (&lt;a href="https://buffer.com" target="_blank" rel="noopener noreferrer"&gt;buffer.com&lt;/a&gt;
) is a service that allows you to schedule updates to the main social media channels (Facebook, Twitter, LinkedIn and Google+)&lt;/p&gt;
&lt;p&gt;IFTTT or If This Then That (&lt;a href="https://ifttt.com" target="_blank" rel="noopener noreferrer"&gt;ifttt.com&lt;/a&gt;
) is a service that allows you to connect different online services. You can send an email when a specific event occurs in your calendar for example.&lt;/p&gt;
&lt;p&gt;I have been using a combination of these services to share to social media some of my past blog posts. I then add to my calendar details of my blog posts. Then I use IFTTT to add the event to Buffer, and then buffer tweets on a schedule.&lt;/p&gt;
&lt;p&gt;This works great however it is a manual process to add my posts to my calendar. I have been using a spreadsheet to help me generate an ics calendar file which I import into my google calendar. There must be a better way of doing this.&lt;/p&gt;
&lt;p&gt;I have written some code that reads the RSS feed of my blog and then shares that to Buffer using the Buffer API. The code I am creating is far from finished however I am trying to use the concepts of clean code to make it as flexible as possible.&lt;/p&gt;
&lt;p&gt;I have an interface called ISocial which my buffer code implements, but it would be easy to add a class that implements the same interface but uses the twitter or facebook APIs. My code reads from a specific WordPress RSS feed, but it should be easy enough to adapt to read from a SQL database or any other data source.&lt;/p&gt;
&lt;p&gt;I am currently unsure what kind of interface to use for this application. I could create a web page that controls the functionality, or maybe just a windows application, or maybe both of these are complicating things and all I need is just a console application that could be added as a scheduled task.&lt;/p&gt;</description></item><item><title>Blame</title><link>https://blog-dev.funkysi1701.com/posts/2017/blame/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 10 Apr 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/blame/</guid><category term="Blame">Blame</category><category term="Culture">Culture</category><category term="DevOps">DevOps</category><category term="SoftSkills">SoftSkills</category><description>&lt;p&gt;I recently came home from a busy day of work to my wife blaming me for allowing our 18 month old son to reach some paint and get it all over the carpet. She was concentrating on the fact that he could reach the paint not on the fact that she had brilliantly got the paint out of the carpet.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Cartoon illustrating blame shifting between people" src="https://blog-dev.funkysi1701.com/images/2017/blame-shifting.jpg" loading="lazy"
width="347" height="346"
/&gt;
&lt;/p&gt;
&lt;p&gt;My instinct on being blamed is to deny it, or start throwing blame back at her. It is possible I put the paint in his reach, it is also possible it was someone else.&lt;/p&gt;
&lt;p&gt;It is very easy to blame someone else. For example, looking through the git history to find out who changed a specific file is only a few clicks.&lt;/p&gt;
&lt;p&gt;But is it ever productive to blame someone? Is it not better to focus our energy on fixing the issue at hand?&lt;/p&gt;
&lt;p&gt;In the world of business it is easy to go from blaming other people until you have a blame culture. When you have a blame culture everyone starts looking out for themselves so it’s not them that gets the blame and productivity will suffer.&lt;/p&gt;
&lt;p&gt;I think it is more important to put in place​ processes to minimise issues happening again. If a deployment causes downtime, don’t ask who’s fault is it and sack them. Instead what can we do to reduce the chance of it happening again?&lt;/p&gt;
&lt;p&gt;As someone who has an interest in DevOps, I often break things and don’t want to get blamed for that, I do want to improve my processes so I am not always breaking the same things.&lt;/p&gt;
&lt;p&gt;What do you think about Blame? Is what can we do differently always better than who did this?&lt;/p&gt;</description></item><item><title>Interfaces</title><link>https://blog-dev.funkysi1701.com/posts/2017/interfaces/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 27 Mar 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/interfaces/</guid><category term="C-Sharp">C-Sharp</category><category term="Interface">Interface</category><description>&lt;p&gt;I am trying to understand interfaces and when to use them in my code.&lt;/p&gt;
&lt;p&gt;An interface defines a contract and any class that implements that interface agrees to fulfil that contract.&lt;/p&gt;
&lt;p&gt;Lets look at an example as this tends to be how I learn best.&lt;/p&gt;
&lt;p&gt;Most applications require some sort of data to work from so lets start by defining IData which can load data.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;IData&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Blog LoadData(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; Connectionstring);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My interface defines one method LoadData and outputs an object called Blog (I will explain why in a minute)&lt;/p&gt;
&lt;p&gt;A common data source is a SQL database so we could define a SQL class that implements IData.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;SQL&lt;/span&gt; : IData
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Blog LoadData(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; Connectionstring)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Blog blog = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Blog();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; (SqlConnection con = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; SqlConnection(Connectionstring))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; con.Open();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//etc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We could also get data from an RSS feed of a blog (hence why I called the object Blog earlier)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XML&lt;/span&gt; : IData
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Blog LoadData(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; Connectionstring)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; XmlDocument myXmlDocument = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; XmlDocument();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; myXmlDocument.Load(Connectionstring);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Blog blog = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Blog();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;foreach&lt;/span&gt; (XmlNode RootNode &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; myXmlDocument.ChildNodes)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//etc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Both classes implement IData and have a method called LoadData which has a string parameter and outputs a blog object. The string parameter is either a connection string to a SQL database or the URL of the rss feed. Not sure if there is a better way of doing this bit, maybe the name of the string needs making more generic.&lt;/p&gt;
&lt;p&gt;Now we have some classes that implement an interface what can we do with them. Lets write a class called GetData which gets data but doesn’t care if it comes form the rss feed or a SQL database.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GetData&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; IData _repo;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; GetData(IData repo)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _repo = repo;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Blog LoadData(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; Connectionstring)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; original = _repo.LoadData(Connectionstring);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; original;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we call GetData we can either pass in XML or SQL as the class is not tied to either implementation. We could even write other classes that implement IData for testing purposes.&lt;/p&gt;
&lt;p&gt;My full code can be found on &lt;a href="https://github.com/funkysi1701/InterfaceExample" target="_blank" rel="noopener noreferrer"&gt;github&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;The advantages of writing code in this way include code that is easier to extend, easier to test and easier to maintain. This is only the start of my understanding and I am sure this is going to be a topic I come back to in the next few weeks.&lt;/p&gt;</description></item><item><title>SOLID and other programming terms</title><link>https://blog-dev.funkysi1701.com/posts/2017/solid-programming-terms/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 20 Mar 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/solid-programming-terms/</guid><category term="DesignPatterns">DesignPatterns</category><category term="DRY">DRY</category><category term="MVC">MVC</category><category term="SOLID">SOLID</category><description>&lt;p&gt;This week I have been looking at improving my understanding of a few programming terms, like SOLID and I will try and define them so I can look back here when I get confused.&lt;/p&gt;
&lt;h2 id="mvc"&gt;MVC&lt;a class="anchor ms-1" href="#mvc" aria-label="Permalink: MVC"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have previously blogged about &lt;a href="https://www.funkysi1701.com/posts/2016/model-view-controller-mvc/" target="_blank" rel="noopener noreferrer"&gt;MVC&lt;/a&gt;
, but my understanding was not 100% correct so I will refine this here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Model&lt;/strong&gt; – Now this is where my understanding was not quite correct. I thought the model was the actual source data, eg an XML file, SQL database etc. The model is the business logic so this is a processed version of the source data. MVC does not care where data is stored it can be flat files, SQL, XML or anything really.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;View&lt;/strong&gt; – This displays data to the user and typically is the HTML/CSS markup. Only display related logic would get included in the view.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Controller&lt;/strong&gt; – This is another place I had got a bit confused. I had thought all the logic lived here. This is incorrect controllers are only concerned with getting data between Model and View.&lt;/p&gt;
&lt;h2 id="solid"&gt;SOLID&lt;a class="anchor ms-1" href="#solid" aria-label="Permalink: SOLID"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SOLID are five principles of object oriented programming and design.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;S&lt;/strong&gt; is for Single Responsibility Principle. A class or piece of code should be responsible for doing one thing.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Diagram illustrating the Single Responsibility Principle" src="https://blog-dev.funkysi1701.com/images/2017/SingleResponsibilityPrinciple2_71060858.jpg" loading="lazy"
width="750" height="600"
/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;O&lt;/strong&gt; is for Open/Closed Principle. Code should be open for extensions but closed for modifications. Often this refers to the way you can implement an interface and add extra functionality.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Diagram illustrating the Open/Closed Principle" src="https://blog-dev.funkysi1701.com/images/2017/ocp.jpg" loading="lazy"
width="640" height="513"
/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;L&lt;/strong&gt; is for Liskov Substitution Principle. Objects in a program can be replaced with subtypes of that object with out changing functionality.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Diagram illustrating the Liskov Substitution Principle" src="https://blog-dev.funkysi1701.com/images/2017/LiskovSubtitutionPrinciple_52BB5162.jpg" loading="lazy"
width="750" height="600"
/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I&lt;/strong&gt; is for Interface Segregation Principle. Large interfaces should be split down into small interfaces so that clients only know about methods that are of interest.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Diagram illustrating the Interface Segregation Principle" src="https://blog-dev.funkysi1701.com/images/2017/isp.jpg" loading="lazy"
width="640" height="513"
/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;D&lt;/strong&gt; is for Dependency Inversion Principle. High and Low level modules should depend on abstractions.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Diagram illustrating the Dependency Inversion Principle" src="https://blog-dev.funkysi1701.com/images/2017/dip.jpg" loading="lazy"
width="640" height="513"
/&gt;
&lt;/p&gt;
&lt;p&gt;I need to look into SOLID some more but here are some &lt;a href="https://www.codeproject.com/Articles/703634/SOLID-architecture-principles-using-simple-Csharp" target="_blank" rel="noopener noreferrer"&gt;examples&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="dry"&gt;DRY&lt;a class="anchor ms-1" href="#dry" aria-label="Permalink: DRY"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;DRY is simply Don’t Repeat Yourself. It is often easy to spot when a function call will help you not have to use the same bit of code in different places. I am often spotting places where I can put this into action.&lt;/p&gt;</description></item><item><title>Test Driven Development or TDD</title><link>https://blog-dev.funkysi1701.com/posts/2017/test-driven-development-tdd/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 13 Mar 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/test-driven-development-tdd/</guid><category term="TestDrivenDevelopment">TestDrivenDevelopment</category><category term="Testing">Testing</category><category term="VisualStudio">VisualStudio</category><media:content medium="image" type="image/gif" url="https://blog-dev.funkysi1701.com/images/2017/03/tdd_flow.gif"/><description>&lt;p&gt;A few weeks back I attended a talk at &lt;a href="https://www.agileyorkshire.org/event-announcements/tuesfebruary21st-drolivershawtestdrivendevelopmentthemostmisusedterminsoftwaredevelopmentandkeithwilliamsdependenciesinjectionandabstractionforfunandprofit" target="_blank" rel="noopener noreferrer"&gt;Agile Yorkshire&lt;/a&gt;
about Test Driven Development or TDD by Dr Oliver Shaw. I was impressed at how easy Oliver made it look, so as I have never tried it I thought I should give it a try.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Red, Green, Refactor cycle diagram for test driven development" src="https://blog-dev.funkysi1701.com/images/2017/tdd_flow.gif" loading="lazy"
width="489" height="511"
/&gt;
&lt;/p&gt;
&lt;p&gt;Test Driven Development or TDD is a way of development which starts with writing a Unit Test. First you write a failing test, then you write the code to make it pass, then you refactor your code. This can be remembered by thinking of &lt;strong&gt;Red, Green, Refactor&lt;/strong&gt;. Red being the failing test, Green being getting the test to pass, and Refactor being the refactoring.&lt;/p&gt;
&lt;p&gt;During the demonstration Oliver used a language called scala and a system that automatically reran all the tests after every change. I code with Visual Studio in C# is there a way I can get my tests to run automatically as well?&lt;/p&gt;
&lt;p&gt;A bit of googling and configuring I can answer this as Yes.&lt;/p&gt;
&lt;p&gt;The nuget package called &lt;a href="https://github.com/codereflection/Giles" target="_blank" rel="noopener noreferrer"&gt;Giles&lt;/a&gt;
is a watcher which will rerun your tests similar to how Oliver did it with his scalar environment. Fans of Buffy the Vampire Slayer will get the joke of why a watcher is called Giles. I couldn’t get this to work with MSTest but works fine with NUnit. There is a powershell script giles.ps1 which you need to run and will update every so often with how many tests have passed or failed. However you may not see this if you are coding in Visual Studio but there is a way to get a notification.&lt;/p&gt;
&lt;p&gt;If you install the application Growl you can get notifications from Giles which pop up and then disappear. So whatever you have on screen you can find out almost instantly if you have broken tests.&lt;/p&gt;
&lt;p&gt;Another thing that I wanted to configure is a way of viewing code coverage and which methods are tested and which aren’t. If you are familiar with VSTS after a build it gives you a percentage score for test coverage. I don’t find this overly useful as it doesn’t tell you what is covered and what isn’t. Also what if you want to use Github, how do you calculate the code coverage then?&lt;/p&gt;
&lt;p&gt;The nuget packages &lt;a href="https://www.nuget.org/packages/OpenCover/" target="_blank" rel="noopener noreferrer"&gt;OpenCover&lt;/a&gt;
and &lt;a href="https://www.nuget.org/packages/ReportGenerator/" target="_blank" rel="noopener noreferrer"&gt;ReportGenerator&lt;/a&gt;
allow a html report of code coverage to be produced. I created a batch script that can be run whenever you require this information.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[path]\OpenCover.Console.exe -target:&amp;#34;[path]\nunit3-console.exe&amp;#34; -targetargs:&amp;#34;[path]\Test.dll&amp;#34; -output:&amp;#34;[path]\coverage.xml&amp;#34; -register:user
[path]\ReportGenerator.exe &amp;#34;-reports:[path]\coverage.xml&amp;#34; &amp;#34;-targetdir:[path]&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The commands are fairly straightforward, the only tricky bit is sorting out all the filepaths to the different programs.&lt;/p&gt;
&lt;p&gt;Now that I have all this plumbing setup time to give TDD a try and see what I can build.&lt;/p&gt;</description></item><item><title>GitHub, Bitbucket, or VSTS compared</title><link>https://blog-dev.funkysi1701.com/posts/2017/github-vs-bitbucket-vs-vsts/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 06 Mar 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/github-vs-bitbucket-vs-vsts/</guid><category term="Git">Git</category><category term="Bitbucket">Bitbucket</category><category term="DevOps">DevOps</category><category term="AzureDevOps">AzureDevOps</category><category term="SourceControl">SourceControl</category><description>&lt;p&gt;As a developer using source control and git is bread and butter of what we do. Github is probably the most popular and widely known hosting service for source control but I have also used Bitbucket and Visual Studio Team Services. Lets have a look at each one and what they offer. Note while I have included prices I have only tried out the free versions.&lt;/p&gt;
&lt;h2 id="github"&gt;Github&lt;a class="anchor ms-1" href="#github" aria-label="Permalink: Github"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="GitHub Octocat mascot logo" src="https://blog-dev.funkysi1701.com/images/2017/github-octocat.png" loading="lazy"
width="1200" height="630"
/&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;URL: &lt;a href="https://github.com/" target="_blank" rel="noopener noreferrer"&gt;https://github.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Private Repositories: Not Available for free&lt;/li&gt;
&lt;li&gt;Public Repositories: Unlimited&lt;/li&gt;
&lt;li&gt;Team Size: Unlimited&lt;/li&gt;
&lt;li&gt;Prices: $7 per month for unlimited private repositories, $25 per month for 5 users then $9 per month per user&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is probably the most widely used service for hosting code. Over 13 million repositories of code. This is an ideal solution if you want your code to be publicly viewable, but take care not to publish passwords, private keys or your companies trade secrets. Every developer should have a Github account for displaying bits of code they are proud of.&lt;/p&gt;
&lt;p&gt;There are a number of externally built APIs that link into Github for doing extra features, like building, code coverage etc&lt;/p&gt;
&lt;h2 id="bitbucket"&gt;Bitbucket&lt;a class="anchor ms-1" href="#bitbucket" aria-label="Permalink: Bitbucket"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Bitbucket logo" src="https://blog-dev.funkysi1701.com/images/2017/d8TRzzL.png" loading="lazy"
width="277" height="277"
/&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;URL: &lt;a href="https://bitbucket.org/" target="_blank" rel="noopener noreferrer"&gt;https://bitbucket.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Private Repositories: Unlimited&lt;/li&gt;
&lt;li&gt;Public Repositories: Unlimited&lt;/li&gt;
&lt;li&gt;Team Size: Less than 5&lt;/li&gt;
&lt;li&gt;Prices: $10 per month for 10 Users, $100 per month for 100 Users, $200 per month for Unlimited Users&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At my last job we used Bitbucket extensively for all our projects. All the code was private so only the team could access it, however before I left we were approaching the 5 user limit (but looking at these prices cost seems very reasonable)&lt;/p&gt;
&lt;h2 id="visual-studio-team-services"&gt;Visual Studio Team Services&lt;a class="anchor ms-1" href="#visual-studio-team-services" aria-label="Permalink: Visual Studio Team Services"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Visual Studio Team Services logo" src="https://blog-dev.funkysi1701.com/images/2017/Visual-Studio-Team-Services.png" loading="lazy"
width="960" height="434"
/&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;URL: &lt;a href="https://azure.microsoft.com/services/devops/" target="_blank" rel="noopener noreferrer"&gt;https://azure.microsoft.com/services/devops/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Private Repositories: Unlimited&lt;/li&gt;
&lt;li&gt;Public Repositories: Not Available&lt;/li&gt;
&lt;li&gt;Team Size: Less than 5&lt;/li&gt;
&lt;li&gt;Prices: $30 per month for 10 users, and other features paid for via Azure Invoices&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Visual Studio Team Services or VSTS is Microsoft’s version control solution and I have only just started using it, however what I have seen I like. There are lots of options for building your code so VSTS is more than just hosting your code it is verging on a Continuous Integration/Delivery solution. Being a Microsoft product there are numerous links to Azure and it is easy to deploy stuff to that platform.&lt;/p&gt;
&lt;p&gt;All three have options for tracking issues but VSTS have options to add Stakeholder users which would allow none developers to add and keep track of issues and progress with them.&lt;/p&gt;
&lt;p&gt;If I want to run tests, look at code coverage VSTS is probably the solution I would go for, if I want something that is public I would go for Github. What do you think which of these is your favourite?&lt;/p&gt;</description></item><item><title>Learning R</title><link>https://blog-dev.funkysi1701.com/posts/2017/learning-r/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 27 Feb 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/learning-r/</guid><category term="ExchangeRates">ExchangeRates</category><category term="R">R</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/2017/Exchange-Rate-Calculator.jpg"/><description>&lt;p&gt;
&lt;img class="img-fluid" alt="R" src="https://blog-dev.funkysi1701.com/images/2017/Exchange-Rate-Calculator.jpg" loading="lazy"
width="1024" height="689"
/&gt;
Today I spent some time learning the R language.&lt;/p&gt;
&lt;p&gt;The problem I was trying to solve was to convert local prices of some items into Euros. I had been using a fixed exchange rate for all data, but as exchange rates fluctuate so much this is incorrect.&lt;/p&gt;
&lt;p&gt;My first though was to find a free API that I could query to get the values I wanted. The first API I found didn’t cover all the currencies, the next one I found I burnt through the free allowance in one pass.&lt;/p&gt;
&lt;p&gt;A colleague of mine mentioned using R to solve this, he sent me some links and I set out to write my first piece of R code.&lt;/p&gt;
&lt;p&gt;My finished code can be found on &lt;a href="https://github.com/funkysi1701/ExchangeRate/blob/master/script.R" target="_blank" rel="noopener noreferrer"&gt;github&lt;/a&gt;
and I will attempt to explain some of it.&lt;/p&gt;
&lt;p&gt;R defines functions fairly simply&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-r" data-lang="r"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nameoffunction &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(arg1, arg2)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; arg1 &lt;span style="color:#f92672"&gt;*&lt;/span&gt; arg2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I have created a function that takes 2 parameters date and currency. I know I have about 10 different currencies that I want to get currencies for and I want to loop through each day so I will need to pass in a date.&lt;/p&gt;
&lt;p&gt;The source of my exchange rate information is the &lt;a href="https://www.xe.com" target="_blank" rel="noopener noreferrer"&gt;www.xe.com&lt;/a&gt;
website, its historical exchange rate page passes currency and date into the query string so I should be able to build up a string containing all the different elements.&lt;/p&gt;
&lt;p&gt;All programming language can concatenate strings and R is no different. R uses paste()&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-r" data-lang="r"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;var &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;paste&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;World&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However R has an annoying feature in this function. I would expect that var in the above example would contain &amp;ldquo;HelloWorld&amp;rdquo;, it doesn’t it contains &amp;ldquo;Hello World&amp;rdquo;. Why it automatically adds a space I don’t know?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-r" data-lang="r"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;var &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;paste&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;World&amp;#34;&lt;/span&gt;, sep&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I am not entirely sure what all of the code does but I can take a good guess.&lt;/p&gt;
&lt;p&gt;read_html() I would guess loads a html page, html_nodes() finds all the html tags of a certain type on the page, in my case &amp;lt;table&amp;gt;, html_table() reads the first table it finds.&lt;/p&gt;
&lt;p&gt;table1[2] selects the second column, and head() selects a specific number of rows. I want the first row and second column so I combine these two as head(table1[2],1)&lt;/p&gt;
&lt;p&gt;Now that I have found my exchange rate what do I do with it? R can read and write to SQL Server so why not store this info in a SQL lookup table. I can then use this data in a stored procedure when I process my data.&lt;/p&gt;
&lt;p&gt;To query sql you can use sqlQuery(), it has two parameters, a sql connection and a TSQL command (eg a SELECT, INSERT, UPDATE statement)&lt;/p&gt;
&lt;p&gt;I use a while loop to loop through every day between 1st October 2016 and today and look up the exchange rate for each currency.&lt;/p&gt;
&lt;p&gt;For now I am manually running this R script, however there are ways to run R directly from SQL Server which I may well investigate. I could then have a SQL job to run this on a schedule, maybe once a day to get the latest exchange rates. I also would like to do something a bit cleverer like only getting exchange rates for the days that I need them by querying existing database tables.&lt;/p&gt;</description></item><item><title>Side Project – Connect 4</title><link>https://blog-dev.funkysi1701.com/posts/2017/side-project-connect-4/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 06 Feb 2017 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2017/side-project-connect-4/</guid><category term="Connect4">Connect4</category><category term="PWA">PWA</category><category term="Website">Website</category><description>&lt;p&gt;Hello?&lt;/p&gt;
&lt;p&gt;You have probably like me almost forgotten about this blog. Life has got in the way over the last few months, but lets see if I can restart my blogging habit.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Connect 4 board game" src="https://blog-dev.funkysi1701.com/images/2017/Connect4.png" loading="lazy"
width="639" height="553"
/&gt;
&lt;/p&gt;
&lt;p&gt;In 2017 I want to start a side project for a few reasons. I want to improve my coding skills and look at things I wouldn’t normally during my day job.&lt;/p&gt;
&lt;p&gt;I have been trying to decide what to build. The actual project doesn’t matter too much, it is the techniques I use during build that matters the most. I would like something that I can start off as a windows app and then extend onto the web or mobile apps.&lt;/p&gt;
&lt;p&gt;I started off thinking about a Rubik’s cube app, however my initial coding has lead me to believe it is probably too complex for my first app.&lt;/p&gt;
&lt;p&gt;Last year I spent an evening looking at Connect 4 during a &lt;a href="https://yorkcodedojo.github.io/" target="_blank" rel="noopener noreferrer"&gt;York Code Dojo&lt;/a&gt;
session. I think this should be complex enough that I can code some logic to efficiently solve the game, however not too complex I get defeated before building too much.&lt;/p&gt;
&lt;p&gt;So far I have built a console app that displays via Console.Write() commands, a grid to represent the game, with 0 meaning empty, 1 red and 2 yellow etc. I am currently working on the logic to solve the game, once I have that in a good state I can extend into a winforms app, into a web (MVC most likely) app and finally a mobile app (I have no knowledge about how to do this yet, but something I would like to try one day).&lt;/p&gt;
&lt;p&gt;Over the last few days I listened to .NetRocks where they discussed &lt;a href="https://www.dotnetrocks.com/?show=1396" target="_blank" rel="noopener noreferrer"&gt;Progressive Web Apps&lt;/a&gt;
. This sounds like a great challenge for me to aim for. A progressive Web App is a website that automatically detects various properties to give you an app that runs well whatever the state of your internet connection and whatever browser you are in.&lt;/p&gt;
&lt;p&gt;I have lots to learn but I can split it down into small sections and I can build something that demonstrates some of my skills.&lt;/p&gt;</description></item></channel></rss>