<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Martin Costello's Blog</title><link>https://blog.martincostello.com/</link><description>Recent content on Martin Costello's Blog</description><generator>Hugo</generator><language>en-gb</language><lastBuildDate>Fri, 14 Nov 2025 16:51:33 +0000</lastBuildDate><atom:link href="https://blog.martincostello.com/feed.xml" rel="self" type="application/rss+xml"/><item><title>Levelling Up Security with the GitHub Secure Open Source Fund</title><link>https://blog.martincostello.com/levelling-up-security-with-the-github-secure-open-source-fund/</link><pubDate>Mon, 11 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/levelling-up-security-with-the-github-secure-open-source-fund/</guid><description>&lt;img src="https://cdn.martincostello.com/blog_github-sosf.png" alt="The GitHub Secure Open Source Fund, showing the logos of various companies including Microsoft, 1Password, American Express, Shopify, Stripe and Vercel" title="The GitHub Secure Open Source Fund, showing the logos of various companies including Microsoft, 1Password, American Express, Shopify, Stripe and Vercel" class="img-fluid mx-auto d-block" height="" width="" &gt;

&lt;p&gt;After sitting on the secret for the last few months, I&amp;rsquo;m excited to finally share that back in May I was selected to participate
in the second cohort of the &lt;a href="https://github.blog/open-source/maintainers/securing-the-supply-chain-at-scale-starting-with-71-important-open-source-projects/" title="Securing the supply chain at scale: Starting with 71 important open source projects"&gt;GitHub Secure Open Source Fund&lt;/a&gt; through my maintenance of &lt;a href="https://github.com/App-vNext/Polly" title="The Polly project on GitHub"&gt;Polly&lt;/a&gt;. 🎉&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://resources.github.com/github-secure-open-source-fund/" title="GitHub Secure Open Source Fund"&gt;GitHub Secure Open Source Fund&lt;/a&gt; is a GitHub-lead initiative aimed at improving the security of open source software
at scale by providing funding and resources to maintainers of popular open source projects. Big names in the software industry like
1Password, American Express, Shopify, Stripe, and Vercel help fund this initiative to enhance the security posture of open source
software projects across many language ecosystems.&lt;/p&gt;
&lt;p&gt;Many open source projects are fundamental building blocks of countless software applications, whether open source or proprietary, and
the security of the entire software supply chain can be at risk if security vulnerabilities occur in these community-driven projects.
For example, Polly is a dependency of &lt;a href="https://github.com/dotnet/aspire" title="The .NET Aspire project on GitHub"&gt;.NET Aspire&lt;/a&gt;, which has become quite popular over the last year.&lt;/p&gt;
&lt;p&gt;Through my participation in the GitHub Secure Open Source Fund, I gained access to a wealth of valuable resources, including expert
guidance from GitHub staff and experts on best practices for securing open source software, as well as funding to help sustain my
involvement in the development and maintenance of the many open source projects I contribute to.&lt;/p&gt;</description></item><item><title>Continuous Benchmarks on a Budget</title><link>https://blog.martincostello.com/continuous-benchmarks-on-a-budget/</link><pubDate>Mon, 23 Sep 2024 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/continuous-benchmarks-on-a-budget/</guid><description>&lt;img src="https://cdn.martincostello.com/blog_benchmarks-regression.png" alt="A chart showing a time series for performance and memory usage with an increase in memory usage in the most recent data points" title="A chart showing a time series for performance and memory usage with an increase in memory usage in the most recent data points" class="img-fluid mx-auto d-block" height="" width="" &gt;

&lt;p&gt;Over the last few months I&amp;rsquo;ve been doing a bunch of testing with the &lt;a href="https://blog.martincostello.com/whats-new-for-openapi-with-dotnet-9/" title="What's New for OpenAPI with .NET 9"&gt;new OpenAPI support in .NET 9&lt;/a&gt;.
As part of that testing, I wanted to take a look at how the performance of the new libraries compared to the existing
open source libraries for OpenAPI support in .NET, the most popular including &lt;a href="https://github.com/RicoSuter/NSwag" title="The NSwag repository on GitHub"&gt;NSwag&lt;/a&gt; and &lt;a href="https://github.com/domaindrivendev/Swashbuckle.AspNetCore" title="The Swashbuckle.AspNetCore repository on GitHub"&gt;Swashbuckle.AspNetCore&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s fairly easy to get up and running writing some benchmarks using &lt;a href="https://github.com/dotnet/BenchmarkDotNet" title="The BenchmarkDotNet repository on GitHub"&gt;BenchmarkDotNet&lt;/a&gt;, but it&amp;rsquo;s often a task
that you need to sit down and do manually when you have the need, and then gets forgotten about as time goes on. Because of that,
I thought it would be a fun mini-project to set up some automation to run the benchmarks on a continuous basis so that I could
monitor the performance of my open source projects easily going forwards.&lt;/p&gt;
&lt;p&gt;In this post I&amp;rsquo;ll cover how I went about setting up a continuous benchmarking pipeline using GitHub Actions, &lt;a href="https://pages.github.com/" title="GitHub Pages"&gt;GitHub Pages&lt;/a&gt;
and &lt;a href="https://learn.microsoft.com/aspnet/core/blazor/" title="ASP.NET Core Blazor"&gt;Blazor&lt;/a&gt; to run and visualise the results of the benchmarks on a &amp;ldquo;good enough&amp;rdquo; basis without needing to spend any money&lt;sup&gt;*&lt;/sup&gt;
on infrastructure.&lt;/p&gt;</description></item><item><title>What's New for OpenAPI with .NET 9</title><link>https://blog.martincostello.com/whats-new-for-openapi-with-dotnet-9/</link><pubDate>Mon, 09 Sep 2024 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/whats-new-for-openapi-with-dotnet-9/</guid><description>&lt;img src="https://cdn.martincostello.com/blog_openapi.png" alt="The OpenAPI logo" title="The OpenAPI logo" class="img-fluid mx-auto d-block" height="272px" width="899px" &gt;

&lt;p&gt;Developers in the .NET ecosystem have been writing APIs with ASP.NET and ASP.NET Core for years, and
&lt;a href="https://swagger.io/docs/specification/about/" title="What Is OpenAPI?"&gt;OpenAPI&lt;/a&gt; has been a popular choice for documenting those APIs.
OpenAPI at its core is a machine-readable document that describes the endpoints available in an API.
It contains information not only about parameters, requests and responses, but also additional metadata
such as descriptions of properties, security-related metadata, and more.&lt;/p&gt;
&lt;p&gt;These documents can then be consumed by tools such as &lt;a href="https://github.com/swagger-api/swagger-ui" title="The Swagger UI repository on GitHub"&gt;Swagger UI&lt;/a&gt; to provide a user interface
for developers to interact with the API quickly and easily, such as when testing. With the recent surge in
popularity of AI-based development tools, OpenAPI has become even more important as a way to describe APIs
in a way that machines can understand.&lt;/p&gt;
&lt;p&gt;For a long time, the two most common libraries to produce API specifications at runtime for ASP.NET Core
have been &lt;a href="https://github.com/RicoSuter/NSwag" title="The NSwag repository on GitHub"&gt;NSwag&lt;/a&gt; and &lt;a href="https://github.com/domaindrivendev/Swashbuckle.AspNetCore" title="The Swashbuckle.AspNetCore repository on GitHub"&gt;Swashbuckle&lt;/a&gt;. Both libraries provide functionality that allows
developers to generate a rich OpenAPI document(s) for their APIs in either JSON and/or YAML from their
existing code. The endpoints can then be augmented in different ways, such as with attributes or custom
code, to further enrich the generated document(s) to provide a great Developer Experience for its consumers.&lt;/p&gt;
&lt;p&gt;With the upcoming release of &lt;a href="https://learn.microsoft.com/aspnet/core/release-notes/aspnetcore-9.0" title="What's new in ASP.NET Core 9.0"&gt;ASP.NET Core 9&lt;/a&gt;, the ASP.NET team have introduced new functionality
for the existing &lt;a href="https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi" title="The Microsoft.AspNetCore.OpenApi package on NuGet.org"&gt;Microsoft.AspNetCore.OpenApi NuGet package&lt;/a&gt;, that provides a
new way to generate OpenAPI documents for ASP.NET Core Minimal APIs.&lt;/p&gt;
&lt;p&gt;In this post, we&amp;rsquo;ll take a look at the new functionality and compare it to the exsisting NSwag and Swashbuckle
libraries to see how it compares in both features as well as performance.&lt;/p&gt;</description></item><item><title>Look ma, no Dockerfile! 🚫🐋 - Publishing containers with the .NET SDK 📦</title><link>https://blog.martincostello.com/look-ma-no-hands-publishing-containers-with-the-dotnet-sdk/</link><pubDate>Thu, 02 May 2024 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/look-ma-no-hands-publishing-containers-with-the-dotnet-sdk/</guid><description>&lt;img src="https://cdn.martincostello.com/blog_dotnet-containers.jpg" alt="A container ship being loaded with the .NET logo on the stern" title="A container ship being loaded with the .NET logo on the stern" class="img-fluid mx-auto d-block" height="384px" width="757px" &gt;

