Hossam Barakat2024-01-12T05:49:10+00:00http://www.hossambarakat.netHossam BarakatClient Credentials Grant Flow with Azure AD B2C2020-08-14T00:00:00+00:00http://www.hossambarakat.net/2020/08/14/azure-b2c-client-credentials<p>One of the known limitations of Azure AD B2C is not directly supporting the OAuth 2.0 client credentials grant flow as it is clearly stated in <a href="https://docs.microsoft.com/en-us/azure/active-directory-b2c/application-types#daemonsserver-side-applications">the documentation</a>. The documentation also hint that you can use the OAuth 2.0 client credentials flow because An Azure AD B2C tenant shares some functionality with Azure AD enterprise tenants however there is no details on how to achieve that.</p>
<p>In this post, I will write down how to issue an access token using the OAuth 2.0 client credentials flow and use it invoke a secure API.</p>
<h2 id="register-a-web-application-in-azure-active-directory-b2c">Register a web application in Azure Active Directory B2C</h2>
<ol>
<li>Sign in to the <a href="https://portal.azure.com">Azure portal</a>.</li>
<li>Select the <strong>Directory + Subscription</strong> icon in the portal toolbar, and then select the directory that contains your Azure AD B2C tenant.</li>
<li>In the Azure portal, search for and select <strong>Azure AD B2C</strong>.</li>
<li>Select <strong>App registrations</strong>, and then select <strong>New registration</strong>.</li>
<li>Enter a <strong>Name</strong> for the application. For example, <em>myapp</em>.</li>
<li>Under <strong>Supported account types</strong>, select <strong>Accounts in any organizational directory or any identity provider. For authenticating users with Azure AD B2C</strong>.</li>
<li>Under <strong>Permissions</strong>, select the <em>Grant admin consent to openid and offline_access permissions</em> check box.</li>
<li>Select <strong>Register</strong>.</li>
</ol>
<h2 id="create-a-client-secret">Create a client secret</h2>
<ol>
<li>In the <strong>Azure AD B2C - App registrations</strong> page, select the application you created, for example <em>webapp1</em>.</li>
<li>In the left menu, under <strong>Manage</strong>, select <strong>Certificates & secrets</strong>.</li>
<li>Select <strong>New client secret</strong>.</li>
<li>Enter a description for the client secret in the <strong>Description</strong> box. For example, <em>clientsecret1</em>.</li>
<li>Under <strong>Expires</strong>, select a duration for which the secret is valid, and then select <strong>Add</strong>.</li>
<li>Record the secret’s <strong>Value</strong>. You use this value as the application secret in your application’s code.</li>
</ol>
<h2 id="configure-scope">Configure scope</h2>
<p>Scopes provide a way to govern access to protected resources. You need to set the scope of the application so you can use the application URI to request an access token:</p>
<ol>
<li>Select <strong>App registrations</strong>.</li>
<li>Select the <em>myapp</em> application to open its <strong>Overview</strong> page.</li>
<li>Under <strong>Manage</strong>, select <strong>Expose an API</strong>.</li>
<li>Next to <strong>Application ID URI</strong>, select the <strong>Set</strong> link.</li>
<li>Select <strong>Save</strong>. The full URI is shown, and should be in the format <code class="language-plaintext highlighter-rouge">https://your-tenant-name.onmicrosoft.com/guid</code>. When your application requests an access token for the API, it should add this URI as the prefix for each scope.</li>
</ol>
<h2 id="get-a-token">Get a token</h2>
<p>You can get a token by using the client credentials grant via sending a POST request to the /token Microsoft identity platform endpoint. The following snippet show how to use the excellent <a href="https://www.nuget.org/packages/IdentityModel">IdentityModel library</a> to get a token</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kt">var</span> <span class="n">response</span> <span class="p">=</span> <span class="k">await</span> <span class="n">httpClient</span><span class="p">.</span><span class="nf">RequestClientCredentialsTokenAsync</span><span class="p">(</span><span class="k">new</span> <span class="n">ClientCredentialsTokenRequest</span>
<span class="p">{</span>
<span class="n">Address</span> <span class="p">=</span> <span class="s">"https://login.microsoftonline.com/b2c-tenant.onmicrosoft.com/oauth2/v2.0/token"</span><span class="p">,</span>
<span class="n">ClientId</span> <span class="p">=</span> <span class="s">"application GUID"</span><span class="p">,</span>
<span class="n">ClientSecret</span> <span class="p">=</span> <span class="s">"client secret"</span><span class="p">,</span>
<span class="n">Scope</span> <span class="p">=</span> <span class="s">"https://b2c-tenant.onmicrosoft.com/c0976379-3467-4e8a-8ff9-05f652d1cde2/.default"</span>
<span class="p">});</span>
<span class="kt">var</span> <span class="n">accessToken</span> <span class="p">=</span> <span class="n">response</span><span class="p">.</span><span class="n">AccessToken</span><span class="p">;</span>
</code></pre></div></div>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">Address</code></td>
<td>The token endpoint of the directory tenant that you want to request permission from. Make sure to replace <code class="language-plaintext highlighter-rouge">b2c-tenant</code> with your directory name.</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">client_id</code></td>
<td>The <strong>Application (client) ID</strong> that has been assigned to your app.</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">client_secret</code></td>
<td>The client secret that you generated for your app in the app registration portal.</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">Scope</code></td>
<td>The value passed for the scope parameter in this request should be the Application ID URI that was configured in “Configure scope” step, affixed with the .default suffix. Make sure to replace <code class="language-plaintext highlighter-rouge">b2c-tenant</code> with your directory name.</td>
</tr>
</tbody>
</table>
<h2 id="secure-aspnet-core-api">Secure ASP.NET Core API</h2>
<p>Now that you have the access token, you can invoke a remote API with the <code class="language-plaintext highlighter-rouge">Authorization</code> header holding the access token but how would you make sure that the API accepts this token.</p>
<p>Securing ASP.NET Core API with JWT tokens is straightforward. You can use the Middleware that exists in the <code class="language-plaintext highlighter-rouge">Microsoft.AspNetCore.Authentication.JwtBearer</code> package by calling <code class="language-plaintext highlighter-rouge">AddAuthentication</code> and <code class="language-plaintext highlighter-rouge">AddJwtBearer</code> in the <code class="language-plaintext highlighter-rouge">ConfigureServices</code> of the <code class="language-plaintext highlighter-rouge">Startup</code> class</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">services</span><span class="p">.</span><span class="nf">AddAuthentication</span><span class="p">(</span><span class="n">JwtBearerDefaults</span><span class="p">.</span><span class="n">AuthenticationScheme</span><span class="p">)</span>
<span class="p">.</span><span class="nf">AddJwtBearer</span><span class="p">(</span><span class="n">options</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">options</span><span class="p">.</span><span class="n">Audience</span> <span class="p">=</span> <span class="s">"Application (client) ID"</span><span class="p">;</span>
<span class="n">options</span><span class="p">.</span><span class="n">Authority</span> <span class="p">=</span> <span class="s">"https://login.microsoftonline.com/<tenant GUID>"</span><span class="p">;</span>
<span class="n">options</span><span class="p">.</span><span class="n">TokenValidationParameters</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Microsoft</span><span class="p">.</span><span class="n">IdentityModel</span><span class="p">.</span><span class="n">Tokens</span><span class="p">.</span><span class="n">TokenValidationParameters</span>
<span class="p">{</span>
<span class="n">ValidAudience</span> <span class="p">=</span> <span class="s">"Application (client) ID"</span><span class="p">;</span>
<span class="n">ValidIssuer</span> <span class="p">=</span> <span class="s">"https://login.microsoftonline.com/<tenant GUID>/v2.0"</span>
<span class="p">};</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Then, in the <code class="language-plaintext highlighter-rouge">Configure</code> method, add <code class="language-plaintext highlighter-rouge">UseAuthentication</code>:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">app</span><span class="p">.</span><span class="nf">UseAuthentication</span><span class="p">();</span>
</code></pre></div></div>
<p>I always forget adding <code class="language-plaintext highlighter-rouge">UseAuthentication()</code> so make sure that you didn’t forget to add it to your class :).</p>
<p>Finally, Add the [Authorize] attribute on the controllers or action methods that you want to secure:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">HttpGet</span><span class="p">]</span>
<span class="p">[</span><span class="n">Authorize</span><span class="p">]</span>
<span class="k">public</span> <span class="kt">string</span> <span class="nf">Secure</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="s">"secure api response"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="secure-apinet-core-api-with-tokens-issued-by-other-oauth-20-flows">Secure API.NET Core API with tokens issued by other OAuth 2.0 flows</h2>
<p>You might be wondering how to get your API to accept tokens issued by other OAuth 2.0 flows like OAuth 2.0 with PKCE. ASP.NET Core can accept multiple authentication methods by adding another <code class="language-plaintext highlighter-rouge">AddJwtBearer</code> in your <code class="language-plaintext highlighter-rouge">ConfigureServices</code> method.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">services</span><span class="p">.</span><span class="nf">AddAuthentication</span><span class="p">(</span><span class="n">JwtBearerDefaults</span><span class="p">.</span><span class="n">AuthenticationScheme</span><span class="p">)</span>
<span class="p">.</span><span class="nf">AddJwtBearer</span><span class="p">(</span><span class="n">options</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">options</span><span class="p">.</span><span class="n">Authority</span> <span class="p">=</span> <span class="s">$"https://my-b2c-tenant.b2clogin.com/my-b2c-tenant.onmicrosoft.com/SignUpSignInPolicyId/v2.0"</span><span class="p">;</span>
<span class="n">options</span><span class="p">.</span><span class="n">Audience</span> <span class="p">=</span> <span class="s">"api app client GUID"</span><span class="p">;</span>
<span class="p">})</span>
<span class="p">.</span><span class="nf">AddJwtBearer</span><span class="p">(</span><span class="s">"AzureAD"</span><span class="p">,</span> <span class="n">options</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">options</span><span class="p">.</span><span class="n">Audience</span> <span class="p">=</span> <span class="s">"Application (client) ID"</span><span class="p">;</span>
<span class="n">options</span><span class="p">.</span><span class="n">Authority</span> <span class="p">=</span> <span class="s">"https://login.microsoftonline.com/<tenant GUID>"</span><span class="p">;</span>
<span class="n">options</span><span class="p">.</span><span class="n">TokenValidationParameters</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Microsoft</span><span class="p">.</span><span class="n">IdentityModel</span><span class="p">.</span><span class="n">Tokens</span><span class="p">.</span><span class="n">TokenValidationParameters</span>
<span class="p">{</span>
<span class="n">ValidAudience</span> <span class="p">=</span> <span class="s">"Application (client) ID"</span><span class="p">;</span>
<span class="n">ValidIssuer</span> <span class="p">=</span> <span class="s">"https://login.microsoftonline.com/<tenant GUID>/v2.0"</span>
<span class="p">};</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Then, You update your controllers or action method <code class="language-plaintext highlighter-rouge">Authorize</code> attribute to define the <code class="language-plaintext highlighter-rouge">AuthenticationSchemes</code></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">HttpGet</span><span class="p">]</span>
<span class="p">[</span><span class="nf">Authorize</span><span class="p">(</span><span class="n">AuthenticationSchemes</span> <span class="p">=</span>
<span class="n">JwtBearerDefaults</span><span class="p">.</span><span class="n">AuthenticationScheme</span><span class="p">)]</span>
<span class="k">public</span> <span class="kt">string</span> <span class="nf">Secure</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="s">"secure api response"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>If you don’t like specifying the <code class="language-plaintext highlighter-rouge">AuthenticationSchemes</code> on controllers or action methods and would like to accept both authentication schemes by updating the default authorization policy:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">services</span><span class="p">.</span><span class="nf">AddAuthorization</span><span class="p">(</span><span class="n">options</span> <span class="p">=></span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">defaultAuthorizationPolicyBuilder</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">AuthorizationPolicyBuilder</span><span class="p">(</span>
<span class="n">JwtBearerDefaults</span><span class="p">.</span><span class="n">AuthenticationScheme</span><span class="p">,</span>
<span class="s">"AzureAD"</span><span class="p">);</span>
<span class="n">defaultAuthorizationPolicyBuilder</span> <span class="p">=</span> <span class="n">defaultAuthorizationPolicyBuilder</span><span class="p">.</span><span class="nf">RequireAuthenticatedUser</span><span class="p">();</span>
<span class="n">options</span><span class="p">.</span><span class="n">DefaultPolicy</span> <span class="p">=</span> <span class="n">defaultAuthorizationPolicyBuilder</span><span class="p">.</span><span class="nf">Build</span><span class="p">();</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Congratulations, You know how to issue an access token with Azure AD B2C Client Credentials grant flow and how to use it to call a secure ASP.NET Core API.</p>
<h2 id="references">References</h2>
<ol>
<li><a href="https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga">Register a web application in Azure Active Directory B2C</a></li>
<li><a href="https://docs.microsoft.com/en-us/azure/active-directory-b2c/add-web-api-application?tabs=app-reg-ga">Add a web API application to your Azure Active Directory B2C tenant</a></li>
<li><a href="https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1">Authorize with a specific scheme in ASP.NET Core</a></li>
</ol>
Fix error NU1101: Unable to find package. No packages exist with this id in source(s): Microsoft Visual Studio Offline Packages2020-06-24T00:00:00+00:00http://www.hossambarakat.net/2020/06/24/fix-error-NU1101<p>I use Azure DevOps as my build pipelines for a lot of projects, I have faced the following error recently:</p>
<blockquote>
<p>Unable to find package AutoFixture. No packages exist with this id in source(s): Microsoft Visual Studio Offline Packages</p>
</blockquote>
<p>I found that there are two easy ways to fix this error hence I am writing them here as self-reminder for the solutions.</p>
<h2 id="option-a-add-nugetconfig">Option A: Add nuget.config</h2>
<p>Add a nuget.config to the solution directory with resolve the issue</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><?xml version="1.0" encoding="utf-8"?></span>
<span class="nt"><configuration></span>
<span class="nt"><packageSources></span>
<span class="nt"><add</span> <span class="na">key=</span><span class="s">"nuget.org"</span> <span class="na">value=</span><span class="s">"https://api.nuget.org/v3/index.json"</span> <span class="na">protocolVersion=</span><span class="s">"3"</span> <span class="nt">/></span>
<span class="nt"></packageSources></span>
<span class="nt"></configuration></span>
</code></pre></div></div>
<h2 id="option-b-add-restore-packages-step-to-the-build-pipeline">Option B: Add Restore Packages step to the build pipeline</h2>
<p>Add the following dotnet restore step to the build pipeline with <code class="language-plaintext highlighter-rouge">includeNuGetOrg: true</code> would resolve the issue</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">task</span><span class="pi">:</span> <span class="s">DotNetCoreCLI@2</span>
<span class="na">displayName</span><span class="pi">:</span> <span class="s">dotnet restore</span>
<span class="na">inputs</span><span class="pi">:</span>
<span class="na">command</span><span class="pi">:</span> <span class="s">restore</span>
<span class="na">projects</span><span class="pi">:</span> <span class="s1">'</span><span class="s">$(serviceLocation)/**/*.csproj'</span>
<span class="na">includeNuGetOrg</span><span class="pi">:</span> <span class="no">true</span>
</code></pre></div></div>
<p>Remember to add the private package feeds if you are using any.</p>
<p>I hope that helps.</p>
Microservices and Istio Service Mesh - Sydney Alt.Net2019-02-26T00:00:00+00:00http://www.hossambarakat.net/2019/02/26/microservices-with-istio-service-mesh-sydney-alt-dot-net<p>Today, I have presented a talk about microservices and Istio service mesh at Sydney Alt.Net User Group.</p>
<p>In this talk I have covered what is Istio service mesh, what kind of problems it solves, and how to leverage Istio traffic routing, reliability and observability features.</p>
<p>The Slides are availabe from https://speakerdeck.com/hossambarakat/empower-your-microservices-with-istio-service-mesh-sydney-alt-dot-net</p>
<blockquote class="embedly-card"><h4><a href="https://speakerdeck.com/hossambarakat/empower-your-microservices-with-istio-service-mesh-sydney-alt-dot-net">Empower Your Microservices with Istio Service Mesh - Sydney Alt.Net</a></h4><p>null</p></blockquote>
<script async="" src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script>
<p>The resources:</p>
<ul>
<li><a href="https://github.com/hossambarakat/EspressoShop">EspressoShop Sample</a></li>
<li><a href="https://istio.io/docs/">Istio Documentation</a></li>
<li><a href="https://katacoda.com/courses/istio">Learn Istio using Interactive Hands-on Scenarios (Katacoda)</a></li>
</ul>
Sharing Code Among Microservices2017-11-27T00:00:00+00:00http://www.hossambarakat.net/2017/11/27/sharing-code-among-microservices<p>Building microservices will always lead to a situation where you have certain functionality to be implemented in multiple services. As developers, we try to apply the DRY mantra by building shared libraries which is fine but shared libraries could lead to more complexities depending how we build and share them.</p>
<h2 id="inheritance">Inheritance</h2>
<p>There are features we assume each service has to have such as request validation, user authorization or request throttling. Since each service has to provide them we start thinking of creating a class called <code class="language-plaintext highlighter-rouge">BaseService</code> that all services must <strong>inherit</strong> from.</p>
<p>Inheriting from base service might not be a good idea:</p>
<ul>
<li>It contradicts with the technology heterogeneity principle because each service should use the right technology to solve the business problem.</li>
<li>Services development becomes coupled to the shared code so if one service requires upgrading the <code class="language-plaintext highlighter-rouge">BaseService</code> to fix a bug or add a new feature that could lead to updating all the services even if not required. Moreover, the upgrade would require large coordination between multiple teams.</li>
<li>Teams starts to avoid changing the shared code because:
<ul>
<li>Fear to break other services.</li>
<li>Required effort to coordinate with all team to upgrade the library and rollout the change.</li>
<li>Testing the change might require running tests for all the services.</li>
</ul>
</li>
<li>Usually shared code is owned by all teams which means no one will be doing housekeeping tasks such as removing technical debt, upgrading the libraries, …</li>
</ul>
<h2 id="composition">Composition</h2>
<p>On the flip side, we could deal with that common code as a 3rd party packages (nuget, npm, …) where each package targets a specific feature. The packages should be published and consumed by any service without any inheritance.</p>
<p>Publishing shared code as 3rd party package will help:</p>
<ul>
<li>Aligning with technology heterogeneity and will improve the coupling as each service might or might not consumer the service</li>
<li>Developers might be more encouraged to update the shared code because the package surface area is small which means small impact.</li>
<li>Less time and effort to change because only consumer will decide when to upgrade to the latest version.</li>
</ul>
<h2 id="few-things-to-consider-for-your-packages">Few things to consider for your packages:</h2>
<ul>
<li>You should have versioning from day one, consider using <a href="https://semver.org">Semantic Versioning</a>.</li>
<li>Please write a documentation on how to use the library streamline consuming and maintaining the library.</li>
<li>Encourage everyone to add features and fix bugs in the shared library given that you follow the versioning process.</li>
<li>Updating to the latest version of the package should be the consumer service responsibility.</li>
</ul>
<h2 id="in-closing">In Closing</h2>
<p>In context of microservices, shared code for common functionalities has its place but I would recommend avoiding having base classes that all services must inherit from. Always deal with your shared code as 3rd party package.</p>
Microservices Coupling With Synchronous Integration2017-11-11T00:00:00+00:00http://www.hossambarakat.net/2017/11/11/microservices-coupling-with-synchronous-integration<p>A lot of companies have started the journey of splitting their current monolithic applications into Microservices to gain all the benefits from Microservices such as strong module boundaries, independent deployment, hybrid technologies… which is fine, but what I am concerned about the assumption of splitting monolothic application to microservice will automatically lead to a loosely coupled services.</p>
<p>Let’s start with a simple piece of code handles purchasing command that includes create an order, then start the shipping process:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">PurchaseCommand</span>
<span class="p">{</span>
<span class="k">public</span> <span class="n">List</span><span class="p"><</span><span class="n">OrderItem</span><span class="p">></span> <span class="n">Items</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="n">Address</span> <span class="n">ShippingAddress</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="c1">//rest of command properties</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">PurchaseCommandHandler</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Handle</span><span class="p">(</span><span class="n">PurchaseCommand</span> <span class="n">command</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">using</span><span class="p">(</span><span class="kt">var</span> <span class="n">transactionScope</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TransactionScope</span><span class="p">())</span>
<span class="p">{</span>
<span class="nf">SaveOrderInDB</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
<span class="nf">SaveShippingInDB</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Now, we decide that this code should be split into two microservices “Orders” and “Shipping” and each one will be hosted in a separate process. but how the two microservices will communicate to each other?</p>
<h2 id="rest">REST</h2>
<p>Usually the answer is using REST for integration between services, so the “Shipping” service will expose an end point that could be called by “Orders” service:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//Shipping Service</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">StartShippingCommand</span>
<span class="p">{</span>
<span class="k">public</span> <span class="n">Guid</span> <span class="n">OrderId</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="n">List</span><span class="p"><</span><span class="n">OrderItem</span><span class="p">></span> <span class="n">Items</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">StartShippingCommandHandler</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Handle</span><span class="p">(</span><span class="n">StartShippingCommand</span> <span class="n">command</span><span class="p">)</span>
<span class="p">{</span>
<span class="nf">SaveShippingInDB</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The orders service will be updated to make a call to the shipping endpoint:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//Orders Service</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">PurchaseCommandHandler</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Handle</span><span class="p">(</span><span class="n">PurchaseCommand</span> <span class="n">command</span><span class="p">)</span>
<span class="p">{</span>
<span class="nf">SaveOrderInDB</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">shippingServiceProxy</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">ShippingServiceProxy</span><span class="p">();</span>
<span class="n">shippingServiceProxy</span><span class="p">.</span><span class="nf">StartShipping</span><span class="p">(</span><span class="k">new</span> <span class="nf">StartShippingCommand</span><span class="p">(){});</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>So we managed to split the code into two separate services that could be deployed independently…but are the services loosely coupled?</p>
<blockquote>
<p><em>Autonomous</em> microservice is a service that can respond to client requests regardless of the availablity of other services…to an extent.</p>
</blockquote>
<h3 id="what-will-happen-if-the-shipping-service-is-not-available">What will happen if the shipping service is not available?</h3>
<p>The orders service will save the order in the DB but will fail while calling the shipping and the whole purchase will fail, moreover our database will be left with data inconsistencies.</p>
<p>So, Although the “Orders” and “Shipping” services are now hosted in two separate processes they are still coupled because the “Orders” service will not be able to serve the client request unless the “Shipping” service is available.</p>
<p>So how could we remove the coupling?</p>
<h2 id="event-driven-integration">Event-Driven Integration</h2>
<p>Event-driven integration means the communication between services done though events, service will publish an event when something notable happens and then other services could subscribe to the event and do its own logic which could result in publishing more events.</p>
<p>So in our scenario, Event-driven integrations means that “Orders” service will save the order in the database then public an event <code class="language-plaintext highlighter-rouge">OrderAccepted</code>, the “Shipping” service will subscribe to <code class="language-plaintext highlighter-rouge">OrderAccepted</code> event and will save the shipping information in the database:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//Orders Service</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">OrderAccepted</span>
<span class="p">{</span>
<span class="k">public</span> <span class="n">Guid</span> <span class="n">OrderId</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="n">List</span><span class="p"><</span><span class="n">OrderItem</span><span class="p">></span> <span class="n">Items</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">PurchaseCommandHandler</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Handle</span><span class="p">(</span><span class="n">PurchaseCommand</span> <span class="n">command</span><span class="p">)</span>
<span class="p">{</span>
<span class="nf">SaveOrderInDB</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
<span class="n">Bus</span><span class="p">.</span><span class="nf">Publish</span><span class="p">(</span><span class="k">new</span> <span class="n">OrderAccepted</span>
<span class="p">{</span>
<span class="n">OrderId</span> <span class="p">=</span> <span class="n">OrderId</span><span class="p">,</span>
<span class="n">Items</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p"><</span><span class="n">OrderItem</span><span class="p">>(</span><span class="n">command</span><span class="p">.</span><span class="n">Items</span><span class="p">)</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">//Shipping Service</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">StartShippingCommandHandler</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Handle</span><span class="p">(</span><span class="n">OrderAccepted</span> <span class="n">@event</span><span class="p">)</span>
<span class="p">{</span>
<span class="nf">SaveShippingInDB</span><span class="p">(</span><span class="n">@event</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The “Shipping” service could publish another event called <code class="language-plaintext highlighter-rouge">ShippingStarted</code> so “Orders” service could update the the order status.</p>
<h3 id="again-what-will-happen-if-the-shipping-service-unavailable">Again, what will happen if the “Shipping” service unavailable?</h3>
<p>The “Orders” service now can serve the requests while “Shipping” service is down because it can save the data in database then publish an event and respond immediately to the client. the published <code class="language-plaintext highlighter-rouge">OrdeAccepted</code> event will be processed by the “Shipping” service whenever it is available.</p>
<p>Ofcourse that is assuming that the events has been published successfully inside the bus/queue.</p>
<h2 id="summary">Summary</h2>
<p>Decomposing a monolithic application into a set of services hosted in different processes doesn’t guarantee having a loosely coupled microservices. Synchronous communication between microservices will lead to a more coupled microservices however using asynchronous event-driven communication will help in leading to more autonomous loosely coupled microservices.</p>
Microservices Monitoring Practical Tips2017-06-14T00:00:00+00:00http://www.hossambarakat.net/2017/06/14/microservices-monitoring-practical-tips<p>During the development of microservices we keep our focus on the architecture of each microservice, integration between microservices, defining the boundery for each service,… however we tend to forget about how we are going to monitor those service after deployment to production.</p>
<p>I have found that two main tips helped me in my implementation:</p>
<h3 id="centralized-structured-logging">Centralized Structured Logging</h3>
<p>Each microservice could be hosted on a separate node(s) and each request coming into the system may require communicating with other microservices so when you have a bug (I know it is rare situation :P) having the logs on each node would make diagnosing of bug very difficult.</p>
<p><strong>Structured logging</strong> is technique which is using a consistent, predetermined message format containing semantic information. So in each message we can include service name, server ip, user id,… and then query the logs using those fields so I can find all log messages related to specific user, also you build aggregates views such as number of error messages per server.</p>
<p>There are a lot of tools available such as <a href="https://www.elastic.co/products/elasticsearch">ElasticSearch</a> and <a href="https://getseq.net">Seq</a>.</p>
<h3 id="use-of-correlation-id">Use of Correlation ID</h3>
<p>Any request coming into the system might result in communication between different microservices that are hosted on different nodes. This means that bug investigation requires reading all logs generated from all microservices relevant to the failed request. I have found an easy solution was correlating log entries relevant to specific request using correlation id.</p>
<p>Once a request enters the system, I assign a correlation to it and keep passing that correlation id to all microservices, then I use that correlation id in all log entries and with the structured logging I can search for specific request using its correlation id.</p>
<p>But how I would know the correlation id of a request? I add the correlation Id to the response headers of my request, this was very handy specially when testers found a bug, they report it with correlation id of the failed request and thanks to structured logging I can trace it back and diagnose what went wrong.</p>
Running Mocha with TypeScript2017-06-01T00:00:00+00:00http://www.hossambarakat.net/2017/06/01/running-mocha-with-typescript<p>I was working on proof-of-concept to TypeScript with Mocha and I wanted to share my learning.</p>
<p>I was working on proof-of-concept to use TypeScript with Mocha. My objective was building a project where both the source and the tests written in TypeScript, executing tests using npm scripts and gulp and finally with a good debugging experience in both Visual Studio code and Web Storm.</p>
<p>TL;DR, Find the working sample <a href="http://github.com/hossambarakat/mocha-with-typescript">here</a></p>
<h2 id="project-skeleton">Project Skeleton</h2>
<p>The first step is to create an empty project directory and run <code class="language-plaintext highlighter-rouge">npm init</code> inside of it, then create two folders <code class="language-plaintext highlighter-rouge">src</code> and <code class="language-plaintext highlighter-rouge">test</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- src
- test
package.json
</code></pre></div></div>
<h2 id="installing-typescript">Installing TypeScript</h2>
<p>The project will written in TypeScript so let’s start by installing the typescript package:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install </span>typescript <span class="nt">--save-dev</span>
</code></pre></div></div>
<p>The TypeScript uses a file called <code class="language-plaintext highlighter-rouge">tsconfig.json</code> in the root directory of the solution to define the compiler options so add new file to the root directory with the following content.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"compilerOptions"</span><span class="p">:{</span><span class="w">
</span><span class="nl">"module"</span><span class="p">:</span><span class="w"> </span><span class="s2">"commonjs"</span><span class="p">,</span><span class="w">
</span><span class="nl">"sourceMap"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"target"</span><span class="p">:</span><span class="w"> </span><span class="s2">"es2015"</span><span class="p">,</span><span class="w">
</span><span class="nl">"isolatedModules"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>You can read more about the tsconfig <a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html">here</a></p>
<h2 id="the-calculator">The Calculator</h2>
<p>The project will be a simple calculator that can add two numbers. Add new file called <code class="language-plaintext highlighter-rouge">Calculator.ts</code> inside the <code class="language-plaintext highlighter-rouge">src</code> folder. The source code that we are going to test will be simple <code class="language-plaintext highlighter-rouge">Calculator</code> class with one method <code class="language-plaintext highlighter-rouge">add</code>:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">default</span> <span class="kd">class</span> <span class="nx">Calculator</span>
<span class="p">{</span>
<span class="k">public</span> <span class="nx">Add</span><span class="p">(</span><span class="nx">a</span> <span class="p">:</span><span class="kr">number</span><span class="p">,</span><span class="nx">b</span><span class="p">:</span><span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="the-test">The Test</h2>
<p>The tests will be written in <a href="http://mochajs.org">Mocha</a> and the assertions will be done using <a href="http://chaijs.com">Chai</a> so let’s start by installing them</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install </span>mocha <span class="nt">--save-dev</span>
npm <span class="nb">install </span>chai <span class="nt">--save-dev</span>
</code></pre></div></div>
<p>Now proceed with creating a new file called <code class="language-plaintext highlighter-rouge">calculator.spec.ts</code> inside the <code class="language-plaintext highlighter-rouge">test</code> directory:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">expect</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">chai</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">Calculator</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../src/calculator</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">Calculator</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">Add</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">it</span><span class="p">(</span><span class="dl">"</span><span class="s2">Should return 3 when a = 1 and b = 2</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">calc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Calculator</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">calc</span><span class="p">.</span><span class="nx">Add</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">);</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">})</span>
<span class="p">});</span>
</code></pre></div></div>
<h2 id="running-the-tests">Running the tests</h2>
<p>I’d like to be able to run the test through npm scripts as well as using gulps but first we need to install another package in order to be able to use Mocha with TypeScript:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install </span>ts-node <span class="nt">--save-dev</span>
</code></pre></div></div>
<blockquote>
<p>TypeScript Node is TypeScript execution environment and REPL for node</p>
</blockquote>
<h3 id="npm-scripts">NPM Scripts</h3>
<p>Update the <code class="language-plaintext highlighter-rouge">package.json</code> scripts section:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"scripts"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"test"</span><span class="p">:</span><span class="w"> </span><span class="s2">"./node_modules/.bin/mocha --compilers ts:ts-node/register ./test/*.spec.ts"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>As you noticed in the above script we used the <code class="language-plaintext highlighter-rouge">--compilers</code> parameter to use the ts-node module to compile the TypeScript files.</p>
<p>Now you should be able to run the tests from command line:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">test</span>
</code></pre></div></div>
<p>The following result should be shown on your command window</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Calculator
Add
✓ Should <span class="k">return </span>3 when a <span class="o">=</span> 1 and b <span class="o">=</span> 2
1 passing <span class="o">(</span>6ms<span class="o">)</span>
</code></pre></div></div>
<h3 id="gulp">Gulp</h3>
<p>We need to install two more packages to be able to use Gulp:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install </span>gulp <span class="nt">--save-dev</span>
npm <span class="nb">install </span>gulp-mocha <span class="nt">--save-dev</span>
</code></pre></div></div>
<p>Then adding <code class="language-plaintext highlighter-rouge">gulpfile.js</code> to the root directory:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">gulp</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">gulp</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">mocha</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">gulp-mocha</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="dl">'</span><span class="s1">run-tests</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(){</span>
<span class="k">return</span> <span class="nx">gulp</span><span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="dl">'</span><span class="s1">test/*.spec.ts</span><span class="dl">'</span><span class="p">)</span>
<span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">mocha</span><span class="p">({</span>
<span class="na">reporter</span><span class="p">:</span> <span class="dl">'</span><span class="s1">nyan</span><span class="dl">'</span><span class="p">,</span>
<span class="na">require</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">ts-node/register</span><span class="dl">'</span><span class="p">]</span>
<span class="p">}));</span>
<span class="p">});</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="dl">'</span><span class="s1">default</span><span class="dl">'</span><span class="p">,</span> <span class="p">[</span> <span class="dl">'</span><span class="s1">run-tests</span><span class="dl">'</span> <span class="p">]);</span>
</code></pre></div></div>
<p>You can run the tests using gulp by running <code class="language-plaintext highlighter-rouge">gulp</code> command and you should see the output similar to the following:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>22:16:05] Using gulpfile ~/My files/Temp/mocha-with-typescript/gulpfile.js
<span class="o">[</span>22:16:05] Starting <span class="s1">'run-tests'</span>...
1 <span class="nt">-__</span>,------,
0 <span class="nt">-__</span>| /<span class="se">\_</span>/<span class="se">\ </span>
0 <span class="nt">-_</span>~|_<span class="o">(</span> ^ .^<span class="o">)</span>
<span class="nt">-_</span> <span class="s2">""</span> <span class="s2">""</span>
1 passing <span class="o">(</span>8ms<span class="o">)</span>
<span class="o">[</span>22:16:06] Finished <span class="s1">'run-tests'</span> after 605 ms
<span class="o">[</span>22:16:06] Starting <span class="s1">'default'</span>...
<span class="o">[</span>22:16:06] Finished <span class="s1">'default'</span> after 8.96 μs
</code></pre></div></div>
<h2 id="debugging">Debugging</h2>
<h3 id="visual-studio-code">Visual Studio Code</h3>
<p>You can debug TypeScript tests inisde visual studio using node debug configurations with V8 inspector protocol, You can set the V8 inspect protocol by setting <code class="language-plaintext highlighter-rouge">protocol</code> to <code class="language-plaintext highlighter-rouge">inspect</code>:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Run mocha"</span><span class="p">,</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"node"</span><span class="p">,</span><span class="w">
</span><span class="nl">"request"</span><span class="p">:</span><span class="w"> </span><span class="s2">"launch"</span><span class="p">,</span><span class="w">
</span><span class="nl">"program"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${workspaceRoot}/node_modules/mocha/bin/_mocha"</span><span class="p">,</span><span class="w">
</span><span class="nl">"stopOnEntry"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"args"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"--no-timeouts"</span><span class="p">,</span><span class="w"> </span><span class="s2">"--compilers"</span><span class="p">,</span><span class="w"> </span><span class="s2">"ts:ts-node/register"</span><span class="p">,</span><span class="w"> </span><span class="s2">"${workspaceRoot}/test/**/*.spec.ts"</span><span class="p">],</span><span class="w">
</span><span class="nl">"cwd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${workspaceRoot}"</span><span class="p">,</span><span class="w">
</span><span class="nl">"protocol"</span><span class="p">:</span><span class="w"> </span><span class="s2">"inspector"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="web-storm">Web Storm</h3>
<p>You can debug the TypeScript tests inside Web Storm by using the normal Mocha configuration but remember to include <code class="language-plaintext highlighter-rouge">--require ts-node/register</code> in the <code class="language-plaintext highlighter-rouge">Extra Mocha options</code> field:</p>
<p><img src="/assets/2017-06-01-running-mocha-with-typescript/webstorm-config.png" alt="" /></p>
Configure Serilog With SQL Server Sink Inside ASP.NET Core2016-12-04T00:00:00+00:00http://www.hossambarakat.net/2016/12/04/configure-serilog-with-sql-server-sink-inside-aspnet-core<p>ASP.NET Core configuration has been re-architected and doesn’t depend on Xml configurations any more, check <a href="http://docs.asp.net/en/latest/fundamentals/configuration.html">this excellent article</a> for an introduction about the new configuration system.</p>
<p>In order to use Serilog with SQL Server Sink follow the below steps:</p>
<h2 id="step1-update-the-projectjson">Step1: Update the project.json</h2>
<p>Update the project.json to reference the <code class="language-plaintext highlighter-rouge">Serilog</code> and <code class="language-plaintext highlighter-rouge">Serilog.Sinks.MSSqlServer</code> packages by adding the following lines at the end of the dependencies section.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"Serilog"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.5.14"</span><span class="err">,</span><span class="w">
</span><span class="nl">"Serilog.Sinks.MSSqlServer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3.0.48"</span><span class="w">
</span></code></pre></div></div>
<h2 id="step-2-add-serilog-sql-server-sink-settings-into-appsettingsjson">Step 2: Add Serilog SQL Server Sink settings into appsettings.json</h2>
<p>Update <code class="language-plaintext highlighter-rouge">appsettings.json</code> file to include all the required Serilog SQL Server Sink configuration by adding the following JSON at the end of the appsettings.json file and before the last closing curly braces, make sure to update the connection string to your relevant values.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"Serilog"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"ConnectionString"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Server=(local);Database=serilogdemo;trusted_connection=true"</span><span class="p">,</span><span class="w">
</span><span class="nl">"TableName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Logs"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h2 id="step-3-update-the-startup-class-to-configure-serilogilogger">Step 3: Update the Startup class to configure Serilog.ILogger</h2>
<p>ASP.NET Core has a new builtin Dependency Injection feature that can be used by registering the services and their implementations through the <code class="language-plaintext highlighter-rouge">ConfigureServices</code> method inside <code class="language-plaintext highlighter-rouge">Startup</code> class so add the following section add the end of the <code class="language-plaintext highlighter-rouge">ConfigureServices</code> method. The <a href="http://docs.asp.net/en/latest/fundamentals/dependency-injection.html">Dependency Injection</a> feature provide three types of registrations <em>Transient</em> , <em>Scoped</em> and <em>Singleton</em> and for this question I have used Singleton just for demo purpose.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">services</span><span class="p">.</span><span class="n">AddSingleton</span><span class="p"><</span><span class="n">Serilog</span><span class="p">.</span><span class="n">ILogger</span><span class="p">>(</span><span class="n">x</span><span class="p">=></span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">LoggerConfiguration</span><span class="p">().</span><span class="n">WriteTo</span><span class="p">.</span><span class="nf">MSSqlServer</span><span class="p">(</span><span class="n">Configuration</span><span class="p">[</span><span class="s">"Serilog:ConnectionString"</span><span class="p">],</span> <span class="n">Configuration</span><span class="p">[</span><span class="s">"Serilog:TableName"</span><span class="p">],</span><span class="n">autoCreateSqlTable</span><span class="p">:</span><span class="k">true</span><span class="p">).</span><span class="nf">CreateLogger</span><span class="p">();</span>
<span class="p">});</span>
</code></pre></div></div>
<p>As you can see, the nested JSON configurations inside the appsettings.json could be read used the property <code class="language-plaintext highlighter-rouge">Configuration</code> and the configuration values can be retrieved using <code class="language-plaintext highlighter-rouge">:</code> as separator.</p>
<p>Note the above code is using <code class="language-plaintext highlighter-rouge">autoCreateSqlTable</code> parameter to automatically create the log table if doesn’t exist; if you don’t like this approach you can use sql script to create the table at any step you like.</p>
<p>##Step 4: Get reference to the Serilog.ILogger
You can get instance of the Serilog.ILogger via the Dependency Injection feature by simply adding variable in your constructor with object of the type Serilog.ILogger and then use the instance in any action method</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">private</span> <span class="n">Serilog</span><span class="p">.</span><span class="n">ILogger</span> <span class="n">_logger</span><span class="p">;</span>
<span class="k">public</span> <span class="nf">HomeController</span><span class="p">(</span><span class="n">Serilog</span><span class="p">.</span><span class="n">ILogger</span> <span class="n">logger</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="n">_logger</span> <span class="p">=</span> <span class="n">logger</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
Integrating Azure Active Directory B2C into Xamarin Mobile App2016-07-07T00:00:00+00:00http://www.hossambarakat.net/2016/07/07/integrating-azure-active-directory-b2c-into-xamarin-mobile-app<p>When building mobile apps, it’s often required to add authentication to protect the app’s content. Authentication could be through social identity providers like Facebook, Amazon, LinkedIn, etc or through application based credentials. <a href="https://azure.microsoft.com/en-us/services/active-directory-b2c/">Azure Active Directory Business to Consumer (Azure AD B2C)</a> provides adding identity management functions into application with little coding.</p>
<p>I will explain how to add customer credentials authentication into Xamarin Forms mobile app targeting iOS and Android using Azure Active Directory B2C:</p>
<ul>
<li><a href="#configuring-azure-ad-b2c-tenant">Configuring Azure AD B2C tenant</a></li>
<li><a href="#create-azure-ad-b2c-tenant">Create Azure AD B2C tenant</a></li>
<li><a href="#register-application-into-the-tenant">Register application into the tenant</a></li>
<li><a href="#configure-sign-up-sign-in-policy">Configure sign-up/sign-in policy</a></li>
<li><a href="#building-xamarin-forms-application">Building Xamarin Forms application</a></li>
<li><a href="#empty-app">Empty App</a></li>
<li><a href="#welcome-screen">Welcome Screen</a></li>
<li><a href="#sign-in-register">Sign in/Register</a></li>
<li><a href="#secure-page">Secure Page</a></li>
<li><a href="#sign-out">Sign out</a></li>
</ul>
<h2 id="configuring-azure-ad-b2c-tenant"><a id="configuring-azure-ad-b2c-tenant"></a>Configuring Azure AD B2C Tenant</h2>
<p>To start using Azure AD B2C, you have to create a new tenant</p>
<h3 id="create-a-new-directory"><a id="create-azure-ad-b2c-tenant"></a>Create a new directory</h3>
<ol>
<li>Log in to the <a href="https://manage.windowsazure.com/">Azure portal</a>.</li>
<li>Click New.</li>
<li>Click App Services > Active Directory > Directory > Custom create > Create and manage a new Microsoft Azure AD directory.</li>
<li>Complete the fields of the add directory page:</li>
</ol>
<p><img src="/assets/integrating-azure-b2c/Create-Active-Directory-Tenant-4-1.png" alt="" /></p>
<h3 id="register-application-into-the-tenant"><a id="register-application-into-the-tenant"></a>Register application into the tenant</h3>
<p>On the quick start page on the created directory, under Administer, click Manage B2C settings. This will open the new Azure portal.</p>
<p>On the B2C features blade on the Azure portal, click Applications then click Add at the top of the blade and fill the details:</p>
<p><img src="/assets/integrating-azure-b2c/AddApplicationToTenant-1.png" alt="" /></p>
<p>Click Create to register your application and then copy down the globally unique Application Client ID because we will use it later while building the application.</p>
<p><img src="/assets/integrating-azure-b2c/Application-Client-ID-5.png" alt="" /></p>
<h3 id="choose-identity-providers">Choose identity providers</h3>
<p>Azure AD B2C offers multiple social identity providers Microsoft, Google, Amazon, LinkedIn and Facebook in addition to the local accounts. For the sake of this article, we will keep it to the default identity provider so no need to apply changes.</p>
<h3 id="configure-sign-upsign-in-policy"><a id="configure-sign-up-sign-in-policy"></a>Configure sign-up/sign-in policy</h3>
<p>Policies define the behaviour of sign in, sign up, etc. We will use the unified “Sign-up or Sign-in” policy which will provide the application a single experience for the sign up and sign in. To configure this policy:</p>
<p>Click on “Sign-up or sign-in policies” > Add > then fill the the details:</p>
<ul>
<li><strong>Policy Name:</strong> This field defines the name of the policy that we will use in our application.</li>
<li><strong>Identity Providers:</strong> The set of identity providers that will be supported in this policy - in our case it will be “Email signup”.
<img src="/assets/integrating-azure-b2c/Identity-Providers-1.png" alt="" /></li>
<li><strong>Sign-up attributes:</strong> The set of attributes the user must provide during the registration process.
<img src="/assets/integrating-azure-b2c/Signup-Attributes-3.png" alt="" /></li>
<li><strong>Application claims:</strong> The claims that will be sent back to the application after the successful log in.
<img src="/assets/integrating-azure-b2c/Application-Claims-1.png" alt="" /></li>
<li><strong>Multifactor authentication:</strong> You can enable Multifactor authentication where the email can use email or mobile to receive confirmation code before proceeding with the login process however we will not use it in this post.</li>
<li><strong>Page UI customisation:</strong> Policies allows customising the look and feel of pages such as sign up and sign in which is basically a CSHTML file.</li>
</ul>
<p>Now we have finished preparing the AD B2C, let’s jump into building the mobile application.</p>
<h2 id="-building-the-xamarin-forms-application"><a id="building-xamarin-forms-application"></a> Building the Xamarin Forms application</h2>
<p>We will build Xamarin forms application that targets both iOS and Android platforms. The application will have two screens:</p>
<ol>
<li>A Welcome Screen that shows welcome message with sign in button to authenticate the user using Azure AD B2C.</li>
<li>A Secure Page that shows the logged in user name and sign out functionality.</li>
</ol>
<h3 id="-empty-app"><a id="empty-app"></a> Empty App</h3>
<p>Will start with creating Xamarin Forms app that target both iOS and Android in Xamarin Studio or Visual Studio.</p>
<h3 id="adding-microsoft-authentication-library">Adding Microsoft Authentication Library</h3>
<p>MSAL is a developer library that helps you to obtain tokens from MSA, Azure AD or Azure B2C for accessing protected resources.</p>
<blockquote>
<p>MSAL helps you with showing the necessary authentication, multi-factor authentication and consent UX in a platform-appropriate fashion; it takes care of crafting, sending, receiving, validating and interpreting the protocol messages that are required for implementing the authentication flows you need; and it takes care of persisting tokens for you, transparently using all the tricks in the book (such as transparent usage of refresh tokens) to minimize the number of authentication prompts presented to your users.<a href="#ms-identity-build">[2]</a></p>
</blockquote>
<p>So, for each project, add a reference to <a href="https://www.nuget.org/packages/Microsoft.Identity.Client/1.0.304142221-alpha">the Microsoft Authentication Library (MSAL) NuGet package</a> and make sure you include the pre-release packages while installing.</p>
<h4 id="android-special-handling">Android Special Handling</h4>
<p>We have to update the <code class="language-plaintext highlighter-rouge">OnActivityResult</code> of the <code class="language-plaintext highlighter-rouge">MainActivity</code> in the Android project with the line of code below to ensure the control goes back to MSAL once the interactive portion of the authentication flow ended:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">AuthenticationAgentContinuationHelper</span><span class="p">.</span><span class="nf">SetAuthenticationAgentContinuationEventArgs</span><span class="p">(</span><span class="n">requestCode</span><span class="p">,</span> <span class="n">resultCode</span><span class="p">,</span> <span class="n">data</span><span class="p">);</span>
<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnActivityResult</span><span class="p">(</span><span class="kt">int</span> <span class="n">requestCode</span><span class="p">,</span> <span class="n">Result</span> <span class="n">resultCode</span><span class="p">,</span> <span class="n">Intent</span> <span class="n">data</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">base</span><span class="p">.</span><span class="nf">OnActivityResult</span><span class="p">(</span><span class="n">requestCode</span><span class="p">,</span> <span class="n">resultCode</span><span class="p">,</span> <span class="n">data</span><span class="p">);</span>
<span class="n">AuthenticationAgentContinuationHelper</span><span class="p">.</span><span class="nf">SetAuthenticationAgentContinuationEventArgs</span><span class="p">(</span><span class="n">requestCode</span><span class="p">,</span> <span class="n">resultCode</span><span class="p">,</span> <span class="n">data</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="-welcome-screen"><a id="welcome-screen"></a> Welcome Screen</h3>
<p>Moving into adding the welcome screen, add new Xamarin forms Xaml content page with the name <code class="language-plaintext highlighter-rouge">WelcomePage</code> and update the Xaml:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><StackLayout</span> <span class="na">Orientation=</span><span class="s">"Vertical"</span> <span class="na">VerticalOptions=</span><span class="s">"FillAndExpand"</span><span class="nt">></span>
<span class="nt"><Label</span> <span class="na">Text=</span><span class="s">"Welcome to Xamarin Forms!"</span> <span class="na">VerticalTextAlignment=</span><span class="s">"Center"</span> <span class="na">VerticalOptions=</span><span class="s">"FillAndExpand"</span> <span class="na">HorizontalOptions=</span><span class="s">"Center"</span> <span class="nt">/></span>
<span class="nt"><StackLayout</span> <span class="na">Orientation=</span><span class="s">"Horizontal"</span> <span class="na">VerticalOptions=</span><span class="s">"End"</span> <span class="na">HorizontalOptions=</span><span class="s">"CenterAndExpand"</span><span class="nt">></span>
<span class="nt"><Button</span> <span class="na">Text=</span><span class="s">"Sign In"</span> <span class="na">x:Name=</span><span class="s">"SignIn"</span> <span class="na">Clicked=</span><span class="s">"OnSignUpSignIn_Clicked"</span> <span class="na">HorizontalOptions=</span><span class="s">"Center"</span><span class="nt">/></span>
<span class="nt"></StackLayout></span>
<span class="nt"></StackLayout></span>
</code></pre></div></div>
<p>We will navigate between welcome screen and secure page so update the constructor inside the file <code class="language-plaintext highlighter-rouge">app.xaml.cs</code>:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="nf">App</span><span class="p">()</span>
<span class="p">{</span>
<span class="nf">InitializeComponent</span><span class="p">();</span>
<span class="n">MainPage</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">NavigationPage</span><span class="p">(</span><span class="k">new</span> <span class="nf">WelcomePage</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The MSAL requires set of parameters so I will create class <code class="language-plaintext highlighter-rouge">AuthParameters</code> with all the required parameters and will initiate them with the values from the previous steps:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">AuthParameters</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">const</span> <span class="kt">string</span> <span class="n">Authority</span> <span class="p">=</span> <span class="s">"https://login.microsoftonline.com/HossamB2CDemo.onmicrosoft.com/"</span><span class="p">;</span>
<span class="k">public</span> <span class="k">const</span> <span class="kt">string</span> <span class="n">ClientId</span> <span class="p">=</span> <span class="s">"1aa3e632-bd72-4040-8d4a-854242bd4f20"</span><span class="p">;</span>
<span class="k">public</span> <span class="k">static</span> <span class="k">readonly</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">Scopes</span> <span class="p">=</span> <span class="p">{</span> <span class="n">ClientId</span> <span class="p">};</span>
<span class="k">public</span> <span class="k">const</span> <span class="kt">string</span> <span class="n">Policy</span> <span class="p">=</span> <span class="s">"B2C_1_default_signup_signin"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The welcome screen will redirect the user to the secure page whenever there is a stored token, so we will update the <code class="language-plaintext highlighter-rouge">WelcomePage.OnAppearing</code>:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span>
<span class="p">{</span>
<span class="n">PublicClientApplication</span> <span class="n">publicClientApplication</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">PublicClientApplication</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">ClientId</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">authResult</span> <span class="p">=</span> <span class="k">await</span> <span class="n">publicClientApplication</span><span class="p">.</span><span class="nf">AcquireTokenSilentAsync</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">Scopes</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">Policy</span><span class="p">,</span> <span class="k">false</span><span class="p">);</span>
<span class="k">await</span> <span class="n">Navigation</span><span class="p">.</span><span class="nf">PushAsync</span><span class="p">(</span><span class="k">new</span> <span class="nf">SecurePage</span><span class="p">());</span>
<span class="p">}</span>
<span class="k">catch</span>
<span class="p">{</span>
<span class="p">}</span>
</code></pre></div></div>
<p>I am using the main class in MSAL <code class="language-plaintext highlighter-rouge">PublicClientApplication</code> trying to retrieve any stored token by calling the method <code class="language-plaintext highlighter-rouge">AcquireTokenSilentAsync</code>. <code class="language-plaintext highlighter-rouge">AcquireTokenSilentAsync</code> throughs an exception if no token found so we have to wrap our code with try catch. if the call succeeds, we redirect the user to the <code class="language-plaintext highlighter-rouge">SecurePage</code>.</p>
<p><a id="sign-in-register"></a></p>
<h3 id="sign-inregister">Sign in/Register</h3>
<p>Add the sign in click button handler:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="k">void</span> <span class="nf">OnSignUpSignIn_Clicked</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">EventArgs</span> <span class="n">e</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">try</span>
<span class="p">{</span>
<span class="n">PublicClientApplication</span> <span class="n">publicClientApplication</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">PublicClientApplication</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">ClientId</span><span class="p">);</span>
<span class="n">publicClientApplication</span><span class="p">.</span><span class="n">PlatformParameters</span> <span class="p">=</span> <span class="n">PlatformParameters</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">authResult</span> <span class="p">=</span> <span class="k">await</span> <span class="n">publicClientApplication</span><span class="p">.</span><span class="nf">AcquireTokenAsync</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">Scopes</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="n">UiOptions</span><span class="p">.</span><span class="n">SelectAccount</span><span class="p">,</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">Policy</span><span class="p">);</span>
<span class="k">await</span> <span class="n">Navigation</span><span class="p">.</span><span class="nf">PushAsync</span><span class="p">(</span><span class="k">new</span> <span class="nf">SecurePage</span><span class="p">());</span>
<span class="p">}</span>
<span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">exception</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">await</span> <span class="nf">DisplayAlert</span><span class="p">(</span><span class="s">"An error has occurred"</span><span class="p">,</span> <span class="n">exception</span><span class="p">.</span><span class="n">Message</span><span class="p">,</span> <span class="s">"Dismiss"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The code is similar to the one we have used to acquire the token inside <code class="language-plaintext highlighter-rouge">OnAppearing</code> of the <code class="language-plaintext highlighter-rouge">WelcomePage</code> however there are two differences:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">AcquireTokenAsync</code>: This method will get the user into the interactive mode of showing web view, to sign up or sign in. The functionalities that appear inside the web view, are mainly derived from the policy configurations which gives more flexibility like enabling multi-factor authentication at any time or adding extra attribute to the user profile.</li>
<li><code class="language-plaintext highlighter-rouge">PlatformParameters</code>: This parameter helps the MSAL to detect which platform is currently in use so it can correctly handle the interactive mode and the value for this parameter must be set through each platform so we have to update the <code class="language-plaintext highlighter-rouge">WelcomePage</code> to contain public variable that we set through a renderer inside each platform.</li>
</ul>
<h3 id="setting-platform-parameters">Setting Platform Parameters</h3>
<p>Add the public property <code class="language-plaintext highlighter-rouge">PlatformParameters</code> to the <code class="language-plaintext highlighter-rouge">WelcomePage</code>:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="n">IPlatformParameters</span> <span class="n">PlatformParameters</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</code></pre></div></div>
<p>Then, create <code class="language-plaintext highlighter-rouge">WelcomePageRender</code> inside the iOS project:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">assembly</span><span class="p">:</span> <span class="nf">ExportRenderer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">WelcomePage</span><span class="p">),</span> <span class="k">typeof</span><span class="p">(</span><span class="n">WelcomePageRenderer</span><span class="p">))]</span>
<span class="k">namespace</span> <span class="nn">B2CDemo.iOS</span>
<span class="p">{</span>
<span class="k">class</span> <span class="nc">WelcomePageRenderer</span> <span class="p">:</span> <span class="n">PageRenderer</span>
<span class="p">{</span>
<span class="n">WelcomePage</span> <span class="n">page</span><span class="p">;</span>
<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnElementChanged</span><span class="p">(</span><span class="n">VisualElementChangedEventArgs</span> <span class="n">e</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">base</span><span class="p">.</span><span class="nf">OnElementChanged</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
<span class="n">page</span> <span class="p">=</span> <span class="n">e</span><span class="p">.</span><span class="n">NewElement</span> <span class="k">as</span> <span class="n">WelcomePage</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">ViewDidLoad</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">base</span><span class="p">.</span><span class="nf">ViewDidLoad</span><span class="p">();</span>
<span class="n">page</span><span class="p">.</span><span class="n">PlatformParameters</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">PlatformParameters</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>And, another renderer inside the Android project:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">assembly</span><span class="p">:</span> <span class="nf">ExportRenderer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">WelcomePage</span><span class="p">),</span> <span class="k">typeof</span><span class="p">(</span><span class="n">WelcomePageRenderer</span><span class="p">))]</span>
<span class="k">namespace</span> <span class="nn">B2CDemo.Droid</span>
<span class="p">{</span>
<span class="k">class</span> <span class="nc">WelcomePageRenderer</span> <span class="p">:</span> <span class="n">PageRenderer</span>
<span class="p">{</span>
<span class="n">WelcomePage</span> <span class="n">page</span><span class="p">;</span>
<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnElementChanged</span><span class="p">(</span><span class="n">ElementChangedEventArgs</span><span class="p"><</span><span class="n">Page</span><span class="p">></span> <span class="n">e</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">base</span><span class="p">.</span><span class="nf">OnElementChanged</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
<span class="n">page</span> <span class="p">=</span> <span class="n">e</span><span class="p">.</span><span class="n">NewElement</span> <span class="k">as</span> <span class="n">WelcomePage</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">activity</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">Context</span> <span class="k">as</span> <span class="n">Activity</span><span class="p">;</span>
<span class="n">page</span><span class="p">.</span><span class="n">PlatformParameters</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">PlatformParameters</span><span class="p">(</span><span class="n">activity</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="secure-page"><a id="secure-page"></a>Secure Page</h3>
<p>This page will show the current user name so update the <code class="language-plaintext highlighter-rouge">OnAppearing</code>:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">protected</span> <span class="k">async</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnAppearing</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">try</span>
<span class="p">{</span>
<span class="n">PublicClientApplication</span> <span class="n">publicClientApplication</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">PublicClientApplication</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">ClientId</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">authResult</span> <span class="p">=</span> <span class="k">await</span> <span class="n">publicClientApplication</span><span class="p">.</span><span class="nf">AcquireTokenSilentAsync</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">Scopes</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">Policy</span><span class="p">,</span> <span class="k">false</span><span class="p">);</span>
<span class="n">Token</span><span class="p">.</span><span class="n">Text</span> <span class="p">=</span> <span class="n">authResult</span><span class="p">.</span><span class="n">IdToken</span><span class="p">;</span>
<span class="n">Name</span><span class="p">.</span><span class="n">Text</span> <span class="p">=</span> <span class="s">"Welcome Secure User:"</span> <span class="p">+</span> <span class="n">authResult</span><span class="p">.</span><span class="n">User</span><span class="p">.</span><span class="n">Name</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">catch</span><span class="p">(</span><span class="n">Exception</span> <span class="n">ex</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//failed to retrieve token</span>
<span class="n">PublicClientApplication</span> <span class="n">publicClientApplication</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">PublicClientApplication</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">AuthParameters</span><span class="p">.</span><span class="n">ClientId</span><span class="p">);</span>
<span class="n">publicClientApplication</span><span class="p">.</span><span class="n">UserTokenCache</span><span class="p">.</span><span class="nf">Clear</span><span class="p">(</span><span class="n">AuthParameters</span><span class="p">.</span><span class="n">ClientId</span><span class="p">);</span>
<span class="k">await</span> <span class="n">Navigation</span><span class="p">.</span><span class="nf">PushAsync</span><span class="p">(</span><span class="k">new</span> <span class="nf">WelcomePage</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The code is very similar to the one that we have used in the welcome screen with the addition of grabbing the user name from the result using <code class="language-plaintext highlighter-rouge">result.User.Name</code></p>
<p>You can use <code class="language-plaintext highlighter-rouge">authResult.IdToken</code> to acquire the Access Token to call any secured APIs.</p>
<h3 id="sign-out"><a id="sign-out"></a>Sign out</h3>
<p>The sign out is easy, all we need to do is remove the access token from the cache and then navigate the user to the welcome screen:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="k">void</span> <span class="nf">SignOut_Clicked</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">System</span><span class="p">.</span><span class="n">EventArgs</span> <span class="n">e</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">PublicClientApplication</span> <span class="n">publicClientApplication</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">PublicClientApplication</span><span class="p">(</span><span class="n">App</span><span class="p">.</span><span class="n">Authority</span><span class="p">,</span> <span class="n">App</span><span class="p">.</span><span class="n">ClientId</span><span class="p">);</span>
<span class="n">publicClientApplication</span><span class="p">.</span><span class="n">UserTokenCache</span><span class="p">.</span><span class="nf">Clear</span><span class="p">(</span><span class="n">App</span><span class="p">.</span><span class="n">PCApplication</span><span class="p">.</span><span class="n">ClientId</span><span class="p">);</span>
<span class="k">await</span> <span class="n">Navigation</span><span class="p">.</span><span class="nf">PushAsync</span><span class="p">(</span><span class="k">new</span> <span class="nf">WelcomePage</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Here, you should be able to run the application with all the functionalities working.</p>
<h2 id="references">References</h2>
<ol>
<li><a href="https://azure.microsoft.com/en-us/documentation/services/active-directory-b2c/">Azure Active Directory B2C documentation</a></li>
<li><a id="ms-identity-build"></a><a href="https://blogs.technet.microsoft.com/enterprisemobility/2016/03/31/microsoft-identity-at-build-2016/">Microsoft Identity at //build/ 2016</a></li>
<li><a href="https://blogs.technet.microsoft.com/enterprisemobility/2015/09/16/azure-ad-b2c-and-b2b-are-now-in-public-preview/">Azure AD B2C and B2B Public Preview Announcement</a></li>
<li><a href="https://azure.microsoft.com/en-us/documentation/services/active-directory-b2c/">Azure Active Directory B2C documentation</a></li>
<li><a href="https://blogs.technet.microsoft.com/enterprisemobility/2016/05/05/more-preview-enhancements-for-azure-ad-b2c/">More preview enhancements for Azure AD B2C</a></li>
</ol>
Configure Camel Case Resolver for ASP.NET Core MVC2016-05-08T00:00:00+00:00http://www.hossambarakat.net/2016/05/08/configure-camel-case-resolver-for-asp-net-core-mvc<p>It is known that camelCase is the common convention while working with JavaScript so you will find yourself in an awkward situation when you integrate with WebApi because the default JSON output is formatted using PascalCase.</p>
<p>Assuming that we have an Employee model that is returned from Web API</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Employee</span>
<span class="p">{</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">FirstName</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">LastName</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="p">[</span><span class="n">HttpGet</span><span class="p">]</span>
<span class="k">public</span> <span class="n">Employee</span> <span class="nf">Get</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Employee</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">FirstName</span> <span class="p">=</span> <span class="s">"Hossam"</span><span class="p">,</span>
<span class="n">LastName</span> <span class="p">=</span> <span class="s">"Barakat"</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The following will be the JSON outcome</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="nl">"FirstName"</span><span class="p">:</span><span class="s2">"Hossam"</span><span class="p">,</span><span class="nl">"LastName"</span><span class="p">:</span><span class="s2">"Barakat"</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The output could be changed to use camelCase by using a new contract resolver and thanks to the excellent library <a href="http://www.newtonsoft.com/json">Json.NET</a> there is a builtin contract resolver that we can plug directly into the ASP.NET startup configurations.</p>
<p>Update the dependencies section inside the project.json to reference <code class="language-plaintext highlighter-rouge">Newtonsoft.Json</code></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"Newtonsoft.Json"</span><span class="p">:</span><span class="w"> </span><span class="s2">"8.0.2"</span><span class="w">
</span></code></pre></div></div>
<p>Update the <code class="language-plaintext highlighter-rouge">ConfigureServices</code> method inside the <code class="language-plaintext highlighter-rouge">Startup</code> class.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">services</span><span class="p">.</span><span class="nf">AddMvc</span><span class="p">()</span>
<span class="p">.</span><span class="nf">AddJsonOptions</span><span class="p">(</span><span class="n">options</span> <span class="p">=></span> <span class="n">options</span><span class="p">.</span><span class="n">SerializerSettings</span><span class="p">.</span><span class="n">ContractResolver</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">CamelCasePropertyNamesContractResolver</span><span class="p">());</span>
</code></pre></div></div>
<p>The output will be camel case formatted</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="nl">"firstName"</span><span class="p">:</span><span class="s2">"Hossam"</span><span class="p">,</span><span class="nl">"lastName"</span><span class="p">:</span><span class="s2">"Barakat"</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
Unit Testing ASP.NET Core Tag Helper2016-02-29T00:00:00+00:00http://www.hossambarakat.net/2016/02/29/unit-testing-asp-net-core-tag-helper<p>Tag helpers is one of the new additions to ASP.NET Core MVC 1.0 features which enables the tags to participate in the server side rendering with an easy syntax that is easy to write and read specially for front-end developers who don’t have any previous knowledge with Razor syntax.</p>
<p>This post will go through testing and ASP.NET core MVC tag helper that I have explained how to build <a href="http://www.hossambarakat.net/2016/02/15/authoring-asp-net-core-mvc-tag-helper/">in a previous post</a></p>
<h2 id="create-a-class-library-project">Create a class library project</h2>
<p>The first step is creating a class library project targeting .NET 4.5 or later. Name the project <em>TagHelperDemoTests</em></p>
<h2 id="reference-xunit">Reference xUnit</h2>
<p>This post will use the <a href="http://xunit.github.io/">xUnit</a> framework for testing so update the <code class="language-plaintext highlighter-rouge">project.json</code> to reference both xunit and xunit runner</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0-*"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"authors"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span><span class="p">],</span><span class="w">
</span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span><span class="p">],</span><span class="w">
</span><span class="nl">"projectUrl"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"licenseUrl"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"dependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"xunit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.1.0-*"</span><span class="p">,</span><span class="w">
</span><span class="nl">"xunit.runner.dnx"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.1.0-rc1-build204"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"frameworks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"dnx451"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="nl">"dnxcore50"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"commands"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"test"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xunit.runner.dnx"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h2 id="reference-the-tag-helper-project">Reference the tag helper project</h2>
<p>Update the dependencies section inside the <code class="language-plaintext highlighter-rouge">project.json</code> file to reference the project that contains the tag helper to be tested which is <code class="language-plaintext highlighter-rouge">TagHelperDemo</code> in my case.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0-*"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"authors"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span><span class="p">],</span><span class="w">
</span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span><span class="p">],</span><span class="w">
</span><span class="nl">"projectUrl"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"licenseUrl"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
</span><span class="nl">"dependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"xunit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.1.0-*"</span><span class="p">,</span><span class="w">
</span><span class="nl">"xunit.runner.dnx"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.1.0-rc1-build204"</span><span class="p">,</span><span class="w">
</span><span class="nl">"TagHelperDemo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0-*"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"frameworks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"dnx451"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="nl">"dnxcore50"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"commands"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"test"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xunit.runner.dnx"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h2 id="writing-a-simple-test">Writing a simple test</h2>
<p>Add new class to your project and name that class <code class="language-plaintext highlighter-rouge">ListGroupTagHelperTests</code></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">Xunit</span><span class="p">;</span>
<span class="k">namespace</span> <span class="nn">TagHelperDemoTests</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">ListGroupTagHelperTests</span>
<span class="p">{</span>
<span class="p">[</span><span class="n">Fact</span><span class="p">]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">VerifyTestConfiguration</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">Assert</span><span class="p">.</span><span class="nf">True</span><span class="p">(</span><span class="m">1</span><span class="p">==</span><span class="m">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Now you can run the tests using visual studio test explorer or open the command prompt and navigate to the test project directory and run the tests using the command <code class="language-plaintext highlighter-rouge">dnx test</code>, the outcome should look like the following</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xUnit.net DNX Runner (32-bit DNX 4.5.1)
Discovering: TagHelperDemoTests
Discovered: TagHelperDemoTests
Starting: TagHelperDemoTests
Finished: TagHelperDemoTests
=== TEST EXECUTION SUMMARY ===
TagHelperDemoTests Total: 1, Errors: 0, Failed: 0, Skipped: 0, Time: 0.078s
</code></pre></div></div>
<h2 id="write-the-tag-helper-test">Write the tag helper test</h2>
<p>Typically tag helpers implement <code class="language-plaintext highlighter-rouge">Process</code> or <code class="language-plaintext highlighter-rouge">ProcessAsync</code> methods so obviously your tests will be addressing those methods. The <code class="language-plaintext highlighter-rouge">Process</code> method accepts two parameters the <code class="language-plaintext highlighter-rouge">TagHelperContext</code> which contains information about the tag addressed by the tag helper and the <code class="language-plaintext highlighter-rouge">TagHelperOutput</code> that is used to generate the tag output.</p>
<h3 id="taghelpercontext">TagHelperContext</h3>
<p>Create an instance of the <code class="language-plaintext highlighter-rouge">TagHelperContext</code>, its constructor accepts three parameters:</p>
<ul>
<li><strong>allAttributes</strong>: List of attributes associated with the current HTML tag and in our case this is empty.</li>
<li><strong>items</strong>: Dictionary of objects which is usually used to transfer data between tag helpers and we are not using it in our case</li>
<li><strong>uniqueId</strong>: Unique id for the HTML tag.</li>
</ul>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">context</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TagHelperContext</span><span class="p">(</span>
<span class="k">new</span> <span class="nf">TagHelperAttributeList</span><span class="p">(),</span>
<span class="k">new</span> <span class="n">Dictionary</span><span class="p"><</span><span class="kt">object</span><span class="p">,</span> <span class="kt">object</span><span class="p">>(),</span>
<span class="n">Guid</span><span class="p">.</span><span class="nf">NewGuid</span><span class="p">().</span><span class="nf">ToString</span><span class="p">(</span><span class="s">"N"</span><span class="p">));</span>
</code></pre></div></div>
<h3 id="taghelperoutput">TagHelperOutput</h3>
<p>Create an instance of the TagHelperOutput, its constructor accepts three parameters:</p>
<ul>
<li><strong>tagName</strong>: The tag name which is <code class="language-plaintext highlighter-rouge">list-group</code> in our case</li>
<li><strong>attributes</strong>: The list of attributes which is empty in our case</li>
<li><strong>getChildContentAsync</strong>: A delegate used to execute and retrieve the rendered child content asynchronously</li>
</ul>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">output</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TagHelperOutput</span><span class="p">(</span>
<span class="s">"list-group"</span><span class="p">,</span>
<span class="k">new</span> <span class="nf">TagHelperAttributeList</span><span class="p">(),</span>
<span class="p">(</span><span class="n">useCachedResult</span><span class="p">)</span> <span class="p">=></span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">tagHelperContent</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">DefaultTagHelperContent</span><span class="p">();</span>
<span class="n">tagHelperContent</span><span class="p">.</span><span class="nf">SetContent</span><span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">);</span>
<span class="k">return</span> <span class="n">Task</span><span class="p">.</span><span class="n">FromResult</span><span class="p"><</span><span class="n">TagHelperContent</span><span class="p">>(</span><span class="n">tagHelperContent</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">);</span>
</code></pre></div></div>
<h3 id="unit-test-logic">Unit test logic</h3>
<p>Create an instance of the <code class="language-plaintext highlighter-rouge">ListGroupTagHelper</code> class, set the Items property and call the Process method with the prepared parameters, then assert the outcome by assessing the properties of the <code class="language-plaintext highlighter-rouge">TagHelperOutput</code>.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">Microsoft.AspNet.Razor.TagHelpers</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Collections.Generic</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Threading.Tasks</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">Xunit</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">TagHelperDemo</span><span class="p">;</span>
<span class="k">namespace</span> <span class="nn">TagHelperDemoTests</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">ListGroupTagHelperTests</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">static</span> <span class="n">TheoryData</span><span class="p"><</span><span class="n">List</span><span class="p"><</span><span class="kt">string</span><span class="p">>,</span><span class="kt">string</span><span class="p">></span> <span class="n">GeneratesExpectedOutputDataSet</span>
<span class="p">{</span>
<span class="k">get</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">TheoryData</span><span class="p"><</span><span class="n">List</span><span class="p"><</span><span class="kt">string</span><span class="p">>,</span> <span class="kt">string</span><span class="p">></span>
<span class="p">{</span>
<span class="p">{</span> <span class="k">new</span> <span class="n">List</span><span class="p"><</span><span class="kt">string</span><span class="p">>()</span> <span class="p">,</span> <span class="s">""</span> <span class="p">},</span>
<span class="p">{</span> <span class="k">new</span> <span class="n">List</span><span class="p"><</span><span class="kt">string</span><span class="p">></span> <span class="p">{</span> <span class="s">"Saturday"</span> <span class="p">}</span> <span class="p">,</span> <span class="s">$"<li class=\"list-group-item\">Saturday</li>"</span><span class="p">}</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">[</span><span class="n">Theory</span><span class="p">]</span>
<span class="p">[</span><span class="nf">MemberData</span><span class="p">(</span><span class="k">nameof</span><span class="p">(</span><span class="n">GeneratesExpectedOutputDataSet</span><span class="p">))]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Process_GeneratesExpectedOutput</span><span class="p">(</span><span class="n">List</span><span class="p"><</span><span class="kt">string</span><span class="p">></span> <span class="n">items</span><span class="p">,</span><span class="kt">string</span> <span class="n">expectedOutput</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">ListGroupTagHelper</span> <span class="n">myTagHelper</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">ListGroupTagHelper</span><span class="p">();</span>
<span class="kt">var</span> <span class="n">context</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TagHelperContext</span><span class="p">(</span>
<span class="k">new</span> <span class="nf">TagHelperAttributeList</span><span class="p">(),</span>
<span class="k">new</span> <span class="n">Dictionary</span><span class="p"><</span><span class="kt">object</span><span class="p">,</span> <span class="kt">object</span><span class="p">>(),</span>
<span class="n">Guid</span><span class="p">.</span><span class="nf">NewGuid</span><span class="p">().</span><span class="nf">ToString</span><span class="p">(</span><span class="s">"N"</span><span class="p">));</span>
<span class="n">myTagHelper</span><span class="p">.</span><span class="n">Items</span> <span class="p">=</span> <span class="n">items</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">output</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TagHelperOutput</span><span class="p">(</span>
<span class="s">"list-group"</span><span class="p">,</span>
<span class="k">new</span> <span class="nf">TagHelperAttributeList</span><span class="p">(),</span>
<span class="p">(</span><span class="n">useCachedResult</span><span class="p">)</span> <span class="p">=></span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">tagHelperContent</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">DefaultTagHelperContent</span><span class="p">();</span>
<span class="n">tagHelperContent</span><span class="p">.</span><span class="nf">SetContent</span><span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">);</span>
<span class="k">return</span> <span class="n">Task</span><span class="p">.</span><span class="n">FromResult</span><span class="p"><</span><span class="n">TagHelperContent</span><span class="p">>(</span><span class="n">tagHelperContent</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">);</span>
<span class="n">myTagHelper</span><span class="p">.</span><span class="nf">Process</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">output</span><span class="p">);</span>
<span class="n">Assert</span><span class="p">.</span><span class="nf">Equal</span><span class="p">(</span><span class="s">"ul"</span><span class="p">,</span> <span class="n">output</span><span class="p">.</span><span class="n">TagName</span><span class="p">);</span>
<span class="n">Assert</span><span class="p">.</span><span class="nf">Equal</span><span class="p">(</span><span class="n">expectedOutput</span><span class="p">,</span> <span class="n">output</span><span class="p">.</span><span class="n">Content</span><span class="p">.</span><span class="nf">GetContent</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Run the command <code class="language-plaintext highlighter-rouge">dnx test</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xUnit.net DNX Runner (32-bit DNX 4.5.1)
Discovering: TagHelperDemoTests
Discovered: TagHelperDemoTests
Starting: TagHelperDemoTests
Finished: TagHelperDemoTests
=== TEST EXECUTION SUMMARY ===
TagHelperDemoTests Total: 2, Errors: 0, Failed: 0, Skipped: 0, Time: 0.276s
</code></pre></div></div>
<h2 id="summary">Summary</h2>
<p>Writing unit test to address ASP.NET Core MVC tag helper could be done by doing the following steps:</p>
<ol>
<li>Creating a class library project that reference xUnit as well as the project that holds the tag helper under test.</li>
<li>Create a test class with test method,</li>
<li>Prepare an instance of TagHelperContext, TagHelperOutput and the tag helper under test.</li>
<li>Call the <code class="language-plaintext highlighter-rouge">Process</code> or <code class="language-plaintext highlighter-rouge">ProcessAsync</code> methods and assert the the outcome.</li>
</ol>
ASP.NET Core MVC Feature Folders2016-02-16T00:00:00+00:00http://www.hossambarakat.net/2016/02/16/asp-net-core-mvc-feature-folders<p>This post will explain how to extend the ASP.NET Core MVC Razor view engine to support feature folders project structure.</p>
<h2 id="project-structure">Project Structure</h2>
<p>After creating a new ASP.NET Core project, the folder structure will be</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Project
- Controllers
- Models
- Services
- ViewModels
- Views
</code></pre></div></div>
<p>The issue with this structure is when the project grow the number of classes inside each folder will keep growing and the situation becomes messy. That’s why I prefer to use features folders structure where each feature is encapsulated inside a folder with all of its related files including Controllers, Views, Models, Services,…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>App
- Features
-- Home
---- HomeController.cs
---- Index.cshtml
---- IndexViewModel.cs
---- Service.cs
</code></pre></div></div>
<p>Most of the files inside the feature folder will just work without issues considering that most of the classes will be constructed via Dependency Injection.</p>
<h2 id="extend-view-locations">Extend View Locations</h2>
<p>The views doesn’t work with the feature folder structure by default and In order to achieve that structure, The MVC view engine must be extended to search for the views inside the features folder. ASP.NET Core MVC provides a new interface <code class="language-plaintext highlighter-rouge">IViewLocationExpander</code> which is used by <code class="language-plaintext highlighter-rouge">RazorViewEngine</code> instances to determine search paths for a view. The following snippet shows how to implement <code class="language-plaintext highlighter-rouge">IViewLocationExpander</code> to extend <code class="language-plaintext highlighter-rouge">RazorViewEngine</code> to search for views inside the feature folder.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">FeaturesViewLocationExpander</span> <span class="p">:</span> <span class="n">IViewLocationExpander</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">PopulateValues</span><span class="p">(</span><span class="n">ViewLocationExpanderContext</span> <span class="n">context</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">context</span><span class="p">.</span><span class="n">Values</span><span class="p">[</span><span class="s">"customviewlocation"</span><span class="p">]</span> <span class="p">=</span> <span class="k">nameof</span><span class="p">(</span><span class="n">FeaturesViewLocationExpander</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="n">IEnumerable</span><span class="p"><</span><span class="kt">string</span><span class="p">></span> <span class="nf">ExpandViewLocations</span><span class="p">(</span>
<span class="n">ViewLocationExpanderContext</span> <span class="n">context</span><span class="p">,</span>
<span class="n">IEnumerable</span><span class="p"><</span><span class="kt">string</span><span class="p">></span> <span class="n">viewLocations</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">viewLocationFormats</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span>
<span class="p">{</span>
<span class="s">"~/Features/{1}/{0}.cshtml"</span><span class="p">,</span>
<span class="s">"~/Features/Shared/{0}.cshtml"</span>
<span class="p">};</span>
<span class="k">return</span> <span class="n">viewLocationFormats</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">IViewLocationExpander</code> has two methods <code class="language-plaintext highlighter-rouge">PopulateValues</code> and <code class="language-plaintext highlighter-rouge">ExpandViewLocations</code> which are invoked in sequence.</p>
<p><strong>PopulateValues</strong></p>
<ul>
<li><code class="language-plaintext highlighter-rouge">PopulateValues(ViewLocationExpanderContext)</code> is invoked each time a view is requested and the expected outcome is adding a value inside <code class="language-plaintext highlighter-rouge">ViewLocationExpanderContext</code> which could be consumed by <code class="language-plaintext highlighter-rouge">ExpandViewLocations</code>.</li>
<li>The value added to <code class="language-plaintext highlighter-rouge">ViewLocationExpanderContext</code> determine a cache key that decides whether the <code class="language-plaintext highlighter-rouge">ExpandViewLocations</code> will be called or not.</li>
<li><code class="language-plaintext highlighter-rouge">ExpandViewLocations</code> will be called in the following cases
<ul>
<li>No result was found in the cache.</li>
<li>The values cached based on what was added to <code class="language-plaintext highlighter-rouge">ViewLocationExpanderContext</code> are different from the last time the <code class="language-plaintext highlighter-rouge">PopulateValues</code> was invoked.</li>
<li>The view was not found at the cached location.</li>
</ul>
</li>
</ul>
<p><strong>ExpandViewLocations</strong></p>
<ul>
<li><code class="language-plaintext highlighter-rouge">ExpandViewLocations(ViewLocationExpanderContext, IEnumerable<string>)</code> invoked to is invoked to determine all potential paths for a view.</li>
</ul>
<h1 id="configure-razorviewengine">Configure RazorViewEngine</h1>
<p>The last step is to update the <code class="language-plaintext highlighter-rouge">ConfigureServices</code> inside the <code class="language-plaintext highlighter-rouge">Startup</code> class to add the created expander to the <code class="language-plaintext highlighter-rouge">RazorViewEngineOptions</code></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">services</span><span class="p">.</span><span class="n">Configure</span><span class="p"><</span><span class="n">RazorViewEngineOptions</span><span class="p">>(</span><span class="n">options</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">options</span><span class="p">.</span><span class="n">ViewLocationExpanders</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="k">new</span> <span class="nf">CustomViewLocationExpander</span><span class="p">());</span>
<span class="p">});</span>
</code></pre></div></div>
<h2 id="summary">Summary</h2>
<p>Using the feature folders could be achieved in three steps:</p>
<ol>
<li>Update project folder structure</li>
<li>Extend View Locations using IViewLocationExpander</li>
<li>Configure RazorViewEngine to use the IViewLocationExpander</li>
</ol>
Authoring ASP.NET Core MVC Tag Helper2016-02-15T00:00:00+00:00http://www.hossambarakat.net/2016/02/15/authoring-asp-net-core-mvc-tag-helper<p>Tag helpers is one of the new additions to ASP.NET Core MVC 1.0 features which enables the tags to participate in the server side rendering with an easy syntax that is easy to write and read specially for front-end developers who don’t have any previous knowledge with Razor syntax.</p>
<p>In this post, I will show how to develop custom tag helper to render one of the Bootstrap components which is <a href="http://getbootstrap.com/components/#list-group">List Group</a>. The target is to build tag helper that could generate that following Html based on <code class="language-plaintext highlighter-rouge">List<string></code></p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span>
<span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Cras justo odio<span class="nt"></li></span>
<span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Dapibus ac facilisis in<span class="nt"></li></span>
<span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Morbi leo risus<span class="nt"></li></span>
<span class="nt"></ul></span>
</code></pre></div></div>
<h2 id="the-target-tag">The Target Tag</h2>
<p>The first step is to decide what is the HTML tag that will participate into the server side processing. The tag could be one of the HTML built in tags such as <code class="language-plaintext highlighter-rouge"><ul></code> or a totally new HTML tag such as the one that we will use in this post which will be <code class="language-plaintext highlighter-rouge"><list-group></code>.</p>
<h2 id="the-tag-helper-class">The Tag Helper Class</h2>
<p>In order to develop tag helper you have to create a class that inherits from <code class="language-plaintext highlighter-rouge">TagHelper</code></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">ListGroupTagHelper</span> <span class="p">:</span> <span class="n">TagHelper</span>
<span class="p">{</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The above class will make the runtime to target the HTML element <code class="language-plaintext highlighter-rouge"><list-group></code> using the convention <strong>TagName</strong>TagHelper and because our tag has more than one word it will target the tag using <a href="http://stackoverflow.com/a/12273101/499930">kebab-case</a> which is <code class="language-plaintext highlighter-rouge"><list-group></code>. The <code class="language-plaintext highlighter-rouge">HtmlTargetElement</code> could be used to avoid using the convention and be explicit about the target element.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="nf">HtmlTargetElement</span><span class="p">(</span><span class="s">"list-group"</span><span class="p">,</span><span class="n">Attributes</span><span class="p">=</span><span class="n">ItemsAttribute</span><span class="p">)]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">ListGroupTagHelper</span> <span class="p">:</span> <span class="n">TagHelper</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">const</span> <span class="kt">string</span> <span class="n">ItemsAttribute</span> <span class="p">=</span> <span class="s">"asp-items"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">HtmlTargetElement</code> constructor accepts the following parameters</p>
<ul>
<li>Element: This is the html tag the will be targeted by the tag helper</li>
<li>Attributes: Comma separated list of attributes that all must exist to fire the tag helper</li>
</ul>
<p>The <code class="language-plaintext highlighter-rouge">HtmlTargetElement</code> allows using it multiple time over the class which enables scenarios that require using the same tag helper against multiple tags or targeting the same tag with multiple attribute combinations.</p>
<h2 id="tag-helper-parameters">Tag Helper Parameters</h2>
<p>We can provide parameters to the Tag helper using public properties.
For example, we can provide the list of strings that will be processed by the tag helper by creating a new property called <code class="language-plaintext highlighter-rouge">Items</code> of type <code class="language-plaintext highlighter-rouge">List<string></code> then use the attribute <code class="language-plaintext highlighter-rouge">HtmlAttributeName</code> to link what is the html attribute that will be used to pass the items to the tag helper</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="nf">HtmlTargetElement</span><span class="p">(</span><span class="s">"list-group"</span><span class="p">,</span><span class="n">Attributes</span><span class="p">=</span><span class="n">ItemsAttribute</span><span class="p">)]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">ListGroupTagHelper</span> <span class="p">:</span> <span class="n">TagHelper</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">const</span> <span class="kt">string</span> <span class="n">ItemsAttribute</span> <span class="p">=</span> <span class="s">"asp-items"</span><span class="p">;</span>
<span class="p">[</span><span class="nf">HtmlAttributeName</span><span class="p">(</span><span class="n">ItemsAttribute</span><span class="p">)]</span>
<span class="k">public</span> <span class="n">List</span><span class="p"><</span><span class="kt">string</span><span class="p">></span> <span class="n">Items</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">Process</span><span class="p">(</span><span class="n">TagHelperContext</span> <span class="n">context</span><span class="p">,</span> <span class="n">TagHelperOutput</span> <span class="n">output</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>In case your TagHelper has a public property that is not supposed to be bound through the HTML then use the attribute <code class="language-plaintext highlighter-rouge">[HtmlAttributeNotBound]</code>, for example to access the executing <code class="language-plaintext highlighter-rouge">ViewContext</code>, create a property of type <code class="language-plaintext highlighter-rouge">ViewContext</code> and add the attributes <code class="language-plaintext highlighter-rouge">ViewContext</code> and <code class="language-plaintext highlighter-rouge">[HtmlAttributeNotBound]</code> to it.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">HtmlAttributeNotBound</span><span class="p">]</span>
<span class="p">[</span><span class="n">ViewContext</span><span class="p">]</span>
<span class="k">public</span> <span class="n">ViewContext</span> <span class="n">ViewContext</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</code></pre></div></div>
<h2 id="the-processing-logic">The Processing Logic</h2>
<p>The <code class="language-plaintext highlighter-rouge">TagHelper</code> class contains two methods <code class="language-plaintext highlighter-rouge">Process</code> and <code class="language-plaintext highlighter-rouge">ProcessAsync</code>,In this post we will use <code class="language-plaintext highlighter-rouge">Process</code></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">Process</span><span class="p">(</span><span class="n">TagHelperContext</span> <span class="n">context</span><span class="p">,</span> <span class="n">TagHelperOutput</span> <span class="n">output</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentNullException</span><span class="p">(</span><span class="k">nameof</span><span class="p">(</span><span class="n">context</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">output</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentNullException</span><span class="p">(</span><span class="k">nameof</span><span class="p">(</span><span class="n">output</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Items</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">(</span><span class="s">$"</span><span class="p">{</span><span class="k">nameof</span><span class="p">(</span><span class="n">Items</span><span class="p">)}</span><span class="s"> must be provided"</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">output</span><span class="p">.</span><span class="n">TagName</span> <span class="p">=</span> <span class="s">"ul"</span><span class="p">;</span>
<span class="n">output</span><span class="p">.</span><span class="n">Attributes</span><span class="p">[</span><span class="s">"class"</span><span class="p">]</span> <span class="p">=</span> <span class="s">"list-group"</span><span class="p">;</span>
<span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">item</span> <span class="k">in</span> <span class="n">Items</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">TagBuilder</span> <span class="n">itemBuilder</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TagBuilder</span><span class="p">(</span><span class="s">"li"</span><span class="p">);</span>
<span class="n">itemBuilder</span><span class="p">.</span><span class="nf">AddCssClass</span><span class="p">(</span><span class="s">"list-group-item"</span><span class="p">);</span>
<span class="n">itemBuilder</span><span class="p">.</span><span class="n">InnerHtml</span><span class="p">.</span><span class="nf">Append</span><span class="p">(</span><span class="n">item</span><span class="p">);</span>
<span class="n">output</span><span class="p">.</span><span class="n">Content</span><span class="p">.</span><span class="nf">Append</span><span class="p">(</span><span class="n">itemBuilder</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">Process</code> method accepts two parameters:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">TagHelperContext</code>: This parameter contains information about the tag addressed by the tag helper including all its attributes and children elements.</li>
<li><code class="language-plaintext highlighter-rouge">TagHelperOutput</code>: Used to generated the tag output.</li>
</ul>
<p>The <code class="language-plaintext highlighter-rouge">Process</code> methodsstarts with checking that the method parameters are not null. The code is using the new C# <a href="https://msdn.microsoft.com/en-au/library/dn986596.aspx">nameof</a> operator to make the code more maintainable.</p>
<p>The exception <code class="language-plaintext highlighter-rouge">InvalidOperationException</code> is thrown when the <code class="language-plaintext highlighter-rouge">Items</code> are null because most of the built-in tag helpers using that exception for similar cases.</p>
<p>The output.TagName is used to change the current tag from <code class="language-plaintext highlighter-rouge"><list-group></code> into <code class="language-plaintext highlighter-rouge"><ul></code>, then loop over the items and for each item generate new <code class="language-plaintext highlighter-rouge"><li></code> tag using the <code class="language-plaintext highlighter-rouge">TagBuilder</code> class.</p>
<blockquote>
<p>The above code is using the RC1 version for setting the attributes which will change in RC2 according to this <a href="https://github.com/aspnet/Announcements/issues/151">announcement</a></p>
</blockquote>
<h2 id="using-the-tag-helper">Using The Tag Helper</h2>
<p>First we need to import the TagHelpers into the view to be able to use them. By updating the file called <em>_ViewImports.cshtml</em> located inside the <em>views</em> folder to include the following line</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@addTagHelper</span> <span class="s">"*, projectname"</span>
</code></pre></div></div>
<p>The below snippet shows how to use the <code class="language-plaintext highlighter-rouge">ListGroupTagHelper</code> inside view to display the list group of the Items property inside the model assuming that the Items property is a <code class="language-plaintext highlighter-rouge">List<string></code></p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><list-group</span> <span class="na">asp-items=</span><span class="s">"Model.Items"</span><span class="nt">></list-group></span>
</code></pre></div></div>
<h2 id="summary">Summary</h2>
<p>Authoring custom tag helper is a straight forward and here are the steps:</p>
<ol>
<li>Decide the target tag.</li>
<li>Create class that inherits from TagHelper class and use the <code class="language-plaintext highlighter-rouge">HtmlTargetElement</code> to define the target HTML tag.</li>
<li>Use public properties with <code class="language-plaintext highlighter-rouge">HtmlAttributeName</code> on them to define the bound HTML attributes.</li>
<li>Override either Process or ProcessAsync method with your own rendering logic</li>
<li>Import the developed tag into your views using <code class="language-plaintext highlighter-rouge">addTagHelper</code></li>
<li>Finally use your HTML tag inside your view.</li>
</ol>
ASP.NET Core MVC LabelTagHelper2016-02-08T00:00:00+00:00http://www.hossambarakat.net/2016/02/08/asp-net-core-mvc-labeltaghelper<p>Tag Helpers enable server-side code to participate in creating and rendering HTML elements in Razor files.Tag Helpers reduce the explicit transitions between HTML and C# in Razor views.<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup></p>
<p><code class="language-plaintext highlighter-rouge">LabelTagHelper</code> could be considered one of the simplest tag helpers. It targets the html tag <code class="language-plaintext highlighter-rouge"><label></code> with <code class="language-plaintext highlighter-rouge">asp-for</code> attribute. It is equivalent to <code class="language-plaintext highlighter-rouge">Html.LabelFor</code>.</p>
<p>Let’s get into the usage steps. Assuming that the following class represent the model of the view</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">ContactModel</span>
<span class="p">{</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">Mobile</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>First we need to import the TagHelpers into the view to be able to use them. By updating the file called <em>_ViewImports.cshtml</em> located inside the <em>views</em> folder to include the following line</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@addTagHelper</span> <span class="s">"*, Microsoft.AspNet.Mvc.TagHelpers"</span>
</code></pre></div></div>
<p>The below snippet shows how to use the LabelTagHelper inside view to display the label of the Mobile property inside the model</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><label</span> <span class="na">asp-for=</span><span class="s">"Mobile"</span><span class="nt">></label></span>
</code></pre></div></div>
<p>the generated <code class="language-plaintext highlighter-rouge">HTML</code> will look like:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><label</span> <span class="na">for=</span><span class="s">"Mobile"</span><span class="nt">></span>Mobile<span class="nt"></label></span>
</code></pre></div></div>
<p>As shown above, the implementation of the <code class="language-plaintext highlighter-rouge">LabelTagHelper</code> provides default value to the label text.The label text could be defined by using the <code class="language-plaintext highlighter-rouge">DisplayAttribute</code> over the <code class="language-plaintext highlighter-rouge">Mobile</code> property so our model will be as shown underneath:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">ContactModel</span>
<span class="p">{</span>
<span class="p">[</span><span class="nf">Display</span><span class="p">(</span><span class="n">Name</span> <span class="p">=</span> <span class="s">"Mob"</span><span class="p">)]</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">Mobile</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Then, the generated <code class="language-plaintext highlighter-rouge">HTML</code> will be as below</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><label</span> <span class="na">for=</span><span class="s">"Mobile"</span><span class="nt">></span>Mob<span class="nt"></label></span>
</code></pre></div></div>
<p>On the other hand, the <code class="language-plaintext highlighter-rouge">LabelTagHelper</code> also takes into consideration the children of the <code class="language-plaintext highlighter-rouge"><Label></code> tag, so the following snippet</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><label</span> <span class="na">asp-for=</span><span class="s">"Mobile"</span><span class="nt">><img</span> <span class="na">src=</span><span class="s">"/images/mobile-image.png"</span><span class="nt">/></label></span>
</code></pre></div></div>
<p>will generate the following <code class="language-plaintext highlighter-rouge">HTML</code></p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><label</span> <span class="na">for=</span><span class="s">"Mobile"</span><span class="nt">><img</span> <span class="na">src=</span><span class="s">"/images/ASP-NET-Banners-01.png"</span><span class="nt">></label></span>
</code></pre></div></div>
<p>Which means that the <code class="language-plaintext highlighter-rouge">DisplayAttribute</code> will take effect only if the content of the <code class="language-plaintext highlighter-rouge"><label></code> tag was empty.</p>
<p>Hope that helps!</p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:1" role="doc-endnote">
<p>Definition from the <a href="http://docs.asp.net/projects/mvc/en/latest/views/tag-helpers/intro.html"><em>tag helpers</em> documentation</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>
Configuring Redis for ASP.NET Core Session Store2016-02-03T00:00:00+00:00http://www.hossambarakat.net/2016/02/03/configuring-redis-as-asp-net-core-1-0-session-store<blockquote>
<p>As you may have seen in <a href="https://www.youtube.com/watch?v=FSf83_TU5Yg&list=PL0M0zPgJ3HSftTAAHttA3JQU4vOjXFquF&index=0">this ASP.NET Community Standup</a> and Scott Hanselman’s blog post <a href="http://www.hanselman.com/blog/ASPNET5IsDeadIntroducingASPNETCore10AndNETCore10.aspx">ASP.NET 5 is dead - Introducing ASP.NET Core 1.0 and .NET Core 1.0</a>, ASP.NET 5 is being renamed to ASP.NET Core so I will use the new names in this post.</p>
</blockquote>
<p><a href="http://redis.io">Redis</a> is an open source (BSD licensed), in-memory data structure store, used as database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries. Redis works with an in-memory dataset. it also supports persisting the dataset to disk. Moreover, It provides master-slave asynchronous replication. For more details, check the <a href="http://redis.io/documentation">documentation</a>.</p>
<p>This post will go through the steps required to configure <a href="http://redis.io">Redis</a> for <s>ASP.NET 5</s> ASP.NET Core session store targeting DNX on .NET Framework 4.5.1 - 4.6.</p>
<h2 id="installing-redis">Installing Redis</h2>
<p>Redis is not officially supported on windows. However, the <a href="https://msopentech.com/">Microsoft Open Tech group</a> develops and maintains Windows port targeting Win64 <a href="https://github.com/MSOpenTech/redis">available here</a></p>
<p>To install Redis on your local machine, install the chocolatey package <a href="http://chocolatey.org/packages/redis-64/">http://chocolatey.org/packages/redis-64/</a> and run <code class="language-plaintext highlighter-rouge">redis-server</code> from a command prompt.</p>
<p>Redis could also be installed as windows service, for more details please review <a href="https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Windows%20Service%20Documentation.md">this link</a></p>
<h2 id="configuring-distributed-cache">Configuring Distributed Cache</h2>
<p>ASP.NET shipped with several caching implementations including Redis, To use <s>ASP.NET 5</s> ASP.NET Core distributed caching, add the following packages to your <code class="language-plaintext highlighter-rouge">project.json</code></p>
<p>At the time of this writing, the package <code class="language-plaintext highlighter-rouge">Microsoft.Extensions.Caching.Redis</code> version “1.0.0-rc1-final” doesn’t support .NET Core 1.0 however it is planned to be supported and for more details check this <a href="https://github.com/aspnet/Caching/issues/121">issue</a></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"dependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"Microsoft.Extensions.Caching.Redis"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0-rc1-final"</span><span class="w">
</span><span class="err">...</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>
<p>Update the <code class="language-plaintext highlighter-rouge">ConfigureServices</code> method inside the <code class="language-plaintext highlighter-rouge">Startup</code> class to add the Redis caching services as below</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">services</span><span class="p">.</span><span class="n">AddSingleton</span><span class="p"><</span><span class="n">IDistributedCache</span><span class="p">>(</span>
<span class="n">serviceProvider</span> <span class="p">=></span>
<span class="k">new</span> <span class="nf">RedisCache</span><span class="p">(</span><span class="k">new</span> <span class="n">RedisCacheOptions</span>
<span class="p">{</span>
<span class="n">Configuration</span> <span class="p">=</span> <span class="s">"localhost"</span><span class="p">,</span>
<span class="n">InstanceName</span> <span class="p">=</span> <span class="s">"Sample"</span>
<span class="p">}));</span>
<span class="c1">//Other services configuration...</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="configuring-session">Configuring Session</h2>
<p>The <s>ASP.NET 5</s> ASP.NET Core <code class="language-plaintext highlighter-rouge">Session</code> is not configured by default, <code class="language-plaintext highlighter-rouge">Session</code> configurations must be done before using it, otherwise you will receive <code class="language-plaintext highlighter-rouge">InvalidOperationException</code> whenever you try to access it.</p>
<p>To use session, add <code class="language-plaintext highlighter-rouge">Microsoft.AspNet.Session</code> to the <code class="language-plaintext highlighter-rouge">project.json</code> as shown below</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"dependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"Microsoft.AspNet.Session"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0-rc1-final"</span><span class="w">
</span><span class="err">...</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>
<p>Then, Update the <code class="language-plaintext highlighter-rouge">ConfigureServices</code> method inside the <code class="language-plaintext highlighter-rouge">Startup</code> class to add the Redis caching services as below</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">services</span><span class="p">.</span><span class="nf">AddSession</span><span class="p">();</span>
<span class="c1">//Other services configuration...</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Finally, add the following line to <code class="language-plaintext highlighter-rouge">Configure</code>:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">void</span> <span class="nf">Configure</span><span class="p">(</span><span class="n">IApplicationBuilder</span> <span class="n">app</span><span class="p">,</span> <span class="n">IHostingEnvironment</span> <span class="n">env</span><span class="p">,</span> <span class="n">ILoggerFactory</span> <span class="n">loggerFactory</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">app</span><span class="p">.</span><span class="nf">UseSession</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>
<p>That’s it, Now you can reference <code class="language-plaintext highlighter-rouge">Session</code> from <code class="language-plaintext highlighter-rouge">HttpContext</code> and all session entries will be saved to Redis.</p>