<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Pete's Blog</title><link>https://petedavis.io:443/blog</link><description></description><item><title>Orchard Core: Up and Running!</title><link>https://petedavis.io:443/blog/orchard-core-up-and-running</link><description>&lt;p&gt;The foundations of Orchard Core are pretty amazing, and the &lt;a href="https://www.youtube.com/watch?v=lSvtxQkaUq4" target="_blank"&gt;performance without caching rendered HTML output is stunning&lt;/a&gt;. However getting up and running to develop your own modules and themes has never been simpler now that the &lt;a href="https://www.youtube.com/watch?v=WCmfa1gHsQo&amp;amp;t=374s" target="_blank"&gt;entire CMS feature set is just a set of Nuget packages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have never built the Orchard Core project from source, &lt;a href="https://www.youtube.com/watch?v=WCmfa1gHsQo&amp;amp;t=374s" target="_blank"&gt;and tried to follow the demo as presented by&amp;nbsp;Sebastien Ros&lt;/a&gt;, then you will most likely have hit some nuget package dependency issues.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here is a quick process to get Orchard Core CMS up and running from the AppVeyour builds.&lt;/p&gt;
&lt;h2&gt;Step 1: Create an Empty ASP.NET Core Web Application&lt;/h2&gt;
&lt;p&gt;First create a new empty ASP.NET&amp;nbsp;Core Web Application.&lt;/p&gt;
&lt;p&gt;&lt;img class="img-responsive" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/orchard-core-up-and-running/NewCoreWebApp.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="img-responsive" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/orchard-core-up-and-running/EmptyWebApp.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Step 2: Install Orchard Core Nuget Packages&lt;/h2&gt;
&lt;blockquote&gt;
&lt;h3&gt;Update - 24/04/2017&lt;/h3&gt;
You should no longer need the other feeds that have the nuget package dependencies for Orchard Core, they have now been mirrored in the orchardcore-preview feed on MyGet. Therefore just use the single&amp;nbsp;orchardcore-preview feed.&lt;/blockquote&gt;
&lt;p&gt;Now we need to add NuGet.config file next to your solution file that adds all the required feeds for both the Orchard Core preview packages, and the Orchard Core package dependencies that are also in various forms of Beta release. This is basically the same setup as the Orchard Core source code, except we have added one more feed for built packages.&lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/petedavis/d398ab0c8e3e5d86f27543f1440fb3ff.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;Now add the OrchardCore.Cms package to your project&lt;/p&gt;
&lt;pre&gt;Install-Package OrchardCore.Cms -Prerelease&lt;/pre&gt;
&lt;h2&gt;Step 3: Configure Orchard Core CMS&lt;/h2&gt;
&lt;p&gt;Edit the Startup.cs to add the OrchardCms to the services collection.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public void ConfigureServices(IServiceCollection services)&lt;br /&gt;{&lt;br /&gt;    services.AddOrchardCms();&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Configure the application builder to use the MVC modules.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)&lt;br /&gt;{&lt;br /&gt;    loggerFactory.AddConsole();&lt;br /&gt;&lt;br /&gt;    if (env.IsDevelopment())&lt;br /&gt;    {&lt;br /&gt;        app.UseDeveloperExceptionPage();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    app.UseModules();&lt;br /&gt;}&lt;/pre&gt;
&lt;h2&gt;Step 4: Run Orchard Core CMS&lt;/h2&gt;
&lt;p&gt;Now Press F5 and you should be now at the setup screen for the Orchard Core CMS.&lt;/p&gt;
&lt;p&gt;&lt;img class="img-responsive" alt="Orchard Core Setup Screen" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/orchard-core-up-and-running/orchard_core_setup_screen.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Lift Off" href="https://flickr.com/photos/soldiersmediacenter/3729394795"&gt;Lift Off&lt;/a&gt; flickr photo by &lt;a href="https://flickr.com/people/soldiersmediacenter"&gt;The U.S. Army&lt;/a&gt; shared under a &lt;a href="https://creativecommons.org/licenses/by/2.0/"&gt;Creative Commons (BY) license&lt;/a&gt;&lt;/p&gt;</description><pubDate>Fri, 21 Apr 2017 02:46:00 GMT</pubDate><guid isPermaLink="true">https://petedavis.io:443/blog/orchard-core-up-and-running</guid></item><item><title>IIS Express HTTPS Trusted Connection to localhost: The quick fix</title><link>https://petedavis.io:443/blog/iis-express-https-trusted-connection-to-localhost-the-quick-fix</link><description>&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you had clicked yes to this dialog then this would have never been an issue...&lt;/p&gt;
&lt;p&gt;&lt;img width="486" height="198" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/iis-express-https/vs_certificate_install_prompt.png" /&gt;&lt;/p&gt;
&lt;p&gt;So if you have clicked no on this dialog and dont prompt, and then realise that you needed to actually click yes otherwise HTTPS wont work, then this is the simplest way to get IIS Express HTTPS connections to be trusted. Bascally IIS Express has a certificate installed on your machine that it uses to encrtypt HTTPS traffic, only this certificate is not trusted, and nor should it be really. However if you do want to enable trust using that certificate, then this is the quick copy and paste solution.&lt;/p&gt;
&lt;p&gt;Run the Microsoft Management Console (mmc.exe)&lt;/p&gt;
&lt;p&gt;&lt;img width="370" height="219" class="img-responsive" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/iis-express-https/run_mmc.png" /&gt;&lt;/p&gt;
&lt;p&gt;Select File -&amp;gt; Add Remove Snap-ins&lt;/p&gt;
&lt;p&gt;&lt;img width="600" height="433" class="img-responsive" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/iis-express-https/mmc_computer_account_certificates_snapin.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Next Expand Personal -&amp;gt; Certificates&lt;/p&gt;
&lt;p&gt;&lt;img width="300" height="102" class="img-responsive" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/iis-express-https/mmc_personal_certificates_folder.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now locate the "IIS Express Devlopment Certificate", right click and copy&lt;/p&gt;
&lt;p&gt;&lt;img width="800" height="264" class="img-responsive" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/iis-express-https/IIS_Express_development_certificate_copy.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Now expand Trusted People -&amp;gt; Certificates, right click the folder and select Paste.&lt;/p&gt;
&lt;p&gt;&lt;img width="400" height="211" class="img-responsive" alt="" src="https://static-austse.devworx.net.au/media/petedavis/blog-images/iis-express-https/mmc_trusted_people_certificates_folder_paste.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;You should now have the IIS Express Development Certificate in the trusted people folder for the system, and refereshing the browser will now trust your HTTPS connection to IIS Express.&lt;/p&gt;</description><pubDate>Mon, 31 Oct 2016 00:10:00 GMT</pubDate><guid isPermaLink="true">https://petedavis.io:443/blog/iis-express-https-trusted-connection-to-localhost-the-quick-fix</guid></item><item><title>URL encoding password reset or email confirmation tokens</title><link>https://petedavis.io:443/blog/url-encoding-password-reset-or-email-confirmation-tokens</link><description>&lt;p&gt;Asp.Net Identity 2.0 makes it really easy to validate an email address by using the&amp;nbsp;GenerateEmailConfirmationTokenAsync method. However I recently hit an issue where the simplest path, from the same controller, in the same web app, on the same server could not round trip a validation token to confirm the email address.&lt;/p&gt;
&lt;p&gt;Using nancy endpoint to send a code, and then validate the code.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public class ConfirmEmailModule : NancyModule&lt;br /&gt;{&lt;br /&gt;    private readonly IdentityUserManager _userManager;&lt;br /&gt;&lt;br /&gt;    public ConfirmEmailModule(IdentityUserManager userManager) : base("confirmEmail")&lt;br /&gt;    {&lt;br /&gt;        _userManager = userManager;&lt;br /&gt;        Get["/", true] = async (x, ct) =&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            var validateAttempt = this.Bind&amp;lt;ValidateEmail&amp;gt;();&lt;br /&gt;            var code = &lt;span&gt;HttpUtility&lt;/span&gt;.UrlDecode(validateAttempt.Code);&lt;br /&gt;            var result = await _userManager.ConfirmEmailAsync(Guid.Parse(validateAttempt.UserId), code);&lt;br /&gt;&lt;br /&gt;            if (result.Succeeded)&lt;br /&gt;            {&lt;br /&gt;                ViewBag.ReturnUrl = validateAttempt.ReturnUrl;&lt;br /&gt;                return View["EmailValidated"];&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            ViewBag.Errors = result.Errors;&lt;br /&gt;            return View["ErrorValidatingEmail"];&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        Post["/{userId}", true] = async (x, ct) =&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            var userId = Guid.Parse(x.userId);&lt;br /&gt;            string code = await _userManager.GenerateEmailConfirmationTokenAsync(userId);&lt;br /&gt;            var baseUrl = Context.Request.Url.SiteBase;&lt;br /&gt;            var encodedCode = &lt;span&gt;HttpUtility&lt;/span&gt;.UrlEncode(code);&lt;br /&gt;&lt;br /&gt;            var callbackUrl = $"{baseUrl}/confirmEmail?userid={userId}&amp;amp;code={encodedCode}";&lt;br /&gt; &lt;br /&gt;            await _userManager.SendEmailAsync(userId,&lt;br /&gt;                "Confirm your email address",&lt;br /&gt;                "Please confirm your email address by clicking &amp;lt;a href=\"" + callbackUrl + "\"&amp;gt;here&amp;lt;/a&amp;gt;");&lt;br /&gt;&lt;br /&gt;           return HttpStatusCode.OK;&lt;br /&gt;       };&lt;br /&gt;    }&lt;br /&gt; }&lt;/pre&gt;
&lt;p&gt;Using &lt;a href="https://www.getpostman.com/" target="_blank"&gt;Postman&lt;/a&gt;&amp;nbsp;to post a userId to the endpoint to send a confirmation URL created the following confimation code&lt;/p&gt;
&lt;pre&gt;frsv1AuYKgDTxcomdt27b/xLiGbzg/pv1k9e6X91B8enQUOIQn4sQ6w/vyZZ4QmIqHVHqMtuFXwbtSJoXKByKkTf7pM1EAftRwwJ2z3BZ/g61NLAhJQ5f8y8NcS+b1vR+/4Cs+yni5GiNElTqqtZVj99c1SY+J7Zsp+Ke/YjkVU3Q75eoghFWlZaCnyUAr29&lt;/pre&gt;
&lt;p&gt;And the URL encoded version to send in the email link becomes&lt;/p&gt;
&lt;pre&gt;frsv1AuYKgDTxcomdt27b%2FxLiGbzg%2Fpv1k9e6X91B8enQUOIQn4sQ6w%2FvyZZ4QmIqHVHqMtuFXwbtSJoXKByKkTf7pM1EAftRwwJ2z3BZ%2Fg61NLAhJQ5f8y8NcS%2Bb1vR%2B%2F4Cs%2Byni5GiNElTqqtZVj99c1SY%2BJ7Zsp%2BKe%2FYjkVU3Q75eoghFWlZaCnyUAr29&lt;/pre&gt;
&lt;p&gt;Now after clicking the emailed link, and then URL Decoding the validation code the code that is used for verification becomes&lt;/p&gt;
&lt;pre&gt;frsv1AuYKgDTxcomdt27b/xLiGbzg/pv1k9e6X91B8enQUOIQn4sQ6w/vyZZ4QmIqHVHqMtuFXwbtSJoXKByKkTf7pM1EAftRwwJ2z3BZ/g61NLAhJQ5f8y8NcS b1vR /4Cs yni5GiNElTqqtZVj99c1SY J7Zsp Ke/YjkVU3Q75eoghFWlZaCnyUAr29&lt;/pre&gt;
&lt;p&gt;Where all '+' chars in the original code have been replaced with spaces. Therefore there is an issue with directly URL encoding the Base64 string into a percent-encoded URL safe string. Hoever the &lt;a href="https://en.wikipedia.org/wiki/Base64#URL_applications" target="_blank"&gt;wikipedia article on Base64&lt;/a&gt;&amp;nbsp;states that there is a URL safe variant of Base64, which does not use the percent encoding. A solution to creating URL safe Base64 string has been provided on &lt;a href="http://stackoverflow.com/a/26354677/137405" target="_blank"&gt;Stack Overflow&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Using this sample, we can create a utility to make the Base64 codes URL safe, wihtout needing to generically URL encode a string.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public static class Base64Utility&lt;br /&gt;{&lt;br /&gt;    static readonly char[] padding = { '=' };&lt;br /&gt;&lt;br /&gt;    public static string UrlSafeEncode(this string base64String)&lt;br /&gt;    {&lt;br /&gt;        return base64String.TrimEnd(padding).Replace('+', '-').Replace('/', '_');&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static string UrlSafeDecode(this string urlSafeBase64String)&lt;br /&gt;    {&lt;br /&gt;        string base64String = urlSafeBase64String.Replace('_', '/').Replace('-', '+');&lt;br /&gt;        switch (urlSafeBase64String.Length % 4)&lt;br /&gt;        {&lt;br /&gt;            case 2: base64String += "=="; break;&lt;br /&gt;            case 3: base64String += "="; break;&lt;br /&gt;        }&lt;br /&gt;        return base64String;&lt;br /&gt;    }&lt;br /&gt; }&lt;/pre&gt;
&lt;p&gt;By using this encode utility method, the encoded code that is URL safe for the activation link becomes&lt;/p&gt;
&lt;pre&gt;frsv1AuYKgDTxcomdt27b_xLiGbzg_pv1k9e6X91B8enQUOIQn4sQ6w_vyZZ4QmIqHVHqMtuFXwbtSJoXKByKkTf7pM1EAftRwwJ2z3BZ_g61NLAhJQ5f8y8NcS-b1vR-_4Cs-yni5GiNElTqqtZVj99c1SY-J7Zsp-Ke_YjkVU3Q75eoghFWlZaCnyUAr29&lt;/pre&gt;
&lt;p&gt;and successfully decodes back to the original code generated by Asp.Net Identiy.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;* flickr photo by Gruenewiese86 https://flickr.com/photos/gruenewiese/27682943560 shared under a Creative Commons (BY-ND) license&lt;/p&gt;</description><pubDate>Thu, 29 Sep 2016 00:14:00 GMT</pubDate><guid isPermaLink="true">https://petedavis.io:443/blog/url-encoding-password-reset-or-email-confirmation-tokens</guid></item></channel></rss>