&lt;p&gt;Containers have been a thing in the software ecosystem for a few years now, with lots of associated technologies and
concepts - Docker, Kubernetes, Helm charts, sidecars and many more. Using containers simplifies the deployment of your
application by reducing things down to a single artifact that you can deploy along with all the required dependencies,
including the operating system, and everything should Just Work™️. It&amp;rsquo;s almost like shipping your whole machine off to production!&lt;/p&gt;
&lt;p&gt;The cost for that simplicity of deployment is the steeper learning curve for you the developer to understand all these
additional concepts and technologies. In addition, you will likely need to revisit how you build your application, creating
a &lt;a href="https://docs.docker.com/reference/dockerfile/" title="Dockerfile reference"&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/a&gt; to produce a container image that contains everything you need to build and run your application.&lt;/p&gt;
&lt;p&gt;The more complicated your build process, the more daunting this becomes - for example, if your application builds client-side
assets with a JavaScript toolchain. In that case, you need to install Node.js, npm etc. in the container build image too so you
can produce those assets. Things can quickly get complicated, and that&amp;rsquo;s before you even start thinking about things like layer
caching, exposing ports, what user to run as and more. 😮‍💨&lt;/p&gt;
&lt;p&gt;What if we could simplify a lot of that complexity and just build our application like we would if we weren&amp;rsquo;t using containers, but
then just turn it into a container image? Well, the .NET 8 SDK &lt;a href="https://devblogs.microsoft.com/dotnet/streamline-container-build-dotnet-8/" title="Streamline your container build and publish with .NET 8"&gt;allows us to do exactly this&lt;/a&gt;, meaning
you can containerise your application and not need a Dockerfile at all! 🚫🐋&lt;/p&gt;
&lt;p&gt;Plus, as a bonus, if building with GitHub Actions, we can leverage this support to
&lt;a href="https://docs.github.com/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds" title="Using artifact attestations to establish provenance for builds"&gt;attest the provenance of our container images&lt;/a&gt; with minimal additional effort. 🕵️🪪&lt;/p&gt;</description></item><item><title>.NET Native AoT Make AWS Lambda Function Go Brrr</title><link>https://blog.martincostello.com/native-aot-make-dotnet-lambda-go-brr/</link><pubDate>Wed, 29 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/native-aot-make-dotnet-lambda-go-brr/</guid><description>&lt;img src="https://cdn.martincostello.com/blog_lambda-go-brr.png" alt="The AWS Lambda logo overlaid with the .NET logo wth some fire emojis added" title="The AWS Lambda logo overlaid with the .NET logo wth some fire emojis added" class="img-fluid mx-auto d-block" height="384px" width="384px" &gt;

&lt;p&gt;Since 2017 I&amp;rsquo;ve been maintaining an Alexa skill, &lt;a href="https://www.amazon.co.uk/Martin-Costello-London-Travel/dp/B01NB0T86R" title="London Travel"&gt;&lt;em&gt;London Travel&lt;/em&gt;&lt;/a&gt;, that provides real-time information about the status of London Underground, London Overground, and the DLR (and the Elizabeth Line). The skill is an AWS Lambda function, &lt;a href="https://blog.martincostello.com/publishing-my-first-alexa-skill/" title="Publishing My First Alexa Skill"&gt;originally implemented in Node.js&lt;/a&gt;, but &lt;a href="https://blog.martincostello.com/integration-testing-lambda-with-dotnet-custom-runtime/" title="Integration testing AWS Lambda C# Functions with Lambda Test Server"&gt;since 2019&lt;/a&gt; it has been implemented in .NET.&lt;/p&gt;
&lt;p&gt;The skill uses the &lt;a href="https://github.com/timheuer/alexa-skills-dotnet" title="Alexa Skills SDK for .NET on GitHub"&gt;Alexa Skills SDK for .NET&lt;/a&gt; to handle the interactions with Alexa, and &lt;a href="https://github.com/martincostello/alexa-london-travel/pull/957" title="Update .NET SDK to 8.0.100"&gt;since earlier this month&lt;/a&gt; has been running on .NET 8.0.0.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using a &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html" title="Custom Lambda runtimes"&gt;custom runtime&lt;/a&gt; for the Lambda function instead of the .NET managed runtime. The main reason for this is that it lets me use &lt;em&gt;any&lt;/em&gt; version of .NET, not just the ones that AWS support. This has allowed me to not only use pre-release versions of .NET for testing, but it also enables me to use the latest versions of .NET &lt;a href="https://blog.martincostello.com/upgrading-to-dotnet-8-part-6-stable-release/" title="Upgrading to .NET 8: Part 6 - The Stable Release"&gt;as soon as they are released&lt;/a&gt;. The only disadvantage of this approach is that I have to patch the version of .NET being used once a month for Patch Tuesday, but &lt;a href="https://blog.martincostello.com/upgrading-to-dotnet-8-part-2-automation-is-our-friend/" title="Upgrading to .NET 8: Part 2 - Automation is our Friend"&gt;I have automation set up to do that for me&lt;/a&gt;, so the overhead of doing that is actually minimal 😎.&lt;/p&gt;
&lt;p&gt;As part of the .NET 8 release, the .NET team has put &lt;a href="https://devblogs.microsoft.com/dotnet/announcing-asp-net-core-in-dotnet-8/#asp-net-core-support-for-native-aot" title="ASP.NET Core support for native AOT"&gt;a lot of effort&lt;/a&gt; into improving the breadth of the capability of the native AoT support. With .NET 8, many more use cases are supported for AoT, making the performance and size benefits of AoT available to more applications than before. The .NET team at AWS has also been working hard on ensuring that the various AWS SDK libraries are compatible with AoT, with the various NuGet packages now annotated (and tested) as being AoT compatible.&lt;/p&gt;
&lt;p&gt;With all these changes, I was curious to see how much of a difference AoT would make to the performance of my Lambda function, so I decided to try it out. In this post I&amp;rsquo;ll go through what I needed to change to allow publishing my Alexa skill as a native application, what I learned along the way, and the results of the changes to the function&amp;rsquo;s runtime performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: It&amp;rsquo;s faster, smaller, and cheaper to run. 🚀🔥&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s dive in!&lt;/p&gt;</description></item><item><title>Upgrading to .NET 8: Part 6 - The Stable Release</title><link>https://blog.martincostello.com/upgrading-to-dotnet-8-part-6-stable-release/</link><pubDate>Mon, 20 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/upgrading-to-dotnet-8-part-6-stable-release/</guid><description>&lt;p&gt;Last week at &lt;a href="https://www.dotnetconf.net/" title=".NET Conf 2023"&gt;.NET Conf 2023&lt;/a&gt;, the stable release of .NET 8 was released as the latest &lt;a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core" title=".NET and .NET Core Support Policy"&gt;Long Term Support&lt;/a&gt; (LTS) release of the .NET platform.&lt;/p&gt;
&lt;p&gt;With the release of .NET 8.0.0 and the end of the preview releases, my past week can be summed up by the following image:&lt;/p&gt;
&lt;img src="https://cdn.martincostello.com/blog_upgrade-all-the-things.jpg" alt="The All the Things meme, with the text: Upgrade All The Things To .NET 8" title="The All the Things meme, with the text: Upgrade All The Things To .NET 8" class="img-fluid mx-auto d-block" height="" width="" &gt;</description></item><item><title>Upgrading to .NET 8: Part 5 - Preview 7 and Release Candidates 1 and 2</title><link>https://blog.martincostello.com/upgrading-to-dotnet-8-part-5-preview-7-and-rc-1-2/</link><pubDate>Fri, 13 Oct 2023 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/upgrading-to-dotnet-8-part-5-preview-7-and-rc-1-2/</guid><description>&lt;p&gt;This post is a bumper edition, covering three different releases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-7/" title="Announcing .NET 8 Preview 7"&gt;Preview 7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-rc1/" title="Announcing .NET 8 RC1"&gt;Release Candidate 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-rc2/" title="Announcing .NET 8 RC2"&gt;Release Candidate 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I had intended to continue the post-per-preview series originally, but time got away from me
with preview 7, plus there wasn&amp;rsquo;t much to say about it, and then I went on holiday for two weeks
just as release candidate 1 landed. Given release candidate 2 was released just a few days ago,
instead I figured I&amp;rsquo;d just catch-up with myself and summarise everything in this one blog post instead!&lt;/p&gt;
&lt;p&gt;Release Candidate 2 is also the last planned release before the final release of .NET 8 in November
to coincide with &lt;a href="https://www.dotnetconf.net/" title=".NET Conf 2023"&gt;.NET Conf 2023&lt;/a&gt;, so this is going to be the penultimate post in this series.&lt;/p&gt;</description></item><item><title>Upgrading to .NET 8: Part 4 - Preview 6</title><link>https://blog.martincostello.com/upgrading-to-dotnet-8-part-4-preview-6/</link><pubDate>Wed, 19 Jul 2023 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/upgrading-to-dotnet-8-part-4-preview-6/</guid><description>&lt;p&gt;Following on from &lt;a href="https://blog.martincostello.com/upgrading-to-dotnet-8-part-3-previews-1-to-5" title="Previews 1-5"&gt;part 3&lt;/a&gt; of this series, I&amp;rsquo;ve been continuing
to upgrade my projects to .NET 8 - this time to preview 6. In this post
I&amp;rsquo;ll cover more experiences with the new source generators with this
preview as well as a new feature of C# 12: &lt;em&gt;primary constructors&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>Upgrading to .NET 8: Part 3 - Previews 1-5</title><link>https://blog.martincostello.com/upgrading-to-dotnet-8-part-3-previews-1-to-5/</link><pubDate>Wed, 12 Jul 2023 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/upgrading-to-dotnet-8-part-3-previews-1-to-5/</guid><description>&lt;p&gt;In the &lt;a href="https://blog.martincostello.com/upgrading-to-dotnet-8-part-2-automation-is-our-friend" title="Automation is our Friend"&gt;previous post of this series&lt;/a&gt; I described how with some
GitHub Actions workflows we can reduce the amount of manual work required
to test each preview of .NET 8 in our projects. With the infrastructure to
do that set up we can now dig into some highlights of the things we found
in our testing of .NET 8 itself in the preview releases available so far
this year!&lt;/p&gt;</description></item><item><title>Upgrading to .NET 8: Part 2 - Automation is our Friend</title><link>https://blog.martincostello.com/upgrading-to-dotnet-8-part-2-automation-is-our-friend/</link><pubDate>Tue, 11 Jul 2023 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/upgrading-to-dotnet-8-part-2-automation-is-our-friend/</guid><description>&lt;p&gt;In &lt;a href="https://blog.martincostello.com/upgrading-to-dotnet-8-part-1-why-upgrade" title="Why Upgrade?"&gt;part 1 of this series&lt;/a&gt; I recommended that you prepare to upgrade to .NET 8 and suggested
that you start off by testing the preview releases. Testing the preview releases is a great
way to get a head start on the upgrade process and to identify any issues sooner rather than
later, but it does require an investment of your time from preview to preview each month.&lt;/p&gt;
&lt;p&gt;Even if you don&amp;rsquo;t want to test new functionality, you still need to download the new .NET SDK,
update all the .NET SDK and NuGet package versions in your projects, and then test that everything
still works (that&amp;rsquo;s already automated at least, right?). This can be a time-consuming process over
the course of a new .NET release, and it starts to become harder to scale if you want to test lots
of different codebases with the latest preview of the next .NET release.&lt;/p&gt;
&lt;p&gt;What if we could automate some of this process so that we only need to focus on the parts
where we as humans really add value compared to the mechanical parts of an upgrade?&lt;/p&gt;
&lt;p&gt;In part 2 of this series I&amp;rsquo;m going to explain how I&amp;rsquo;ve gone about automating the boring
parts of the process of testing the latest .NET preview releases using &lt;a href="https://github.com/features/actions" title="GitHub Actions"&gt;GitHub Actions&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Upgrading to .NET 8: Part 1 - Why Upgrade?</title><link>https://blog.martincostello.com/upgrading-to-dotnet-8-part-1-why-upgrade/</link><pubDate>Mon, 10 Jul 2023 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/upgrading-to-dotnet-8-part-1-why-upgrade/</guid><description>&lt;p&gt;Another year, another new major version of .NET is coming - .NET &lt;strong&gt;8&lt;/strong&gt;, to be specific.&lt;/p&gt;
&lt;p&gt;I write that like it&amp;rsquo;s brand new information - it&amp;rsquo;s been coming for a while, what with
&lt;a href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-1/" title="Announcing .NET 8 Preview 1"&gt;.NET 8 Preview 1 having being released in Feburary&lt;/a&gt; - but it&amp;rsquo;s only
recently occured to me to write this blog post series (yes, a series, more on that later).&lt;/p&gt;
&lt;p&gt;As annouced a few releases ago, a new major version of .NET is &lt;a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core#cadence" title=".NET release cadence"&gt;released every November&lt;/a&gt;.
These alternate between an odd-numbered Short Term Support (STS) release and an even-numbered
Long Term Support (LTS) release (&lt;a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core#release-types" title=".NET Release types"&gt;see here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a nice graphic here from the .NET website that illustrates how things look today:&lt;/p&gt;
&lt;img src="https://cdn.martincostello.com/blog_dotnet-8-releases.svg" alt="A timeline showing the support for .NET 5 in 2020 through to .NET 9 in 2024" title="A timeline showing the support for .NET 5 in 2020 through to .NET 9 in 2024" class="img-fluid mx-auto d-block" height="" width="" &gt;

&lt;p&gt;That means .NET 8 will be the next LTS release and supercede .NET 6 &lt;em&gt;and also&lt;/em&gt; .NET 7 by the end of 2024.&lt;/p&gt;
&lt;p&gt;But why should you upgrade to .NET 8? &lt;a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core" title=".NET and .NET Core Support Policy"&gt;Staying supported&lt;/a&gt; and
patched is the primary reason, but there&amp;rsquo;s another reason that sounds much more compelling:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;The first thing that you can do to get free performance in your ASP.NET or .NET applications is to upgrade your .NET version.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://twitter.com/DamianEdwards" title="@DamianEdwards on Twitter"&gt;Damian Edwards&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Improving ASP.NET Core Before It Ships 🚢</title><link>https://blog.martincostello.com/improving-asp-net-core-before-it-ships/</link><pubDate>Tue, 03 May 2022 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/improving-asp-net-core-before-it-ships/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This blog post was originally published by me on the &lt;a href="https://medium.com/justeattakeaway-tech/improving-asp-net-core-before-it-ships-3e44b6f65054"&gt;Just Eat Tech blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Writing code that millions of people will use is something we do every day. Writing code that millions
of developers will use feels a little different.&lt;/p&gt;
&lt;p&gt;Have you ever wondered why Microsoft releases preview versions of their products before the final release?
Well, it’s so real customers can help ensure their quality before they go live. In this post, we’ll tell you
about an issue we found in testing the previews of ASP.NET Core and how we worked with Microsoft to fix it.&lt;/p&gt;</description></item><item><title>Using the .NET JSON Source Generator with ASP.NET Core Minimal APIs</title><link>https://blog.martincostello.com/using-json-source-generators-with-aspnet-core-minimal-apis/</link><pubDate>Sun, 28 Nov 2021 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/using-json-source-generators-with-aspnet-core-minimal-apis/</guid><description>&lt;p&gt;I&amp;rsquo;ve recently completed upgrading a bunch of personal and work applications to
ASP.NET Core 6, and now that the dust has finally settled on those efforts, I
thought I&amp;rsquo;d look into a new feature of .NET 6 that I hadn&amp;rsquo;t tried out yet - &lt;a href="https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/"&gt;JSON source generators&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t come across them before, &lt;a href="https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/"&gt;C# source generators&lt;/a&gt; are a way to
write some code that can generate more code during compilation. It&amp;rsquo;s a form of
&lt;a href="https://en.wikipedia.org/wiki/Metaprogramming"&gt;metaprogramming&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the benefits of the new JSON source generator for the System.Text.Json
serializer is that it is more performant that the APIs introduced as part of
.NET 5. This is because the serializer is able to leverage code that is compiled
ahead-of-time (the source generator part) to serialize and deserialize objects
to and from JSON without using reflection (which is relatively slow).&lt;/p&gt;
&lt;p&gt;It sounds like that could give applications a performance boost at runtime, but
how can we use the new JSON source generator with ASP.NET Core &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis"&gt;Minimal APIs&lt;/a&gt;?&lt;/p&gt;</description></item><item><title>GitHub Codespaces Gotchas with ASP.NET Core OAuth</title><link>https://blog.martincostello.com/github-codespaces-gotchas-with-aspnetcore-oauth/</link><pubDate>Sun, 15 Aug 2021 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/github-codespaces-gotchas-with-aspnetcore-oauth/</guid><description>&lt;p&gt;This week GitHub &lt;a href="https://docs.github.com/codespaces" title="GitHub Codespaces Documentation"&gt;Codespaces&lt;/a&gt; was made &lt;a href="https://github.blog/changelog/2021-08-11-codespaces-is-generally-available-for-team-and-enterprise/" title="Codespaces is generally available for Team and Enterprise"&gt;generally available&lt;/a&gt; for Teams and
Enterprise, and coupled with the release of the ability to open any repository
in &lt;a href="https://code.visualstudio.com/" title="Visual Studio Code"&gt;Visual Studio Code&lt;/a&gt; in a web browser &lt;a href="https://twitter.com/github/status/1425505817827151872?s=20" title="New shortcut: Press . on any GitHub repo."&gt;just by pressing &lt;code&gt;.&lt;/code&gt;&lt;/a&gt;, I thought
I&amp;rsquo;d give it a try with some existing projects. In the process I hit a few
gotchas that took me a few hours to get to the bottom of. This post goes through
some of those and how to resolve them.&lt;/p&gt;</description></item><item><title>Integration Testing ASP.NET Core Resources Protected with Antiforgery Using Application Parts</title><link>https://blog.martincostello.com/integration-testing-antiforgery-with-application-parts/</link><pubDate>Tue, 16 Jun 2020 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/integration-testing-antiforgery-with-application-parts/</guid><description>&lt;p&gt;To protect your POST resources in an ASP.NET Core application from &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery" title="Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core"&gt;Cross-Site Request Forgery&lt;/a&gt; (CSRF) an application developer would typically use the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery#aspnet-core-antiforgery-configuration" title="ASP.NET Core antiforgery configuration"&gt;antiforgery&lt;/a&gt; features to require an antiforgery token and cookie are included in HTTP POST form requests.&lt;/p&gt;
&lt;p&gt;A necessary downside of these protections is that they make it harder to integration test such resources, particularly in a headless manner. This is because the tests need to acquire the antiforgery token and cookie to be able to successfully pass the antiforgery protections on a resource that needs to be tested.&lt;/p&gt;
&lt;p&gt;A typical approach for this is to scrape the HTML response from the application for the hidden form field token (often named &lt;code&gt;__RequestVerificationToken&lt;/code&gt;) using Regular Expressions and then using that, along with the cookie, in the request(s) the test(s) make. This can however make tests brittle to change, particularly if the UI is refactored.&lt;/p&gt;
&lt;p&gt;In this blog post I&amp;rsquo;ll discuss an alternate approach using &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/app-parts" title="Share controllers, views, Razor Pages and more with Application Parts"&gt;ASP.NET Core Application Parts&lt;/a&gt; that can make such tests easier to author and maintain, allowing you to concentrate on the core logic of your tests, rather than boilerplate setup.&lt;/p&gt;</description></item><item><title>Integration testing AWS Lambda C# Functions with Lambda Test Server</title><link>https://blog.martincostello.com/integration-testing-lambda-with-dotnet-custom-runtime/</link><pubDate>Mon, 11 Nov 2019 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/integration-testing-lambda-with-dotnet-custom-runtime/</guid><description>&lt;p&gt;&lt;em&gt;Lambda Test Server&lt;/em&gt; is a .NET Core 3.0 library available from &lt;a href="https://www.nuget.org/packages/MartinCostello.Testing.AwsLambdaTestServer/" title="MartinCostello.Testing.AwsLambdaTestServer on NuGet.org"&gt;NuGet&lt;/a&gt; which builds on top of the &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.testhost.testserver" title="TestServer Class on Microsoft Docs"&gt;&lt;code&gt;TestServer&lt;/code&gt;&lt;/a&gt; class in the &lt;a href="https://www.nuget.org/packages/Microsoft.AspNetCore.TestHost/" title="Microsoft.AspNetCore.TestHost on NuGet.org"&gt;Microsoft.AspNetCore.TestHost NuGet package&lt;/a&gt; to provide infrastructure to use with end-to-end/integration tests for .NET Core AWS Lambda Functions using a &lt;a href="https://aws.amazon.com/blogs/developer/net-core-3-0-on-lambda-with-aws-lambdas-custom-runtime/" title=".NET Core 3.0 on Lambda with AWS Lambda’s Custom Runtime"&gt;custom runtime&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The example below shows how &lt;em&gt;Lambda Test Server&lt;/em&gt; can be used to write an xunit integration test for a simple C# Lambda function that reverses an array of integers:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;[Fact]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;public&lt;/span&gt; &lt;span style="color:#cf222e"&gt;static&lt;/span&gt; &lt;span style="color:#cf222e"&gt;async&lt;/span&gt; Task Function_Reverses_Numbers&lt;span style="color:#1f2328"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#57606a"&gt;// Arrange&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;using&lt;/span&gt; &lt;span style="color:#24292e"&gt;var&lt;/span&gt; server &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;new&lt;/span&gt; LambdaTestServer&lt;span style="color:#1f2328"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;using&lt;/span&gt; &lt;span style="color:#24292e"&gt;var&lt;/span&gt; cancellationTokenSource &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;new&lt;/span&gt; CancellationTokenSource&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;TimeSpan&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;FromSeconds&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#0550ae"&gt;1&lt;/span&gt;&lt;span style="color:#1f2328"&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:#cf222e"&gt;await&lt;/span&gt; server&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;StartAsync&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;cancellationTokenSource&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;Token&lt;span style="color:#1f2328"&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:#cf222e"&gt;int&lt;/span&gt;&lt;span style="color:#1f2328"&gt;[]&lt;/span&gt; &lt;span style="color:#cf222e"&gt;value&lt;/span&gt; &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;new&lt;/span&gt;&lt;span style="color:#1f2328"&gt;[]&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt; &lt;span style="color:#0550ae"&gt;1&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#0550ae"&gt;2&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#0550ae"&gt;3&lt;/span&gt; &lt;span style="color:#1f2328"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;string&lt;/span&gt; json &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; JsonConvert&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;SerializeObject&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#cf222e"&gt;value&lt;/span&gt;&lt;span style="color:#1f2328"&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; LambdaTestContext context &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;await&lt;/span&gt; server&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;EnqueueAsync&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;json&lt;span style="color:#1f2328"&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:#cf222e"&gt;using&lt;/span&gt; &lt;span style="color:#24292e"&gt;var&lt;/span&gt; httpClient &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; server&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;CreateClient&lt;span style="color:#1f2328"&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:#57606a"&gt;// Act&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;await&lt;/span&gt; ReverseFunction&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;RunAsync&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;httpClient&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; cancellationTokenSource&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;Token&lt;span style="color:#1f2328"&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:#57606a"&gt;// Assert&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Assert&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;True&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;context&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;Response&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;TryRead&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#cf222e"&gt;out&lt;/span&gt; LambdaTestResponse response&lt;span style="color:#1f2328"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Assert&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;True&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;response&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;IsSuccessful&lt;span style="color:#1f2328"&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; json &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;await&lt;/span&gt; response&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;ReadAsStringAsync&lt;span style="color:#1f2328"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;int&lt;/span&gt;&lt;span style="color:#1f2328"&gt;[]&lt;/span&gt; actual &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; JsonConvert&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;DeserializeObject&lt;span style="color:#1f2328"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt;&lt;span style="color:#1f2328"&gt;[]&amp;gt;(&lt;/span&gt;json&lt;span style="color:#1f2328"&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; Assert&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;Equal&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#cf222e"&gt;new&lt;/span&gt;&lt;span style="color:#1f2328"&gt;[]&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt; &lt;span style="color:#0550ae"&gt;3&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#0550ae"&gt;2&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#0550ae"&gt;1&lt;/span&gt; &lt;span style="color:#1f2328"&gt;},&lt;/span&gt; actual&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The source is available &lt;a href="https://github.com/martincostello/lambda-test-server" title="Lambda Test Server on GitHub.com"&gt;in GitHub&lt;/a&gt; - pull requests are welcome!&lt;/p&gt;
&lt;p&gt;Further samples for using the library with xunit are available in GitHub here: &lt;a href="https://github.com/martincostello/lambda-test-server/tree/main/samples" title="Lambda Test Server samples on GitHub.com"&gt;https://github.com/martincostello/lambda-test-server/tree/main/samples&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Using Refit with the new System.Text.Json APIs</title><link>https://blog.martincostello.com/refit-and-system-text-json/</link><pubDate>Sun, 16 Jun 2019 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/refit-and-system-text-json/</guid><description>&lt;p&gt;I&amp;rsquo;m a big fan of the &lt;a href="https://github.com/reactiveui/refit" title="Refit on GitHub.com"&gt;&lt;em&gt;Refit&lt;/em&gt;&lt;/a&gt; library for calling HTTP APIs from my .NET applications.&lt;/p&gt;
&lt;p&gt;It uses code generation to let you do simple HTTP calls using interfaces and uses &lt;a href="https://www.newtonsoft.com/json" title="JSON.NET website"&gt;JSON.NET&lt;/a&gt; under-the-hood to handle serializing and deserializing JSON.&lt;/p&gt;
&lt;p&gt;For example, to get a repository from the GitHub API you could define these types:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;public&lt;/span&gt; &lt;span style="color:#cf222e"&gt;class&lt;/span&gt; &lt;span style="color:#1f2328"&gt;Organization&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt; [JsonProperty(&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 style="color:#cf222e"&gt;public&lt;/span&gt; &lt;span style="color:#cf222e"&gt;string&lt;/span&gt; Login &lt;span style="color:#1f2328"&gt;{&lt;/span&gt; &lt;span style="color:#cf222e"&gt;get&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt; &lt;span style="color:#cf222e"&gt;set&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt; &lt;span style="color:#1f2328"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt; [JsonProperty(&amp;#34;id&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;public&lt;/span&gt; &lt;span style="color:#cf222e"&gt;long&lt;/span&gt; Id &lt;span style="color:#1f2328"&gt;{&lt;/span&gt; &lt;span style="color:#cf222e"&gt;get&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt; &lt;span style="color:#cf222e"&gt;set&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt; &lt;span style="color:#1f2328"&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:#57606a"&gt;// ... other properties&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;[Headers(&amp;#34;Accept: application/vnd.github.v3+json&amp;#34;, &amp;#34;User-Agent: My-App/1.0.0&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;public&lt;/span&gt; &lt;span style="color:#cf222e"&gt;interface&lt;/span&gt; &lt;span style="color:#1f2328"&gt;IGitHub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt; [Get(&amp;#34;/orgs/{organization}&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Task&lt;span style="color:#1f2328"&gt;&amp;lt;&lt;/span&gt;Organization&lt;span style="color:#1f2328"&gt;&amp;gt;&lt;/span&gt; GetOrganizationAsync&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#cf222e"&gt;string&lt;/span&gt; organization&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then you could call the API like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;var&lt;/span&gt; client &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; RestService&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;For&lt;span style="color:#1f2328"&gt;&amp;lt;&lt;/span&gt;IGitHub&lt;span style="color:#1f2328"&gt;&amp;gt;(&lt;/span&gt;&lt;span style="color:#0a3069"&gt;&amp;#34;https://api.github.com&amp;#34;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;var&lt;/span&gt; org &lt;span style="color:#1f2328"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;await&lt;/span&gt; client&lt;span style="color:#1f2328"&gt;.&lt;/span&gt;GetOrganizationAsync&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#0a3069"&gt;&amp;#34;dotnet&amp;#34;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This week &lt;a href="https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0-preview-6/" title="Announcing .NET Core 3.0 Preview 6"&gt;.NET Core 3.0 preview 6&lt;/a&gt; was released, and with that the &lt;a href="https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/" title="Try the new System.Text.Json APIs"&gt;new System.Text.Json APIs&lt;/a&gt;. These new APIs are designed to be more performant and do less allocations that JSON.NET, so should bring performance benefits to applications that use them.&lt;/p&gt;
&lt;p&gt;So what should you do if you want to use the new System.Text.Json APIs with Refit?&lt;/p&gt;</description></item><item><title>Prototyping Sign In with Apple for ASP.NET Core</title><link>https://blog.martincostello.com/sign-in-with-apple-prototype-for-aspnet-core/</link><pubDate>Mon, 10 Jun 2019 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/sign-in-with-apple-prototype-for-aspnet-core/</guid><description>&lt;p&gt;Last week at Apple&amp;rsquo;s &lt;a href="https://developer.apple.com/wwdc19/" title="WWDC19"&gt;WWDC 2019&lt;/a&gt; conference, Apple announced a forthcoming service for enabling users to log into apps and services using their Apple ID, &lt;a href="https://developer.apple.com/sign-in-with-apple/" title="Sign In with Apple"&gt;&lt;em&gt;Sign In with Apple&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main points of note about the new service are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Users can sign in without having to give their email address to a third-party;&lt;/li&gt;
&lt;li&gt;It will be required as an option in the future for apps that support third-party sign-in.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Just &lt;em&gt;one day&lt;/em&gt; after the announcement at WWDC19, &lt;a href="https://github.com/leastprivilege" title="@leastprivilege on GitHub.com"&gt;@leastprivilege&lt;/a&gt; of Identity Server fame, opened a &lt;a href="https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/issues/314" title="Support for Apple Sign-in on GitHub.com"&gt;GitHub issue&lt;/a&gt; over at the &lt;a href="https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers" title="AspNet.Security.OAuth.Providers on GitHub.com"&gt;&lt;em&gt;AspNet.Security.OAuth.Providers&lt;/em&gt;&lt;/a&gt; repository requesting a provider to support &lt;em&gt;Sign In with Apple&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;While the issue was opened slightly tongue-in-cheek, it&amp;rsquo;s a valid start to the conversation about investigating support for this new technology (or not).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve recently become a maintainer of the &lt;a href="https://github.com/aspnet-contrib" title="aspnet-contrib org on GitHub.com"&gt;aspnet-contrib&lt;/a&gt; organisation in GitHub.com, which provides a suite of community-written providers for various OAuth 2.0 and Open ID 2.0 third-party authentication providers. Over the last few years I&amp;rsquo;ve made a number of contributions; for an &lt;a href="https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/pull/157" title="Add Amazon provider"&gt;Amazon Login provider&lt;/a&gt;, and most recently starting the work to &lt;a href="https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/pull/280" title="Support ASP.NET Core 3.0"&gt;add support for ASP.NET Core 3.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Given the community discussion and appetite, some previous experience implementing &lt;a href="https://blog.martincostello.com/bringing-apple-pay-to-the-web" title="Bringing Apple Pay to the web"&gt;Apple Pay JS for ASP.NET Core&lt;/a&gt;, and some shiny new technology to play with, last I decided to try my hand at adding support for &lt;em&gt;Sign In with Apple&lt;/em&gt; for ASP.NET Core myself via &lt;em&gt;AspNet.Security.OAuth.Providers&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>Pseudo-localization with ASP.NET Core</title><link>https://blog.martincostello.com/aspnet-core-pseudo-localization/</link><pubDate>Mon, 17 Dec 2018 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/aspnet-core-pseudo-localization/</guid><description>&lt;p&gt;Earlier this year I read a &lt;a href="https://medium.com/netflix-techblog/pseudo-localization-netflix-12fff76fbcbe" title="Pseudo Localization @ Netflix"&gt;blog post&lt;/a&gt; by &lt;a href="https://www.linkedin.com/in/timjbrandall/" title="Tim Brandall on LinkedIn"&gt;Tim Brandall&lt;/a&gt; at Netflix about how they use pseudo-localization to test the User Interfaces of their various native applications for layout issues. For example, text in languages such as German and Finnish can be up to 40% longer than their English equivalents, causing text overflow in UI elements that don&amp;rsquo;t account for such differences.&lt;/p&gt;
&lt;p&gt;A simple example of pseudo-localisation would be changing the text of the sentence below.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The quick brown fox jumped over the lazy dog&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With transformations to lengthen the text, apply accents and surround it in brackets applied, it becomes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;[Ţĥéẋ ǫûîçķẋẋ ƀŕöŵñẋẋ ƒöẋẋ ĵûɱþéðẋẋ öṽéŕẋẋ ţĥéẋ ļåžýẋẋ ðöĝẋẋ]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I found the approach particularly interesting, so wondered how I could look at using it in my own day-to-day work.&lt;/p&gt;</description></item><item><title>SQL LocalDB Wrapper v2 - The Next Generation</title><link>https://blog.martincostello.com/sql-localdb-wrapper-v2/</link><pubDate>Tue, 02 Oct 2018 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/sql-localdb-wrapper-v2/</guid><description>&lt;p&gt;After over 2 years and 100,000 package downloads since the &lt;a href="https://www.nuget.org/packages/System.Data.SqlLocalDb/1.15.0" title="System.Data.SqlLocalDb 1.15.0 on NuGet.org"&gt;last release&lt;/a&gt; of &lt;a href="https://github.com/martincostello/sqllocaldb" title="SQL LocalDB Wrapper on GitHub.com"&gt;SQL LocalDB Wrapper&lt;/a&gt;, I&amp;rsquo;ve released &lt;a href="https://github.com/martincostello/sqllocaldb/releases/tag/v2.0.0" title="SQL LocalDB Wrapper v2.0.0 on GitHub.com"&gt;version 2&lt;/a&gt; to NuGet.&lt;/p&gt;
&lt;p&gt;Version 2.0.0 of SQL LocalDB Wrapper is a major rewrite of version 1.x.x, and is now fully .NET Core compatible. You can read more about the changes in the &lt;a href="https://github.com/martincostello/sqllocaldb/releases/tag/v2.0.0" title="SQL LocalDB Wrapper 2.0.0 release notes"&gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/MartinCostello.SqlLocalDb" title="MartinCostello.SqlLocalDb on NuGet.org"&gt;NuGet package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/martincostello/sqllocaldb" title="SQL LocalDB Wrapper on GitHub.com"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Writing Logs to xunit Test Output</title><link>https://blog.martincostello.com/writing-logs-to-xunit-test-output/</link><pubDate>Sun, 30 Sep 2018 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/writing-logs-to-xunit-test-output/</guid><description>&lt;p&gt;Today I&amp;rsquo;ve published a NuGet package that simplifies the mechanics of writing logs to the test output for xunit tests, &lt;code&gt;MartinCostello.Logging.XUnit&lt;/code&gt; v0.1.0. It&amp;rsquo;s open-source with an Apache 2.0 licence and available on GitHub.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/MartinCostello.Logging.XUnit/" title="MartinCostello.Logging.XUnit on NuGet.org"&gt;NuGet package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/martincostello/xunit-logging" title="MartinCostello.Logging.XUnit on GitHub.com"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pull Requests and questions are welcome over on GitHub - I hope you find it useful!&lt;/p&gt;</description></item><item><title>Deploying a static website to Azure Storage from AppVeyor</title><link>https://blog.martincostello.com/azure-static-websites-with-appveyor/</link><pubDate>Sat, 30 Jun 2018 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/azure-static-websites-with-appveyor/</guid><description>&lt;p&gt;This week the Azure storage team &lt;a href="https://azure.microsoft.com/en-gb/blog/azure-storage-static-web-hosting-public-preview/" title="Static website hosting for Azure Storage now in public preview"&gt;finally announced&lt;/a&gt; that Azure Storage now support hosting static websites. This has been a &lt;a href="https://feedback.azure.com/forums/217298-storage/suggestions/6417741-static-website-hosting-in-azure-blob-storage" title="Static website hosting in Azure blob storage"&gt;long-standing&lt;/a&gt; request from users of Azure (for nearly 4 years), so it&amp;rsquo;s great to see something now available for use, even if at the time of writing it&amp;rsquo;s currently only in public preview.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been hosting this blog in &lt;a href="https://blog.martincostello.com/migrating-from-iis-to-s3/" title="Migrating to Amazon S3"&gt;AWS for almost a year now&lt;/a&gt;, so I thought I&amp;rsquo;d give the public preview a try and automate deployment with &lt;a href="https://www.appveyor.com/" title="AppVeyor CI"&gt;AppVeyor&lt;/a&gt; as well at the same time.&lt;/p&gt;</description></item><item><title>Upgrade to ASP.NET Core 2.1 for Productivity and Performance Gains</title><link>https://blog.martincostello.com/upgrade-to-dotnet-21-for-productivity-and-performance-gains/</link><pubDate>Sat, 23 Jun 2018 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/upgrade-to-dotnet-21-for-productivity-and-performance-gains/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using .NET Core since it was released &lt;a href="https://blogs.msdn.microsoft.com/dotnet/2016/06/27/announcing-net-core-1-0/" title="Announcing .NET Core 1.0"&gt;back in June 2016&lt;/a&gt; as my development technology of choice for my personal projects, as well as helping introduce it as a mainstream technology choice at &lt;a href="https://www.just-eat.com/" title="Just Eat global website"&gt;Just Eat&lt;/a&gt; (my employer at the time of writing).&lt;/p&gt;
&lt;p&gt;I find it so much more pleasurable to code against compared to &amp;ldquo;traditional&amp;rdquo; ASP.NET. With features such as self-hosting, built-in dependency injection and a high level of testability, you can really focus on solving the domain problem at hand, rather than worrying too much over boilerplate and ceremony.&lt;/p&gt;
&lt;p&gt;Each new release, both major and minor, brings something new to geek-out over, but ASP.NET Core 2.1 has been a particular stand-out so far for new features and benefits that I find really compelling as a software developer.&lt;/p&gt;</description></item><item><title>ASP.NET Core 2.1 – Supercharging Our Applications 🚀</title><link>https://blog.martincostello.com/aspnet-core-21-supercharging-our-applications/</link><pubDate>Thu, 14 Jun 2018 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/aspnet-core-21-supercharging-our-applications/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This blog post was originally published by me on the &lt;a href="https://web.archive.org/web/20240422072816/https://tech.justeattakeaway.com/2018/06/14/aspnet-core-21-supercharging-our-applications/"&gt;Just Eat Tech blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/asp-net-core-2-1-0-now-available/"&gt;ASP.NET Core 2.1&lt;/a&gt; was released by Microsoft at the end of May, and last week we deployed
two consumer-facing applications upgraded to use ASP.NET Core 2.1 to production for the first time.&lt;/p&gt;
&lt;p&gt;These applications have now been run in production for an entire weekend of peak traffic, and we’ve seen
some great performance improvements – in some cases &lt;strong&gt;improving average response times by over 40%&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Reliably Testing HTTP Integrations in a .NET Application</title><link>https://blog.martincostello.com/reliably-testing-http-integrations-in-a-dotnet-application/</link><pubDate>Tue, 03 Oct 2017 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/reliably-testing-http-integrations-in-a-dotnet-application/</guid><description>&lt;p&gt;Over the past few months I&amp;rsquo;ve been working on some new ASP.NET Core applications in my day job at Just Eat, and as part of that devised a new strategy for integration testing the applications with respect to their HTTP dependencies.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve written a blog post about the problems I faced and how I went about solving them &lt;a href="https://blog.martincostello.com/reliably-testing-http-integrations-in-dotnet-applications/" title="Read the post here"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Reliably Testing HTTP Integrations in a .NET Application</title><link>https://blog.martincostello.com/reliably-testing-http-integrations-in-dotnet-applications/</link><pubDate>Mon, 02 Oct 2017 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/reliably-testing-http-integrations-in-dotnet-applications/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This blog post was originally published by me on the &lt;a href="https://web.archive.org/web/20240622022707/https://tech.justeattakeaway.com/2017/10/02/reliably-testing-http-integrations-in-a-dotnet-application/"&gt;Just Eat Tech blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Testing HTTP dependencies in modern web applications is a common problem, but it’s also something that can
create difficulty for authoring reliable tests. Today, we’re open-sourcing a library to help reduce the friction
many developers have with this common requirement: JustEat.HttpClientInterception. You can find the repository in
&lt;a href="https://github.com/justeattakeaway/httpclient-interception"&gt;our GitHub organisation&lt;/a&gt; and can find the package available to &lt;a href="https://www.nuget.org/packages/JustEat.HttpClientInterception/"&gt;download at JustEat.HttpClientInterception on NuGet.org&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Migrating to Amazon S3</title><link>https://blog.martincostello.com/migrating-from-iis-to-s3/</link><pubDate>Mon, 28 Aug 2017 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/migrating-from-iis-to-s3/</guid><description>&lt;p&gt;Since I set up my blog in March 2014, it&amp;rsquo;s been running in IIS as part of an Azure App Service. Initially this was required as the blog was originally a WordPress site, so a server was required to run the PHP code for WordPress. However when I got fed up with keeping WordPress up-to-date and &lt;a href="https://blog.martincostello.com/why-i-switched-from-wordpress-to-middleman/" title="Why I Switched From WordPress To Middleman"&gt;migrated to a static Middleman site&lt;/a&gt;, I left it hosted in Azure. This was mainly because it was the easiest option, as that&amp;rsquo;s where it was already, but also because this allowed me to specify HTTP response headers still, such as for &lt;code&gt;X-Frame-Options&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At the end of the day though, this blog is still statically generated, and running a whole web server (actually two, one in Azure&amp;rsquo;s East US datacentre, another in UK South) is just overkill. Given that Amazon S3 supports static website hosting, I thought I&amp;rsquo;d migrate it to an S3 bucket instead.&lt;/p&gt;</description></item><item><title>Publishing My First Alexa Skill</title><link>https://blog.martincostello.com/publishing-my-first-alexa-skill/</link><pubDate>Mon, 20 Feb 2017 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/publishing-my-first-alexa-skill/</guid><description>&lt;p&gt;A few weeks ago at work it was our quarterly Hackathon. After a dearth of ideas I thought of an idea to extend our Alexa app to incorporate something I&amp;rsquo;ve been working on in the office over the last few months. Over the course of a few days a colleague and I tweaked the skill and achieved our aim, which was pretty fun. Did I mention we also won the technical category?&lt;/p&gt;
&lt;p&gt;Off the back of that success I thought I&amp;rsquo;d have a go at writing my own skill, which was &lt;a href="https://www.amazon.co.uk/dp/B01NB0T86R" title="London Travel on amazon.co.uk"&gt;finally accepted into the Alexa Skill Store&lt;/a&gt; on the 14th February after it&amp;rsquo;s third round of certification tests. It&amp;rsquo;s a fairly simple skill with just two &amp;ldquo;intents&amp;rdquo; that allows you to either ask about current disruption on any London tube line, the London Overground or the DLR, or for just a specific line. It&amp;rsquo;s also 100% open-source, &lt;a href="https://github.com/martincostello/alexa-london-travel" title="Alexa London Travel on GitHub"&gt;hosted on GitHub&lt;/a&gt;. The &lt;a href="https://aws.amazon.com/lambda/pricing/#lambda" title="AWS Lambda pricing"&gt;free AWS Lambda tier&lt;/a&gt; also makes it free to run (unless the skill becomes wildly popular&amp;hellip;).&lt;/p&gt;
&lt;p&gt;Now the dust has settled and I&amp;rsquo;ve got some free time, I thought I&amp;rsquo;d do a blog post about how I got started with Alexa and the idea for the skill, how I coded it and set up the Continuous Integration, how I got it through the certification tests and, finally, setting up monitoring for it in production.&lt;/p&gt;</description></item><item><title>BrowserStack Automate API Client v2</title><link>https://blog.martincostello.com/browserstack-automate-api-client-v2/</link><pubDate>Tue, 18 Oct 2016 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/browserstack-automate-api-client-v2/</guid><description>&lt;p&gt;I&amp;rsquo;ve just released &lt;a href="https://www.nuget.org/packages/MartinCostello.BrowserStack.Automate"&gt;version 2.0.1&lt;/a&gt; of the &lt;a href="https://www.browserstack.com/automate"&gt;BrowserStack Automate&lt;/a&gt; .NET client open source project that I maintain on &lt;a href="https://martincostello.github.io/browserstack-automate/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Apple Pay JS</title><link>https://blog.martincostello.com/apple-pay-js/</link><pubDate>Mon, 10 Oct 2016 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/apple-pay-js/</guid><description>&lt;p&gt;I&amp;rsquo;ve been working on an integration of the new &lt;a href="https://developer.apple.com/reference/applepayjs"&gt;Apple Pay JS&lt;/a&gt; SDK over the last few months. If you&amp;rsquo;d like to read about it, check out my post &lt;a href="https://blog.martincostello.com/bringing-apple-pay-to-the-web"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Bringing Apple Pay to the web</title><link>https://blog.martincostello.com/bringing-apple-pay-to-the-web/</link><pubDate>Mon, 10 Oct 2016 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/bringing-apple-pay-to-the-web/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This blog post was originally published by me on the &lt;a href="https://web.archive.org/web/20161015205706/http://tech.just-eat.com:80/2016/10/10/bringing-apple-pay-to-the-web/"&gt;Just Eat Tech blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Back in June at &lt;a href="https://developer.apple.com/videos/play/wwdc2016/703/"&gt;WWDC&lt;/a&gt;, Apple announced that &lt;a href="https://www.apple.com/uk/apple-pay/"&gt;Apple Pay&lt;/a&gt; was expanding its reach.
No longer just for apps and Wallet on TouchID compatible iOS devices and the Apple Watch, it would also
be coming to Safari in iOS 10 and macOS Sierra in September 2016.&lt;/p&gt;
&lt;p&gt;Just Eat was a launch partner when Apple Pay was released in the UK in our &lt;a href="https://itunes.apple.com/gb/app/just-eat-takeaway-food-delivery/id566347057"&gt;iOS app&lt;/a&gt; in 2015.
We wanted to again be one of the first websites to support Apple Pay on the web by making it available within
&lt;a href="https://www.just-eat.co.uk/"&gt;just-eat.co.uk&lt;/a&gt;. Our mission is to make food discovery exciting for everyone – and supporting
Apple Pay for payment will make your experience even more dynamic and friction-free.&lt;/p&gt;
&lt;p&gt;Alberto from our iOS team wrote a post about &lt;a href="https://web.archive.org/web/20161015205706/http://tech.just-eat.com/2015/07/14/the-journey-of-apple-pay-at-just-eat/"&gt;how we introduced Apple Pay&lt;/a&gt; into our
iOS app last year, and this post follows on from that journey with a write-up of how we went about making
Apple Pay available on our website to iOS and macOS users with the new &lt;a href="https://developer.apple.com/documentation/applepayontheweb"&gt;Apple Pay JS SDK&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>This Blog Is Now Open Source!</title><link>https://blog.martincostello.com/this-blog-is-now-opensource/</link><pubDate>Mon, 30 Nov 2015 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/this-blog-is-now-opensource/</guid><description>&lt;p&gt;TL;DR - This blog is now hosted on &lt;a href="https://github.com/martincostello/blog"&gt;GitHub.com&lt;/a&gt;!&lt;/p&gt;</description></item><item><title>Why I Switched From WordPress To Middleman</title><link>https://blog.martincostello.com/why-i-switched-from-wordpress-to-middleman/</link><pubDate>Thu, 18 Jun 2015 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/why-i-switched-from-wordpress-to-middleman/</guid><description>&lt;p&gt;A few years ago I thought I&amp;rsquo;d set up a blog. Initially I created a blog in &lt;a href="http://martincostello.blogspot.co.uk/"&gt;Blogspot&lt;/a&gt; but I decided some time later that I&amp;rsquo;d rather host it myself with custom DNS, etc., mainly as a learning exercise. As I&amp;rsquo;m mostly a developer in the Microsoft stack, I decided I&amp;rsquo;d set it up in Windows Azure as an Azure Website (now a &amp;ldquo;Microsoft Azure Web App&amp;rdquo;) as that was something I knew of and knew a little about. A few clicks through a wizard later and I had a WordPress blog running in Azure, backed by a MySQL database. Great - time to get blogging!&lt;/p&gt;
&lt;p&gt;Flash-foward a few years, and I had a sum total of &lt;a href="https://blog.martincostello.com/ensuring-your-asp-net-website-is-secure/"&gt;one solitary blog post&lt;/a&gt;. Yeah, so I&amp;rsquo;d been a bit slack on the whole writing a blog thing. However I&amp;rsquo;ve got an idea for a second blog post that I&amp;rsquo;ve been procrastinating over writing for a while, so I thought I&amp;rsquo;d start on that (aside: this isn&amp;rsquo;t that blog post, that&amp;rsquo;s coming soon). By this point I&amp;rsquo;d grown two different Azure subscriptions and the blog was running in the wrong one and I was starting to hit limits on my free Azure credits due to other usage, so I figured I&amp;rsquo;d switch it around. The problems begin.&lt;/p&gt;</description></item><item><title>Ensuring Your ASP.NET Website Is Secure</title><link>https://blog.martincostello.com/ensuring-your-asp-net-website-is-secure/</link><pubDate>Tue, 04 Mar 2014 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/ensuring-your-asp-net-website-is-secure/</guid><description>&lt;!-- markdownlint-disable-file MD036 --&gt;
&lt;p&gt;So recently I&amp;rsquo;ve been doing some work ensuring some websites I work on are secure. This has been from a mix of hands-on testing of them myself, dealing with feedback from dedicated security testers testing the applications, and this week attending an &amp;ldquo;ASP.NET Secure Coding&amp;rdquo; training course.&lt;/p&gt;
&lt;p&gt;From my own testing I found the odd thing here and there during development based on what I&amp;rsquo;ve read in the past is best-practice. These were exclusively application/coding changes. Fixing these was a mix of &amp;ldquo;Oh yeah&amp;rdquo; realisations or a quick Google leading to MSDN or Stack Overflow, leading to some simple one-line changes here and there.&lt;/p&gt;
&lt;p&gt;The same was true of the results from the dedicated security testers. This was slightly more work, as they were very good at saying &amp;ldquo;X is an issue&amp;rdquo;, but almost useless at saying how to fix it. They also did some tests which were more of the server and network configuration, which in some cases fell out of my personal work remit. However, a secure app is a secure app, meaning that you just can&amp;rsquo;t ignore it because it&amp;rsquo;s not controllable by the code. This meant yet further reading to find out how to fix the software issues, as well as reading further afield to find out how to fix the server and network configuration issues as well.&lt;/p&gt;
&lt;p&gt;Then there was the security testing course. The title was a bit of a misnomer, as it wasn&amp;rsquo;t so much &amp;ldquo;how to code securely&amp;rdquo; as &amp;ldquo;how to find security problems&amp;rdquo;. It was very useful as it was quite eye-opening to discover what seemingly innocent &amp;ldquo;oh that&amp;rsquo;s not important&amp;rdquo; small niggly things could, in the hands of a skilled &amp;ldquo;hacker&amp;rdquo;, actually lead to your machine being completely owned by an attacker.&lt;/p&gt;
&lt;p&gt;However, after three rounds of realisation, fixing and testing, there was one common theme I found with all of this - there was no central resource detailing how to fix all of the issues that came up. There were a lot of resources where just one problem would be described (and sometimes a fix for it described), but a lot of the time there&amp;rsquo;d be a page about a problem, but you&amp;rsquo;d need to go to a completely different one for the fix. Some required some creative Googling to find, others were right there (if you knew what you were looking for).&lt;/p&gt;
&lt;p&gt;So, Dear Reader, why have I written this? Well, I thought it would be a good idea to collate all the stuff that&amp;rsquo;s best practice into a single blog post, and then include for each one the instructions of how to fix it. Helpful right? Well, at least I hope so.&lt;/p&gt;</description></item><item><title>About Me</title><link>https://blog.martincostello.com/about-me/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/about-me/</guid><description/></item><item><title>Archive</title><link>https://blog.martincostello.com/archive/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/archive/</guid><description/></item><item><title>Error</title><link>https://blog.martincostello.com/error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/error/</guid><description/></item><item><title>Not Found</title><link>https://blog.martincostello.com/notfound/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.martincostello.com/notfound/</guid><description/></item></channel></rss>