Code Inside BlogCode Inside Blog - Code Inside Teamhttps://blog.codeinside.eu
https://blog.codeinside.eu
Wed, 19 Dec 2018 09:03:26 +0000Wed, 19 Dec 2018 09:03:26 +00001800How to use TensorFlow with AMD GPU's
<h1 id="how-to-use-tensorflow-with-amd-gpus">How to use TensorFlow with AMD GPU’s</h1>
<p>Most machine learning frameworks that run with a GPU support Nvidia GPUs,
but if you own a AMD GPU you are out of luck.</p>
<p>Recently AMD has made some progress with their <a href="https://rocm.github.io/">ROCm</a> platform for GPU computing and does now provide a TensorFlow build for their gpus.</p>
<p>Since I work with tensorflow and own a AMD GPU it was time to give it a try.
I stumpled upon <a href="https://gpuopen.com/rocm-tensorflow-1-8-release/">these</a> instructions for TensorFlow 1.8 but since they are outdated, I decided to write down what I did.</p>
<h2 id="1-set-up-linux">1. Set up Linux</h2>
<p>It looks like there is currently no ROCm support for Windows. And no, WSL aka Bash for Windows does not work. But there are packages for CentOS/RHEL 7 and Ubuntu. I used Ubuntu 18.04.</p>
<h2 id="2-install-rocm">2. Install ROCm</h2>
<p>Just follow the ROCm <a href="https://rocm.github.io/ROCmInstall.html#ubuntu-support---installing-from-a-debian-repository">install instructions</a>.</p>
<h2 id="3-install-tensorflow">3. Install TensorFlow</h2>
<p>AMD provides a special build of TensorFlow. Currently they support TensorFlow 1.12.0.
You can build it yourself, but the most convenient way to use it, is to install the package from PyPI:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install python3-pip
pip3 install --user tensorflow-rocm
</code></pre></div></div>
<h2 id="4-train-a-model">4. Train a Model</h2>
<p>To test your setup you can run the image recognition task from the Tensorflow tutorials.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/tensorflow/models.git
cd models/tutorials/image/imagenet
python3 classify_image.py
</code></pre></div></div>
<p>and the result should look like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca (score = 0.89103)
indri, indris, Indri indri, Indri brevicaudatus (score = 0.00810)
lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens (score = 0.00258)
custard apple (score = 0.00149)
earthstar (score = 0.00141)
</code></pre></div></div>
<h2 id="extra-monitor-your-gpu">Extra: Monitor your GPU</h2>
<p>If you like to check that your model fully utilize your GPU, you can use the (radeontop)[https://github.com/clbr/radeontop] tool:</p>
<p>Install it with</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install radeontop
</code></pre></div></div>
<p>and run it</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo radeontop
</code></pre></div></div>
<p>This will dump the statistics to the command line.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo radeontop -d -
</code></pre></div></div>
https://blog.codeinside.eu/2018/12/04/howto-use-tensorflow-with-amd-gpus/
https://blog.codeinside.eu/2018/12/04/howto-use-tensorflow-with-amd-gpusTue, 04 Dec 2018 23:15:00 +0000Make your WCF Service async
<h1 id="oh-my-wcf">Oh my: WCF???</h1>
<p>This might be the elephant in the room: I wouldn’t use WCF for new stuff anymore, but to keep some “legacy” stuff working it might be a good idea to modernize those services as well.</p>
<h1 id="wcf-serviceclient-compatibility">WCF Service/Client compatibility</h1>
<p>WCF services had always close relationships with their clients and so it is no suprise, that most guides show how to implement async operations on the <a href="https://docs.microsoft.com/en-us/dotnet/framework/wcf/how-to-implement-an-asynchronous-service-operation">server and client side</a>.</p>
<p>In our product we needed to ensure backwards compatibility with <strong>older</strong> clients and to my suprise: <strong>Making the operations async don’t break the WCF contract!</strong>.</p>
<p>So - a short example:</p>
<h2 id="sync-sample">Sync Sample</h2>
<p>The sample code is more or less the default implementation for WCF services when you use Visual Studio:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
</code></pre></div></div>
<p>The code is pretty straight forward: The typical interface with two methods, which are decorated with OperationContract and a default implementation.</p>
<p>When we know run this example and check the generated WSDL we will get something like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="Service1" targetNamespace="http://tempuri.org/"&gt;
&lt;wsdl:types&gt;
&lt;xsd:schema targetNamespace="http://tempuri.org/Imports"&gt;
&lt;xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/SyncWcf/Service1/?xsd=xsd0" namespace="http://tempuri.org/"/&gt;
&lt;xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/SyncWcf/Service1/?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/&gt;
&lt;xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/SyncWcf/Service1/?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/SyncWcf"/&gt;
&lt;/xsd:schema&gt;
&lt;/wsdl:types&gt;
&lt;wsdl:message name="IService1_GetData_InputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetData"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:message name="IService1_GetData_OutputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetDataResponse"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:message name="IService1_GetDataUsingDataContract_InputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetDataUsingDataContract"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:message name="IService1_GetDataUsingDataContract_OutputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetDataUsingDataContractResponse"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:portType name="IService1"&gt;
&lt;wsdl:operation name="GetData"&gt;
&lt;wsdl:input wsaw:Action="http://tempuri.org/IService1/GetData" message="tns:IService1_GetData_InputMessage"/&gt;
&lt;wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataResponse" message="tns:IService1_GetData_OutputMessage"/&gt;
&lt;/wsdl:operation&gt;
&lt;wsdl:operation name="GetDataUsingDataContract"&gt;
&lt;wsdl:input wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContract" message="tns:IService1_GetDataUsingDataContract_InputMessage"/&gt;
&lt;wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContractResponse" message="tns:IService1_GetDataUsingDataContract_OutputMessage"/&gt;
&lt;/wsdl:operation&gt;
&lt;/wsdl:portType&gt;
&lt;wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1"&gt;
&lt;soap:binding transport="http://schemas.xmlsoap.org/soap/http"/&gt;
&lt;wsdl:operation name="GetData"&gt;
&lt;soap:operation soapAction="http://tempuri.org/IService1/GetData" style="document"/&gt;
&lt;wsdl:input&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:input&gt;
&lt;wsdl:output&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:output&gt;
&lt;/wsdl:operation&gt;
&lt;wsdl:operation name="GetDataUsingDataContract"&gt;
&lt;soap:operation soapAction="http://tempuri.org/IService1/GetDataUsingDataContract" style="document"/&gt;
&lt;wsdl:input&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:input&gt;
&lt;wsdl:output&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:output&gt;
&lt;/wsdl:operation&gt;
&lt;/wsdl:binding&gt;
&lt;wsdl:service name="Service1"&gt;
&lt;wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1"&gt;
&lt;soap:address location="http://localhost:8733/Design_Time_Addresses/SyncWcf/Service1/"/&gt;
&lt;/wsdl:port&gt;
&lt;/wsdl:service&gt;
&lt;/wsdl:definitions&gt;
</code></pre></div></div>
<h2 id="convert-to-async">Convert to async</h2>
<p>To make the service async we only need change the method signature and returing Tasks:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[ServiceContract]
public interface IService1
{
[OperationContract]
Task&lt;string&gt; GetData(int value);
[OperationContract]
Task&lt;CompositeType&gt; GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
...
public class Service1 : IService1
{
public async Task&lt;string&gt; GetData(int value)
{
return await Task.FromResult(string.Format("You entered: {0}", value));
}
public async Task&lt;CompositeType&gt; GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return await Task.FromResult(composite);
}
}
</code></pre></div></div>
<p>When we run this example and check the WSDL we will see that it is (besides some naming that I changed based on my samples) identical:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="Service1" targetNamespace="http://tempuri.org/"&gt;
&lt;wsdl:types&gt;
&lt;xsd:schema targetNamespace="http://tempuri.org/Imports"&gt;
&lt;xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/AsyncWcf/Service1/?xsd=xsd0" namespace="http://tempuri.org/"/&gt;
&lt;xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/AsyncWcf/Service1/?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/&gt;
&lt;xsd:import schemaLocation="http://localhost:8733/Design_Time_Addresses/AsyncWcf/Service1/?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/AsyncWcf"/&gt;
&lt;/xsd:schema&gt;
&lt;/wsdl:types&gt;
&lt;wsdl:message name="IService1_GetData_InputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetData"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:message name="IService1_GetData_OutputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetDataResponse"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:message name="IService1_GetDataUsingDataContract_InputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetDataUsingDataContract"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:message name="IService1_GetDataUsingDataContract_OutputMessage"&gt;
&lt;wsdl:part name="parameters" element="tns:GetDataUsingDataContractResponse"/&gt;
&lt;/wsdl:message&gt;
&lt;wsdl:portType name="IService1"&gt;
&lt;wsdl:operation name="GetData"&gt;
&lt;wsdl:input wsaw:Action="http://tempuri.org/IService1/GetData" message="tns:IService1_GetData_InputMessage"/&gt;
&lt;wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataResponse" message="tns:IService1_GetData_OutputMessage"/&gt;
&lt;/wsdl:operation&gt;
&lt;wsdl:operation name="GetDataUsingDataContract"&gt;
&lt;wsdl:input wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContract" message="tns:IService1_GetDataUsingDataContract_InputMessage"/&gt;
&lt;wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContractResponse" message="tns:IService1_GetDataUsingDataContract_OutputMessage"/&gt;
&lt;/wsdl:operation&gt;
&lt;/wsdl:portType&gt;
&lt;wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1"&gt;
&lt;soap:binding transport="http://schemas.xmlsoap.org/soap/http"/&gt;
&lt;wsdl:operation name="GetData"&gt;
&lt;soap:operation soapAction="http://tempuri.org/IService1/GetData" style="document"/&gt;
&lt;wsdl:input&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:input&gt;
&lt;wsdl:output&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:output&gt;
&lt;/wsdl:operation&gt;
&lt;wsdl:operation name="GetDataUsingDataContract"&gt;
&lt;soap:operation soapAction="http://tempuri.org/IService1/GetDataUsingDataContract" style="document"/&gt;
&lt;wsdl:input&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:input&gt;
&lt;wsdl:output&gt;
&lt;soap:body use="literal"/&gt;
&lt;/wsdl:output&gt;
&lt;/wsdl:operation&gt;
&lt;/wsdl:binding&gt;
&lt;wsdl:service name="Service1"&gt;
&lt;wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1"&gt;
&lt;soap:address location="http://localhost:8733/Design_Time_Addresses/AsyncWcf/Service1/"/&gt;
&lt;/wsdl:port&gt;
&lt;/wsdl:service&gt;
&lt;/wsdl:definitions&gt;
</code></pre></div></div>
<h2 id="clients">Clients</h2>
<p>The contract itself is still <strong>the same</strong>. You can still use the sync-methods on the client side, because WCF doesn’t care (at least with the SOAP binding stuff). It would be clever to also update your client code, but you don’t have to, that was the most important point for us.</p>
<h2 id="async--operationcontext-access">Async &amp; OperationContext access</h2>
<p>If you are accessing the OperationContext on the server side and using async methods you might stumble on an odd behaviour:</p>
<p>After the first access to <a href="https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.operationcontext.current?view=netframework-4.7.2">OperationContext.Current</a> the value will disappear and OperationContext.Current will be null. This <a href="https://stackoverflow.com/questions/12797091/operationcontext-current-is-null-after-first-await-when-using-async-await-in-wcf">Stackoverflow.com question</a> shows this “bug”.</p>
<p><strong>The reason for this:</strong> There are some <a href="https://github.com/Microsoft/dotnet/issues/403">edge cases</a>, but if you are not using “Reentrant services” the behaviour can be changed with this setting:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;appSettings&gt;
&lt;add key="wcf:disableOperationContextAsyncFlow" value="false" /&gt;
&lt;/appSettings&gt;
</code></pre></div></div>
<p>With this setting if should work like before in the “sync”-world.</p>
<h1 id="summery">Summery</h1>
<p>“Async all the things” - even legacy WCF services can be turned into async task based APIs without breaking any clients. Checkout the sample code on <a href="https://github.com/Code-Inside/Samples/tree/master/2018/AsyncWcf">GitHub</a>.</p>
<p>Hope this helps!</p>
<p><strong>Links:</strong></p>
<ul>
<li><a href="http://blogs.microsoft.co.il/iblogger/2014/12/09/making-your-wcf-service-task-based-without-changing-its-code/">Making your WCF Service Task based without changing its code</a></li>
<li><a href="https://stackoverflow.com/questions/22623922/different-forms-of-the-wcf-service-contract-interface">Different forms of the WCF service contract interface</a></li>
</ul>
https://blog.codeinside.eu/2018/12/03/make-your-wcf-service-async-and-even-maintain-client-compatibility/
https://blog.codeinside.eu/2018/12/03/make-your-wcf-service-async-and-even-maintain-client-compatibilityMon, 03 Dec 2018 22:00:00 +0000HowTo: Run a Docker container using Azure Container Instances
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-11-12/0.png" alt="x" title="Azure Container Instances" /></p>
<h1 id="azure-container-instances">Azure Container Instances</h1>
<p>There are (at least) 3 diffent ways how to run a Docker Container on Azure:</p>
<ul>
<li>Using the <a href="https://azure.microsoft.com/en-us/services/app-service/containers/">Web App for Containers</a></li>
<li>Using <a href="https://docs.microsoft.com/en-us/azure/aks/">Azure Kubernetes Service (AKS)</a></li>
<li>Using <a href="https://azure.microsoft.com/en-us/services/container-instances/">Azure Container Instances</a></li>
</ul>
<p>In this blogpost we will take a small look how to run a Docker Container on this service. The “Azure Container Instances”-service is a pretty easy service and might be a good first start. I will do this step for step guide via the Azure Portal. You can use the <a href="https://docs.microsoft.com/en-us/azure/container-instances/container-instances-quickstart">CLI</a> or <a href="https://docs.microsoft.com/en-us/azure/container-instances/container-instances-quickstart-powershell">Powershell</a>. My guide is more or less the same as <a href="https://docs.microsoft.com/en-us/azure/container-instances/container-instances-quickstart-portal">this one</a>, but I will highlight some important points in my blogpost, so feel free to check out the official docs.</p>
<h1 id="using-azure-container-instances">Using Azure Container Instances</h1>
<h2 id="1-add-new">1. Add new…</h2>
<p>At first search for <strong>“Container Instances”</strong> and this should show up:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-11-12/1.png" alt="x" title="Azure Container Instances - service found" /></p>
<h2 id="2-set-base-settings">2. Set base settings</h2>
<p>Now - this is propably the most important step - choose the container name and source of the image. Those settings can’t be changed later on!</p>
<p>The image can be from a <strong>Public Docker Hub</strong> repository or from a prive docker registry.</p>
<p><strong>Important:</strong> If you are using a <strong>Private Docker Hub</strong> repository use ‘index.docker.io’ as the login server. It took me a while to figure that out.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-11-12/2.png" alt="x" title="Base settings" /></p>
<h2 id="3-set-container-settings">3. Set container settings</h2>
<p>Now you need to choose which OS and how powerful the machine should be.</p>
<p><strong>Important:</strong> If you want an easy access via HTTP to your container, make sure to set a <strong>“DNS label”</strong>. With this label you access it like this: customlabel.azureregion.azurecontainer.io</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-11-12/3.png" alt="x" title="Container settings" /></p>
<p>Make sure to set any needed environment variables here.</p>
<p>Also keep in mind: You can’t change this stuff later on.</p>
<h2 id="ready">Ready</h2>
<p>In the last step you will see a summery of the given settings:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-11-12/4.png" alt="x" title="Summery" /></p>
<h2 id="go">Go</h2>
<p>After you finish the setup your Docker Container should start after a short amount of time (depending on your OS and image of course).</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-11-12/5.png" alt="x" title="Status" /></p>
<p>The most important aspect here:</p>
<p>Check the status, which should be “running”. You can also see your applied FQDN.</p>
<h1 id="summery">Summery</h1>
<p>This service is pretty easy. The setup itself is not hard, but sometimes the UI seems “buggy”, but if you can run your Docker Container locally, you should also be able to run it on this service.</p>
<p>Hope this helps!</p>
https://blog.codeinside.eu/2018/11/12/howto-run-a-docker-container-using-azure-container-instances/
https://blog.codeinside.eu/2018/11/12/howto-run-a-docker-container-using-azure-container-instancesMon, 12 Nov 2018 23:45:00 +0000How to fix ERR_CONNECTION_RESET & ERR_CERT_AUTHORITY_INVALID with IISExpress and SSL
<p>This post is a result of some pretty strange SSL errors <a href="https://github.com/NuGet/NuGetGallery/issues/3892#issuecomment-427608552">that I encountered last weekend</a>.</p>
<p><strong>The scenario:</strong></p>
<p>I tried to setup a development environment for a website that uses a self signed SSL cert. The problem occured right after the start - especially Chrome displayed those wonderful error messages:</p>
<ul>
<li>ERR_CONNECTION_RESET</li>
<li>ERR_CERT_AUTHORITY_INVALID</li>
</ul>
<p><strong>The “maybe” solution:</strong></p>
<p>When you google the problem you will see a couple of possible solutions. I guess the first problem on my machine was, that a previous cert was stale and thus created this issue.
I later then began to delete all localhost SSL &amp; IIS Express related certs in the LocalMachine-Cert store. Maybe this was a dumb idea, because it caused more harm then it helped.</p>
<p>But: Maybe this could solve your problem. Try to check your LocalMachine or LocalUser-Cert store and check for stale certs.</p>
<p><strong>How to fix the IIS Express?</strong></p>
<p>Well - after I deleted the IIS Express certs I couldn’t get anything to work, so I tried to repair the IIS Express installation and boy… this is a long process.</p>
<p>The repair process via the Visual Studio Installer will take some minutes and in the end I had the same problem again, but my IIS Express was working again.</p>
<p><strong>How to fix the real problem?</strong></p>
<p>After some more time (and I did repair the IIS Express at least 2 or 3 times) I tried the second answer from this <a href="https://stackoverflow.com/questions/20036984/how-do-i-restore-a-missing-iis-express-ssl-certificate">Stackoverflow.com question</a>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd C:\Program Files (x86)\IIS Express\IisExpressAdminCmd.exe setupsslUrl -url:https://localhost:44387/ -UseSelfSigned
</code></pre></div></div>
<p>And yeah - this worked. Puh…</p>
<p><strong>Another option:</strong></p>
<p>Checkout the project settings and try to change the bitness settings (I had once a problem with “x64” instead of “Default”) or try to recreate the virtual directory here:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-10-31/projsettings.png" alt="x" title="Project settings" /></p>
<p><strong>Conclusion:</strong></p>
<ul>
<li>Don’t delete random IIS Express certs in your LocalMachine-Cert store.</li>
<li>If you do: Repair the IIS Express via the Visual Studio Installer (the option to repair IIS Express via the Programs &amp; Feature management tool seems to be gone with VS 2017).</li>
<li>Try to setup the SSL cert with the “IisExpressAdminCmd.exe” - this helped me a lot.</li>
<li>Try to use the VS tooling and checkout the project tab and try out “Create Virtual Directory” or change the IIS Express bitness settings.</li>
</ul>
<p>I’m not sure if this really fixed my problem, but maybe it may help:</p>
<p>You can “manage” some part of the SSL stuff via “netsh” from a normal cmd prompt (powershell acts weird with netsh), e.g.:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>netsh http delete sslcert ipport=0.0.0.0:44300
netsh http add sslcert ipport=0.0.0.0:44300 certhash=your_cert_hash_with_no_spaces appid={123a1111-2222-3333-4444-bbbbcccdddee}
</code></pre></div></div>
<p>Be aware: I remember that I deleted a sslcert via the netsh tool, but was unable to add a sslcert. After the IisExpressAdminCmd.exe stuff I worked for me.</p>
<p>Hope this helps!</p>
https://blog.codeinside.eu/2018/10/31/fix-ERR_CONNECTION_RESET-and-ERR_CERT_AUTHORITY_INVALID-with-iisexpress-and-ssl/
https://blog.codeinside.eu/2018/10/31/fix-ERR_CONNECTION_RESET-and-ERR_CERT_AUTHORITY_INVALID-with-iisexpress-and-sslWed, 31 Oct 2018 23:45:00 +0000Be afraid of varchar(max) with async EF or ADO.NET
<p>Last month we had changed our WCF APIs to async implementations, because we wanted all those glorious scalability improvements in our codebase.</p>
<p>The implementation was quite easy, because our service layer did most of the time just some simple EntityFramework 6 queries.</p>
<h2 id="the-field-test-went-horribly-wrong">The field test went horribly wrong</h2>
<p>After we moved most of the code to async we did a small test and it worked quite good. Our gut feelings were OK-ish, because we knew that we didn’t do a full stress test.</p>
<p>As always: Things didn’t work as expected. We deployed the code on our largest customer and it did: Nothing.</p>
<h2 id="100-cpu">100% CPU</h2>
<p>We knew that after the deployment we would hit a high load and at first it seems to “work” based on the CPU workload, but nothing happend.
I checked the SQL monitoring and noticed that the throughput was ridiculous low. One query (which every client needed to execute) caught my attention, because the query itself was super simple, but somehow was the showstopper for everyone.</p>
<h2 id="the-bad-query">The “bad query”</h2>
<p>I checked the code and it was more or less something like this (with the help of EntityFramework 6)</p>
<p>var result = await dbContext.Configuration.ToListAsync();</p>
<p>The “Configuration” itself is a super simple table with a Key &amp; Value column.</p>
<p>Be aware that the same code worked OK with the non async implementation!</p>
<h2 id="cause">“Cause”</h2>
<p>This call was extremely costly in terms of performance, but why? It turns out, that this customer installation had a pretty large configuration. One value was around 10MB, which doesn’t sound that much, but if this code is executed in parallel with 5000 clients, it can hurt.</p>
<p><strong>On top of that:</strong> The async implementation tries to be smart, but this leads to thousand of task creations, which will slow down everything.</p>
<p>This <strong><a href="https://stackoverflow.com/a/28619983">stackoverflow answer</a></strong> really helped me to understand this problem. Just look at those figures:</p>
<blockquote>
<p>First, in the first case we were having just 3500 hit counts along the full call path, here we have 118 371. Moreover, you have to imagine all the synchronization calls I didn’t put on the screenshoot…</p>
<p>Second, in the first case, we were having “just 118 353” calls to the TryReadByteArray() method, here we have 2 050 210 calls ! It’s 17 times more… (on a test with large 1Mb array, it’s 160 times more)</p>
<p>Moreover there are:</p>
<ul>
<li>120 000 Task instances created</li>
<li>727 519 Interlocked calls</li>
<li>290 569 Monitor calls</li>
<li>98 283 ExecutionContext instances, with 264 481 Captures</li>
<li>208 733 SpinLock calls</li>
</ul>
<p>My guess is the buffering is made in an async way (and not a good one), with parallel Tasks trying to read data from the TDS. Too many Task are created just to parse the binary data.
…</p>
</blockquote>
<h2 id="switch-to-adonet-damn-ef-right">Switch to ADO.NET, damn EF, right?</h2>
<p>If you are now thinking: “Yeah… EF sucks, right, use just plain ADO.NET!” you will end up in the same mess, because the default ExecuteAsync-reader is used in the EntityFramework.</p>
<h2 id="i-use-ef-core-am-i-save">I use EF Core, am I save?</h2>
<p>The same problem applies to EF Core, just checkout <a href="https://github.com/aspnet/EntityFramework6/issues/88#issuecomment-256103455">this comment</a> by the EF Team.</p>
<p>How can we solve this problem then?</p>
<h2 id="solution-1-async-but-with-sequential-read">Solution 1: Async, but with Sequential read</h2>
<p>I changed the code to use plain ADO.NET, but with <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idbcommand.executereader?view=netframework-4.7.2">CommandBehavior.Sequential</a> access.</p>
<p>This way it seems that the async implementation is much smarter how to read large chunks of data. I’m not an ADO.NET expert, but with the default strategy ADO.NET tries to read the whole row and stores it in memory. With the sequential access it can use the memory more effective - at least, it seems to work much better.</p>
<p>Your code also needs to be implemented with sequential access in mind, otherwise it will fail.</p>
<h2 id="solution-2-avoid-large-type-like-nvarcharmax">Solution 2: Avoid large type like nvarchar(max)</h2>
<p>This advice comes from the EF team:</p>
<p><em>Avoid using NTEXT, TEXT, IMAGE, TVP, UDT, XML, [N]VARCHAR(MAX) and VARBINARY(MAX) – the maximum data size for these types is so large that it is very unusual (or even impossible) that they would happen to be able to fit within a single packet.</em></p>
<p>When we need to store large content, we typically use a separat blob table and <a href="https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sqlclient-streaming-support">stream</a> those values to the clients. This works quite well, but we forgot our “configuration” table :-)</p>
<p>When I now look at this problem it seems obvious, but we had some hard days to fix the issue.</p>
<p><strong>Hope this helps.</strong></p>
<p>Helpful links:</p>
<ul>
<li><a href="https://entityframework.net/why-ef-async-methods-are-slow">Why EF async methods are slower than non-async?</a></li>
<li><a href="https://github.com/aspnet/EntityFramework6/issues/88">EF GitHub Issue: Performance issue when querying varbinary(MAX), varchar(MAX), nvarchar(MAX) or XML with Async</a></li>
<li><a href="https://stackoverflow.com/a/28619983">Stackoverflow answer</a></li>
</ul>
https://blog.codeinside.eu/2018/09/26/be-afraid-of-varcharmax-with-async-ef-adonet/
https://blog.codeinside.eu/2018/09/26/be-afraid-of-varcharmax-with-async-ef-adonetWed, 26 Sep 2018 23:45:00 +0000Migrate a .NET library to .NET Core / .NET Standard 2.0
<p>I have a small spare time project called <strong><a href="https://github.com/Code-Inside/Sloader/">Sloader</a></strong> and I recently moved the code base to .NET Standard 2.0. This blogpost covers how I moved this library to .NET Standard.</p>
<h1 id="uhmmm-wait-what-is-net-standard">Uhmmm… wait… what is .NET Standard?</h1>
<p>If you have been living under a rock in the past year: <strong><a href="https://docs.microsoft.com/en-us/dotnet/standard/net-standard">.NET Standard</a></strong> is a kind of “contract” that allows the library to run under all .NET implementations like the full .NET Framework or .NET Core.
But hold on: The library might also run under Unity, Xamarin and Mono (and future .NET implementations that support this contract - that’s why it is called “Standard”). So - in general: This is a great thing!</p>
<h1 id="sloader---before-net-standard">Sloader - before .NET Standard</h1>
<p>Back to my spare time project:</p>
<p>Sloader consists of three projects (Config/Result/Engine) and targeted the full .NET Framework. All projects were typical library projects. All components were tested with xUnit and builded via Cake. The configuration is using YAML and the main work is done via the HttpClient.</p>
<p>To summarize it: The library is a not too trivial example, but in general it has pretty low requirements.</p>
<h1 id="sloader---moving-to-net-standard-20">Sloader - moving to .NET Standard 2.0</h1>
<p>The blogpost from Daniel Crabtee <strong><a href="https://www.danielcrabtree.com/blog/314/upgrading-to-net-core-and-net-standard-made-easy">“Upgrading to .NET Core and .NET Standard Made Easy”</a></strong> was a great resource and if you want to migrate you should check his blogpost.</p>
<p>The best advice from the blogpost: <strong>Just create new .NET Standard projects and xcopy your files to the new projects.</strong></p>
<p>To migrate the projects to .NET Standard I really just needed to deleted the old .csproj files and copied everything into new .NET Standard library projects.</p>
<p>After some fine tuning and NuGet package reference updates everything compilied.</p>
<p>This <a href="https://github.com/Code-Inside/Sloader/pull/35/files">GitHub PR</a> shows the result of the migration.</p>
<h1 id="problems--aftermath">Problems &amp; Aftermath</h1>
<p>In my library I still used the old way to access configuration via the ConfigurationManager class (referenced via the <a href="https://www.nuget.org/packages/System.Configuration.ConfigurationManager/">official NuGet package</a>). This API is not supported on every platform (e.g. Azure Functions), so I needed to tweak those code parts to use System.Environment Variables (this is in my example OK, but there are other options as well).</p>
<p>Everthing else “just worked” and it was a great experience. I tried the same thing with .NET Core 1.0 and it failed horrible, but this time the migration was more or less painless.</p>
<h1 id="net-portability-analyzer">.NET Portability Analyzer</h1>
<p>If you are not sure if your code works under .NET Standard or Core just install the <a href="https://marketplace.visualstudio.com/items?itemName=ConnieYau.NETPortabilityAnalyzer">.NET Portability Analyzer</a>.</p>
<p>This handy tool will give you an overwhy which parts might run without problems under .NET Standard or .NET Core.</p>
<h1 id="net-standard-20-and-net-framework">.NET Standard 2.0 and .NET Framework</h1>
<p>If you still targeting the full Framework, make sure you use at least .NET Framework Version <strong>4.7.2</strong>. In theory .NET Standard 2.0 was supposed to work under .NET 4.6.1, but it seems that this <a href="https://twitter.com/terrajobst/status/1031999730320986112">ended not too well</a>:</p>
<blockquote class="twitter-tweet" data-lang="de"><p lang="en" dir="ltr">Sorry but we messed up. We tried to make .NET Framework 4.6.1 retroactively implement .NET Standard 2.0. This was a mistake as we don&#39;t have a time machine and there is a tail of bugs.<br /><br />If you want to consume .NET Standard 1.5+ from .NET Framework, I recommend to be on 4.7.2. <a href="https://t.co/E7H2Ps9cLk">https://t.co/E7H2Ps9cLk</a></p>&mdash; Immo Landwerth (@terrajobst) <a href="https://twitter.com/terrajobst/status/1031999730320986112?ref_src=twsrc%5Etfw">21. August 2018</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Hope this helps and encourage you to try a migration to a more modern stack!</p>
https://blog.codeinside.eu/2018/08/30/migrate-a-library-to-dotnetcore/
https://blog.codeinside.eu/2018/08/30/migrate-a-library-to-dotnetcoreThu, 30 Aug 2018 22:45:00 +0000Improving Code
<h1 id="improving-code">Improving code</h1>
<h2 id="tldr">TL;DR;</h2>
<p><strong>Things I learned:</strong></p>
<ul>
<li>long one-liners are hard to read and understand</li>
<li>split up your code into small, easy to understand functions</li>
<li>less “plumping” (read infrastructure code) is the better</li>
<li>get <a href="https://en.wikipedia.org/wiki/Indentation_style">indentation</a> right</li>
<li>“Make it correct, make it clear, make it concise, make it fast. In that order.” Wes Dyer</li>
</ul>
<p><strong>Why should I bother?</strong></p>
<p>Readable code is:</p>
<ul>
<li>easier to debug</li>
<li>fast to fix</li>
<li>easier to maintain</li>
</ul>
<h2 id="the-problem">The problem</h2>
<p>Recently I wanted to implement an algorithm for a project we are doing. The goal was to create a so-called “Balanced Latin Square”, we used it to prevent ordering effects in user studies. You can find a little bit of background <a href="http://www.statisticshowto.com/latin-square-design/">here</a> and a nice description of the algorithm <a href="http://rintintin.colorado.edu/~chathach/balancedlatinsquares.html">here</a>.</p>
<p>It’s fairly simple, although it is not obvious how it works, just by looking at the code. The function takes an integer as an argument and returns a Balanced Latin Square. For example, a “4” would return this matrix of numbers:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1 2 4 3
2 3 1 4
3 4 2 1
4 1 3 2
</code></pre></div></div>
<p>And there is a little twist if your number is odd, then you need to reverse every row and append them to your result.</p>
<p>After I created the my implementation, I had an idea on how to simplify it. At least I thought its simpler ;)</p>
<h2 id="first-attempt----loops">First attempt - Loops</h2>
<p>Based on the description and a Python version of that algorithm, I created a classical (read “imperative”) implementation.</p>
<p>So this is the C# Code:</p>
<div class="language-c# highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">List</span><span class="p">&lt;</span><span class="n">String</span><span class="p">&gt;&gt;</span> <span class="nf">BalancedLatinSquares</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">List</span><span class="p">&lt;</span><span class="n">String</span><span class="p">&gt;&gt;()</span> <span class="p">{</span> <span class="p">};</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">row</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">String</span><span class="p">&gt;();</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">j</span> <span class="p">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="p">++)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">cell</span> <span class="p">=</span> <span class="p">((</span><span class="n">j</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">1</span> <span class="p">?</span> <span class="n">j</span> <span class="p">/</span> <span class="m">2</span> <span class="p">+</span> <span class="m">1</span> <span class="p">:</span> <span class="n">n</span> <span class="p">-</span> <span class="n">j</span> <span class="p">/</span> <span class="m">2</span><span class="p">)</span> <span class="p">+</span> <span class="n">i</span><span class="p">)</span> <span class="p">%</span> <span class="n">n</span><span class="p">;</span>
<span class="n">cell</span><span class="p">++;</span> <span class="c1">// start counting from 1</span>
<span class="n">row</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">cell</span><span class="p">.</span><span class="nf">ToString</span><span class="p">());</span>
<span class="p">}</span>
<span class="n">result</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">row</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">reversedResult</span> <span class="p">=</span> <span class="n">result</span><span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span><span class="p">.</span><span class="nf">AsQueryable</span><span class="p">().</span><span class="nf">Reverse</span><span class="p">().</span><span class="nf">ToList</span><span class="p">()).</span><span class="nf">ToList</span><span class="p">();</span>
<span class="n">result</span><span class="p">.</span><span class="nf">AddRange</span><span class="p">(</span><span class="n">reversedResult</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>I also wrote some simple unit tests to ensure this works. But in the end, I really didn’t like this code. It contains two nested loops and a lot of plumbing code. There are four lines alone just to create the result object (list) and to add the values to it. Recently I looked into functional programming and since C# also has some functional inspired features, I tried to improve this code with some functional goodness :)</p>
<h2 id="second-attempt---lambda-expressions">Second attempt - Lambda Expressions</h2>
<div class="language-c# highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">List</span><span class="p">&lt;</span><span class="n">String</span><span class="p">&gt;&gt;</span> <span class="nf">BalancedLatinSquares</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="n">Enumerable</span><span class="p">.</span><span class="nf">Range</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">i</span> <span class="p">=&gt;</span>
<span class="n">Enumerable</span><span class="p">.</span><span class="nf">Range</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">n</span><span class="p">).</span><span class="nf">Select</span><span class="p">(</span><span class="n">j</span> <span class="p">=&gt;</span> <span class="p">((((</span><span class="n">j</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">1</span> <span class="p">?</span> <span class="n">j</span> <span class="p">/</span> <span class="m">2</span> <span class="p">+</span> <span class="m">1</span> <span class="p">:</span> <span class="n">n</span> <span class="p">-</span> <span class="n">j</span> <span class="p">/</span> <span class="m">2</span><span class="p">)</span> <span class="p">+</span> <span class="n">i</span><span class="p">)</span> <span class="p">%</span> <span class="n">n</span><span class="p">)+</span><span class="m">1</span><span class="p">).</span><span class="nf">ToString</span><span class="p">()).</span><span class="nf">ToList</span><span class="p">()</span>
<span class="p">)</span>
<span class="p">.</span><span class="nf">ToList</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">reversedResult</span> <span class="p">=</span> <span class="n">result</span><span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span><span class="p">.</span><span class="nf">AsQueryable</span><span class="p">().</span><span class="nf">Reverse</span><span class="p">().</span><span class="nf">ToList</span><span class="p">()).</span><span class="nf">ToList</span><span class="p">();</span>
<span class="n">result</span><span class="p">.</span><span class="nf">AddRange</span><span class="p">(</span><span class="n">reversedResult</span><span class="p">);</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This is the result of my attempt to use some functional features. And hey, it is much shorter, therefore it must be better, right? Well, <a href="https://twitter.com/oliverguhr/status/1022395269026070528">I posted a screenshot of both versions on Twitter</a> and asked which one the people prefer. As it turned out, a lot of folks actually preferred the loop version. But why? Looking back at my code a saw two problems by looking at this line:</p>
<p><code class="highlighter-rouge">Enumerable.Range(0, n).Select(j =&gt; ((((j % 2 == 1 ? j / 2 + 1 : n - j / 2) + i) % n)+1).ToString()).ToList()</code></p>
<ul>
<li>I squeezed a lot of code in this one liner. This makes it harder to read and therefore harder to understand.</li>
<li>Another issue is, that I omitted descriptive variable names since they are not needed anymore. Oh and I removed the only comment I wrote since this comment would not fit in the one line of code :)</li>
</ul>
<p>So, shorter is not always better.</p>
<h2 id="third-attempt---better-lambda-expressions">Third attempt - better Lambda Expressions</h2>
<p>The smart folks on Twitter had some great ideas about how to improve my code.</p>
<p>The first step was to get rid of the unholy one-liner. You can - and should - always split up your code into smaller, meaningful code blocks. I pulled out the <em>calculateCell</em> function and out of that I also extracted a <em>isEven</em> function. The nice thing is, that the function names also working as a kind of documentation about whats going on.</p>
<p>By returning IEnumerable instead of lists, I was able to remove some <em>.toList()</em> calls. Also, I was able to shorten the code to create the <em>reversedResult</em>.</p>
<p>Another simple step to improve readability is to get line <a href="https://en.wikipedia.org/wiki/Indentation_style">indentation</a> right. Personally, I don’t care which indentation style people are using, as long as it’s used consistently.</p>
<div class="language-c# highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;&gt;</span> <span class="nf">GenerateBalancedLatinSquares</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">bool</span> <span class="nf">isEven</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">i</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">0</span><span class="p">;</span>
<span class="kt">int</span> <span class="nf">calculateCell</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="p">,</span> <span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="p">=&gt;((</span><span class="nf">isEven</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="p">?</span> <span class="n">n</span> <span class="p">-</span> <span class="n">j</span> <span class="p">/</span> <span class="m">2</span> <span class="p">:</span> <span class="n">j</span> <span class="p">/</span> <span class="m">2</span> <span class="p">+</span> <span class="m">1</span><span class="p">)</span> <span class="p">+</span> <span class="n">i</span><span class="p">)</span> <span class="p">%</span> <span class="n">n</span> <span class="p">+</span> <span class="m">1</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="n">Enumerable</span>
<span class="p">.</span><span class="nf">Range</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">row</span> <span class="p">=&gt;</span>
<span class="n">Enumerable</span>
<span class="p">.</span><span class="nf">Range</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">col</span> <span class="p">=&gt;</span><span class="nf">calculateCell</span><span class="p">(</span><span class="n">col</span><span class="p">,</span><span class="n">row</span><span class="p">))</span>
<span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nf">isEven</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="p">!=</span> <span class="k">false</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">reversedResult</span> <span class="p">=</span> <span class="n">result</span><span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span><span class="p">.</span><span class="nf">Reverse</span><span class="p">());</span>
<span class="n">result</span> <span class="p">=</span> <span class="n">result</span><span class="p">.</span><span class="nf">Concat</span><span class="p">(</span><span class="n">reversedResult</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span><span class="n">conditional</span>
<span class="p">}</span>
</code></pre></div></div>
<p>I think there is room for further improvement. For the <em>calculateCell</em> function I am using this <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator">?: conditional operator</a>, it allows you to write very compact code, on the other hand, it’s also harder to read. If you would replace this with an <em>if</em> statement you would need more lines of code, but also have more space to add comments. Functional languages like Scala, F#, and Haskel providing this neat <em>match</em> expression that could help here.</p>
<h2 id="extra-how-does-this-algorithm-look-in-other-languages">Extra: How does this algorithm look in other languages:</h2>
<p><strong>Python</strong></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">balanced_latin_squares</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="n">l</span> <span class="o">=</span> <span class="p">[[((</span><span class="n">j</span><span class="o">/</span><span class="mi">2</span><span class="o">+</span><span class="mi">1</span> <span class="k">if</span> <span class="n">j</span><span class="o">%</span><span class="mi">2</span> <span class="k">else</span> <span class="n">n</span><span class="o">-</span><span class="n">j</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="n">i</span><span class="p">)</span> <span class="o">%</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">)]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">)]</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">%</span> <span class="mi">2</span><span class="p">:</span> <span class="c"># Repeat reversed for odd n</span>
<span class="n">l</span> <span class="o">+=</span> <span class="p">[</span><span class="n">seq</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">seq</span> <span class="ow">in</span> <span class="n">l</span><span class="p">]</span>
<span class="k">return</span> <span class="n">l</span>
</code></pre></div></div>
<p>I took this sample from <a href="https://gist.github.com/graup/70b09323bfa7182fe693eecb8e749896#file-balanced_latin_squares-py">Paul Grau.</a></p>
<p><strong>Haskell</strong></p>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="de"><p lang="en" dir="ltr">Haskell: <a href="https://t.co/P5rFqvgvgA">pic.twitter.com/P5rFqvgvgA</a></p>&mdash; λx.x Carsten (@CarstenK_Dev) <a href="https://twitter.com/CarstenK_Dev/status/1022404328529829888?ref_src=twsrc%5Etfw">26. Juli 2018</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Thank you <a href="https://twitter.com/CarstenK_Dev">Carsten</a></p>
https://blog.codeinside.eu/2018/08/03/improving-code/
https://blog.codeinside.eu/2018/08/03/improving-codeFri, 03 Aug 2018 09:00:00 +0000Easy way to copy a SQL database with Microsoft SQL Server Management Studio (SSMS)
<h1 id="how-to-copy-a-database-on-the-same-sql-server">How to copy a database on the same SQL server</h1>
<p>The scenario is pretty simple: We just want a copy of our database, with all the data and the complete scheme and permissions.</p>
<h2 id="1-step-make-a-back-up-of-your-source-database">1. step: Make a back up of your source database</h2>
<p>Click on the desired database and choose “Backup” under tasks.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-07-31/1_BackupTask.png" alt="x" title="Backup the database" /></p>
<h2 id="2-step-use-copy-only-or-use-a-full-backup">2. step: Use copy only or use a full backup</h2>
<p>In the dialog you may choose “copy-only” backup. With this option the regular backup job will not be confused.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-07-31/2_BackupOptions.png" alt="x" title="Copy only" /></p>
<h2 id="3-step-use-restore-to-create-a-new-database">3. step: Use “Restore” to create a new database</h2>
<p>This is the most important point here: To avoid fighting against database-file namings use the “restore” option. <strong>Don’t</strong> create a database manually - this is part of the restore operation.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-07-31/3_restoredatabase.png" alt="x" title="Restore database" /></p>
<h2 id="4-step-choose-the-copy-only-backup-and-choose-a-new-name">4. step: Choose the copy-only backup and choose a new name</h2>
<p>In this dialog you can name the “copy” database and choose the copy-only backup from the source database.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-07-31/4_copydb.png" alt="x" title="Restore dialog" /></p>
<p>Now click ok and you are done!</p>
<h2 id="behind-the-scenes">Behind the scenes</h2>
<p>This restore operation works way better to copy a database then to overwrite an existing database, because the restore operation will adjust the filenames.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-07-31/5_copydb_setting.png" alt="x" title="Filename settings" /></p>
<h2 id="further-information">Further information</h2>
<p>I’m not a DBA, but when I follow these steps I normally have nothing to worry about if I want a 1:1 copy of a database. This can also be scripted, but then you may need to worry about filenames.</p>
<p>This <a href="https://stackoverflow.com/questions/3829271/how-can-i-clone-an-sql-server-database-on-the-same-server-in-sql-server-2008-exp">stackoverflow question</a> is full of great answers!</p>
<p>Hope this helps!</p>
https://blog.codeinside.eu/2018/07/31/easy-way-to-copy-a-sql-database-with-ssms/
https://blog.codeinside.eu/2018/07/31/easy-way-to-copy-a-sql-database-with-ssmsTue, 31 Jul 2018 23:45:00 +0000DbProviderFactories & ODP.NET: When even Oracle can be tamed
<h1 id="oracle-and-net-tales-from-the-dark-ages">Oracle and .NET: Tales from the dark ages</h1>
<p>Each time when I tried to load data from an Oracle database it was a pretty terrible experience.</p>
<p>I remember that I struggle to find the right Oracle driver and even when everything was installed the strange TNS ora config file popped up and nothing worked.</p>
<h1 id="it-can-be-simple">It can be simple…</h1>
<p>2 weeks ago I had the pleasure to load some data from a Oracle database and discovered something beautiful: Actually, I can be pretty simple today.</p>
<h1 id="the-way-to-success">The way to success:</h1>
<p><strong>1. Just ignore the <a href="https://msdn.microsoft.com/en-us/library/system.data.oracleclient(v=vs.110).aspx">System.Data.OracleClient-Namespace</a></strong></p>
<p>The implementation is pretty old and if you go this route you will end up with the terrible “Oracle driver/tns.ora”-chaos mentioned above.</p>
<p><strong>2. Use the <a href="https://www.nuget.org/packages/Oracle.ManagedDataAccess/">Oracle.ManagedDataAccess</a>:</strong></p>
<p>Just install the official NuGet package and you are done. The single .dll contains all the bits to connect to an Oracle database. <strong>No</strong> driver installation additional software is needed. Yay!</p>
<p>The NuGet package will add some config entries in your web.config or app.config. I will cover this in the section below.</p>
<p><strong>3. Use sane ConnectionStrings:</strong></p>
<p>Instead of the wild Oracle TNS config stuff, just use (a more or less) sane ConnectionString.</p>
<p>You can either just use the same configuration you would normally do in the TNS file, like <a href="https://www.connectionstrings.com/oracle-data-provider-for-net-odp-net/using-odpnet-without-tnsnamesora/">this</a>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=MyHost)(PORT=MyPort)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=MyOracleSID)));User Id=myUsername;Password=myPassword;
</code></pre></div></div>
<p>Or use the even simpler <a href="http://www.oracle.com/technetwork/database/enterprise-edition/oraclenetservices-neteasyconnect-133058.pdf">“easy connect name schema”</a> like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Data Source=username/password@myserver//instancename;
</code></pre></div></div>
<h1 id="dbproviderfactories--odpnet">DbProviderFactories &amp; ODP.NET</h1>
<p>As I mentioned earlier after the installation your web or app.config might look different.</p>
<p>The most interesting addition is the registration in the DbProviderFactories-section:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
<span class="nt">&lt;system.data&gt;</span>
<span class="nt">&lt;DbProviderFactories&gt;</span>
<span class="nt">&lt;remove</span> <span class="na">invariant=</span><span class="s">"Oracle.ManagedDataAccess.Client"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;add</span> <span class="na">name=</span><span class="s">"ODP.NET, Managed Driver"</span> <span class="na">invariant=</span><span class="s">"Oracle.ManagedDataAccess.Client"</span> <span class="na">description=</span><span class="s">"Oracle Data Provider for .NET, Managed Driver"</span>
<span class="na">type=</span><span class="s">"Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/DbProviderFactories&gt;</span>
<span class="nt">&lt;/system.data&gt;</span>
...
</code></pre></div></div>
<p>I covered this topic a while ago in an <a href="https://blog.codeinside.eu/2016/12/31/dbproviderfactory-write-database-agnostic-adonet-code/">older blogpost</a>, but to keep it simple: <strong>It also works for Oracle!</strong></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">private</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">OracleTest</span><span class="p">()</span>
<span class="p">{</span>
<span class="kt">string</span> <span class="n">constr</span> <span class="p">=</span> <span class="s">"Data Source=localhost;User Id=...;Password=...;"</span><span class="p">;</span>
<span class="n">DbProviderFactory</span> <span class="n">factory</span> <span class="p">=</span> <span class="n">DbProviderFactories</span><span class="p">.</span><span class="nf">GetFactory</span><span class="p">(</span><span class="s">"Oracle.ManagedDataAccess.Client"</span><span class="p">);</span>
<span class="k">using</span> <span class="p">(</span><span class="n">DbConnection</span> <span class="n">conn</span> <span class="p">=</span> <span class="n">factory</span><span class="p">.</span><span class="nf">CreateConnection</span><span class="p">())</span>
<span class="p">{</span>
<span class="k">try</span>
<span class="p">{</span>
<span class="n">conn</span><span class="p">.</span><span class="n">ConnectionString</span> <span class="p">=</span> <span class="n">constr</span><span class="p">;</span>
<span class="n">conn</span><span class="p">.</span><span class="nf">Open</span><span class="p">();</span>
<span class="k">using</span> <span class="p">(</span><span class="n">DbCommand</span> <span class="n">dbcmd</span> <span class="p">=</span> <span class="n">conn</span><span class="p">.</span><span class="nf">CreateCommand</span><span class="p">())</span>
<span class="p">{</span>
<span class="n">dbcmd</span><span class="p">.</span><span class="n">CommandType</span> <span class="p">=</span> <span class="n">CommandType</span><span class="p">.</span><span class="n">Text</span><span class="p">;</span>
<span class="n">dbcmd</span><span class="p">.</span><span class="n">CommandText</span> <span class="p">=</span> <span class="s">"select name, address from contacts WHERE UPPER(name) Like UPPER('%' || :name || '%') "</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">dbParam</span> <span class="p">=</span> <span class="n">dbcmd</span><span class="p">.</span><span class="nf">CreateParameter</span><span class="p">();</span>
<span class="c1">// prefix with : possible, but @ will be result in an error</span>
<span class="n">dbParam</span><span class="p">.</span><span class="n">ParameterName</span> <span class="p">=</span> <span class="s">"name"</span><span class="p">;</span>
<span class="n">dbParam</span><span class="p">.</span><span class="n">Value</span> <span class="p">=</span> <span class="s">"foobar"</span><span class="p">;</span>
<span class="n">dbcmd</span><span class="p">.</span><span class="n">Parameters</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">dbParam</span><span class="p">);</span>
<span class="k">using</span> <span class="p">(</span><span class="n">DbDataReader</span> <span class="n">dbrdr</span> <span class="p">=</span> <span class="n">dbcmd</span><span class="p">.</span><span class="nf">ExecuteReader</span><span class="p">())</span>
<span class="p">{</span>
<span class="k">while</span> <span class="p">(</span><span class="n">dbrdr</span><span class="p">.</span><span class="nf">Read</span><span class="p">())</span>
<span class="p">{</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">dbrdr</span><span class="p">[</span><span class="m">0</span><span class="p">]);</span>
<span class="p">}</span>
<span class="p">}</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="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">ex</span><span class="p">.</span><span class="n">Message</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">ex</span><span class="p">.</span><span class="n">StackTrace</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h1 id="mssql-mysql-and-oracle---via-dbproviderfactories">MSSQL, MySql and Oracle - via DbProviderFactories</h1>
<p>The above code is a snippet from my larger sample demo covering <strong>MSSQL</strong>, <strong>MySQL</strong> and <strong>Oracle</strong>. If you are interested just check this demo on <a href="https://github.com/Code-Inside/Samples/tree/master/2018/OracleMySqlMsSqlViaGenericSql"><strong>GitHub</strong></a>.</p>
<p>Each SQL-Syntax teats parameter a bit different, so make sure you use the correct syntax for your target database.</p>
<h1 id="bottom-line">Bottom line</h1>
<p>Accessing a Oracle database from .NET doesn’t need to be a pain nowadays.</p>
<p>Be aware that the ODP.NET provider might surface higher level APIs to work with Oracle databases. The dbProviderfactory-approach helped us for our simple “just load some data”-scenario.</p>
<p>Hope this helps.</p>
https://blog.codeinside.eu/2018/06/01/dbproviderfactories-and-odpdotnet-when-even-oracle-can-be-tamed/
https://blog.codeinside.eu/2018/06/01/dbproviderfactories-and-odpdotnet-when-even-oracle-can-be-tamedFri, 01 Jun 2018 18:00:00 +0000CultureInfo.GetCultureInfo() vs. new CultureInfo() - what's the difference?
<h1 id="the-problem">The problem</h1>
<p>The problem started with a simple code:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>double.TryParse("1'000", NumberStyles.Any, culture, out _)
</code></pre></div></div>
<p>Be aware that the given culture was “DE-CH” and the Swiss use the ‘ for the separator for numbers.</p>
<p>Unfortunately the <a href="https://www.bk.admin.ch/bk/de/home/dokumentation/sprachen/hilfsmittel-textredaktion/schreibweisungen.html">Swiss authorities</a> have abandoned the ‘ for currencies, but it is widly used in the industrie and such a number should be parsed or displayed.</p>
<p>Now Microsoft steps in and they use a very similar char in the “DE-CH” region setting:</p>
<ul>
<li>The backed in char to separate numbers: ‘ (CharCode: 8217)</li>
<li>The obvious choice would be: ‘ (CharCode: 39)</li>
</ul>
<p><strong>The result of this configuration hell:</strong></p>
<p>If you don’t change the region settings in Windows you can’t parse doubles with this fancy group separator.</p>
<p><strong>Stranger things:</strong></p>
<p>My work machine is running the EN-US version of Windows and my tests where failing because of this madness, but it was even stranger: Some other tests (quite similar to what I did) were OK on our company DE-CH machines.</p>
<h1 id="but-why">But… why?</h1>
<p>After some crazy time I discovered that our company DE-CH machines (and the machines from our customer) were using the “sane” group separator, but my code still didn’t work as expected.</p>
<h1 id="root-cause">Root cause</h1>
<p>The root problem (besides the stupid char choice) was this: I used the “wrong” method to get the “DE-CH” culture in my code.</p>
<p>Let’s try out this demo code:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Program</span>
<span class="p">{</span>
<span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">culture</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">CultureInfo</span><span class="p">(</span><span class="s">"de-CH"</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"de-CH Group Separator"</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span>
<span class="s">$"</span><span class="p">{</span><span class="n">culture</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">CurrencyGroupSeparator</span><span class="p">}</span><span class="s"> - CharCode: </span><span class="p">{(</span><span class="kt">int</span><span class="p">)</span> <span class="kt">char</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">culture</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">CurrencyGroupSeparator</span><span class="p">)}</span><span class="s">"</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span>
<span class="s">$"</span><span class="p">{</span><span class="n">culture</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberGroupSeparator</span><span class="p">}</span><span class="s"> - CharCode: </span><span class="p">{(</span><span class="kt">int</span><span class="p">)</span> <span class="kt">char</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">culture</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberGroupSeparator</span><span class="p">)}</span><span class="s">"</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">cultureFromFramework</span> <span class="p">=</span> <span class="n">CultureInfo</span><span class="p">.</span><span class="nf">GetCultureInfo</span><span class="p">(</span><span class="s">"de-CH"</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"de-CH Group Separator from Framework"</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span>
<span class="s">$"</span><span class="p">{</span><span class="n">cultureFromFramework</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">CurrencyGroupSeparator</span><span class="p">}</span><span class="s"> - CharCode: </span><span class="p">{(</span><span class="kt">int</span><span class="p">)</span><span class="kt">char</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">cultureFromFramework</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">CurrencyGroupSeparator</span><span class="p">)}</span><span class="s">"</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span>
<span class="s">$"</span><span class="p">{</span><span class="n">cultureFromFramework</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberGroupSeparator</span><span class="p">}</span><span class="s"> - CharCode: </span><span class="p">{(</span><span class="kt">int</span><span class="p">)</span><span class="kt">char</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">cultureFromFramework</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberGroupSeparator</span><span class="p">)}</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The result should be something like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>de-CH Group Separator
' - CharCode: 8217
' - CharCode: 8217
de-CH Group Separator from Framework
' - CharCode: 8217
' - CharCode: 8217
</code></pre></div></div>
<p>Now change the region setting for de-CH and see what happens:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-05-28/regionsettings.png" alt="x" title="Changed region settings" /></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>de-CH Group Separator
' - CharCode: 8217
X - CharCode: 88
de-CH Group Separator from Framework
' - CharCode: 8217
' - CharCode: 8217
</code></pre></div></div>
<p>Only the CultureInfo from the first instance got the change!</p>
<h1 id="modified-vs-read-only">Modified vs. read-only</h1>
<p>The problem can be summerized with: <a href="https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.getcultureinfo(v=vs.110).aspx">RTFM</a>!</p>
<p>From the MSDN for GetCultureInfo: <em>Retrieves a cached, read-only instance of a culture.</em></p>
<p>The <a href="https://msdn.microsoft.com/en-us/library/205h6kwc(v=vs.110).aspx">“new CultureInfo” constructor</a> will pick up the changed settings from Windows.</p>
<h1 id="tldr">TL;DR:</h1>
<ul>
<li>CultureInfo.GetCultureInfo will return a “backed in” culture, which might be very fast, but doesn’t respect user changes.</li>
<li>If you need to use the modified values from windows: Use the normal CultureInfo constructor.</li>
</ul>
<p>Hope this helps!</p>
https://blog.codeinside.eu/2018/05/28/cultureinfo-getculture-vs-new-cultureinfo/
https://blog.codeinside.eu/2018/05/28/cultureinfo-getculture-vs-new-cultureinfoMon, 28 May 2018 23:45:00 +0000.editorconfig: Sharing a common coding style in a team
<h1 id="sharing-coding-styles--conventions">Sharing Coding Styles &amp; Conventions</h1>
<p>In a team it is really important to set coding conventions and to use a specific coding style, because it helps to maintain the code - <strong>a lot</strong>.
Of course has each developer his own “style”, but some rules should be set, otherwise it will end in a mess.</p>
<p>Typical examples for such rules are “Should I use var or not?” or “Are _ still OK for private fields?”. Those questions shouldn’t be answered in a Wiki - it should be part of the daily developer life and should show up in your IDE!</p>
<p><em>Be aware that coding conventions are highly debated. In our team it was important to set a commpon ruleset, even if not everyone is 100% happy with each setting.</em></p>
<h1 id="embrace--enforce-the-conventions">Embrace &amp; enforce the conventions</h1>
<p>In the past this was the most “difficult” aspect: How do we enforce these rules?</p>
<p>Rules in a Wiki are not really helpful, because if you are in your favorite IDE you might not notice rule violations.</p>
<p><a href="https://blogs.msdn.microsoft.com/sourceanalysis/">Stylecop</a> was once a thing in the Visual Studio World, but I’m not sure if this is still alive.</p>
<p>Resharper, a pretty useful Visual Studio plugin, comes with it’s own code convention sharing file, but you will need Resharper to enforce and embrace the conventions.</p>
<h1 id="introducing-editorconfig">Introducing: .editorconfig</h1>
<p>Last year Microsoft decided to support the <a href="http://editorconfig.org/">.EditorConfig</a> file format in Visual Studio.</p>
<p>The .editorconfig defines a set of common coding styles (think of tabs or spaces) in a very simple format. Different text editors and IDEs support this file, which makes it a good choice if you are using multiple IDEs or working with different setups.</p>
<p>Additionally Microsoft added a couple of <a href="https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference">C# related options</a> for the editorconfig file to support the C# language features.</p>
<p>Each rule can be marked as “Information”, “Warning” or “Error” - which will light up in your IDE.</p>
<h1 id="sample">Sample</h1>
<p>This was a tough choice, but I ended up with the <a href="https://github.com/dotnet/coreclr/blob/master/.editorconfig"><strong>.editorconfig of the CoreCLR</strong></a>. It is more or less the “normal” .NET style guide. I’m not sure if I love the the “var”-setting and the “static private field naming (like s_foobar)”, but I can live with them and it was a good starting point for us (and still is).</p>
<p>The .editorconfig file can be saved at the same level as the .sln file, but you can also use multiple .editorconfig files based on the folder structure. Visual Studio should detect the file and apply the rules.</p>
<h1 id="benefits">Benefits</h1>
<p>When everything is ready Visual Studio should populate the results and show the light blub notification:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-04-30/editorconfig.png" alt="x" title=".editorconfig in VS" /></p>
<p><em>Be aware that I have Resharper installed and Resharper has it’s own ruleset, which might be in conflict with the .editorconfig setting. You need to adjust those settings in Resharper. I’m still not 100% sure how good the .editorconfig support is, sometimes I need to overwrite the backed in Resharper settings and sometimes it just works. Maybe this page gives a <a href="https://www.jetbrains.com/help/resharper/Using_EditorConfig.html">hint</a></em>.</p>
<h1 id="getting-started">Getting started?</h1>
<p>Just search for a .editorconfig file (or use something from the Microsoft GitHub repositories) and play with the settings. The setup is easy and it’s just a small text file right next to our code.
Read more about the customization <a href="https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options">here</a>.</p>
<h1 id="related-topic">Related topic</h1>
<p>If you are looking for a more powerful option to embrace coding standards, you might want to take a look at <a href="https://msdn.microsoft.com/en-us/library/mt162308.aspx"><strong>Roslyn Analysers</strong></a>:</p>
<blockquote>
<p>With live, project-based code analyzers in Visual Studio, API authors can ship domain-specific code analysis as part of their NuGet packages. Because these analyzers are powered by the .NET Compiler Platform (code-named “Roslyn”), they can produce warnings in your code as you type even before you’ve finished the line (no more waiting to build your code to discover issues). Analyzers can also surface an automatic code fix through the Visual Studio light bulb prompt to let you clean up your code immediately</p>
</blockquote>
https://blog.codeinside.eu/2018/04/30/editorconfig-sharing-code-style/
https://blog.codeinside.eu/2018/04/30/editorconfig-sharing-code-styleMon, 30 Apr 2018 23:45:00 +0000Did you know that you can run ASP.NET Core 2 under the full framework?
<p><em>This post might be obvious for some, but I really struggled a couple of month ago and I’m not sure if a Visual Studio Update fixed the problem for me or if I was just blind…</em></p>
<h1 id="the-default-way-running-net-core">The default way: Running .NET Core</h1>
<p><em>AFAIK the framework dropdown in the normal Visual Studio project template selector (the first window) is not important and doesn’t matter anyway for .NET Core related projects.</em></p>
<p>When you create a new ASP.NET Core application you will see something like this:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-03-31/default.png" alt="x" title="Default Framework selection" /></p>
<p>The important part for the framework selection can be found in the upper left corner: .NET Core is currently selected.</p>
<p>When you continue your .csproj file should show something like this:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;Project</span> <span class="na">Sdk=</span><span class="s">"Microsoft.NET.Sdk.Web"</span><span class="nt">&gt;</span>
<span class="nt">&lt;PropertyGroup&gt;</span>
<span class="nt">&lt;TargetFramework&gt;</span>netcoreapp2.0<span class="nt">&lt;/TargetFramework&gt;</span>
<span class="nt">&lt;/PropertyGroup&gt;</span>
<span class="nt">&lt;ItemGroup&gt;</span>
<span class="nt">&lt;PackageReference</span> <span class="na">Include=</span><span class="s">"Microsoft.AspNetCore.All"</span> <span class="na">Version=</span><span class="s">"2.0.5"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/ItemGroup&gt;</span>
<span class="nt">&lt;ItemGroup&gt;</span>
<span class="nt">&lt;DotNetCliToolReference</span> <span class="na">Include=</span><span class="s">"Microsoft.VisualStudio.Web.CodeGeneration.Tools"</span> <span class="na">Version=</span><span class="s">"2.0.2"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/ItemGroup&gt;</span>
<span class="nt">&lt;/Project&gt;</span>
</code></pre></div></div>
<h1 id="running-the-full-framework">Running the full framework:</h1>
<p>I had some trouble to find the option, but it’s really obvious. You just have to adjust the selected framework in the second window:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2018-03-31/full.png" alt="x" title=".NET Framework selected" /></p>
<p>After that your .csproj has the needed configuration.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;Project</span> <span class="na">Sdk=</span><span class="s">"Microsoft.NET.Sdk.Web"</span><span class="nt">&gt;</span>
<span class="nt">&lt;PropertyGroup&gt;</span>
<span class="nt">&lt;TargetFramework&gt;</span>net461<span class="nt">&lt;/TargetFramework&gt;</span>
<span class="nt">&lt;/PropertyGroup&gt;</span>
<span class="nt">&lt;ItemGroup&gt;</span>
<span class="nt">&lt;PackageReference</span> <span class="na">Include=</span><span class="s">"Microsoft.AspNetCore"</span> <span class="na">Version=</span><span class="s">"2.0.1"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;PackageReference</span> <span class="na">Include=</span><span class="s">"Microsoft.AspNetCore.Mvc"</span> <span class="na">Version=</span><span class="s">"2.0.2"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;PackageReference</span> <span class="na">Include=</span><span class="s">"Microsoft.AspNetCore.Mvc.Razor.ViewCompilation"</span> <span class="na">Version=</span><span class="s">"2.0.2"</span> <span class="na">PrivateAssets=</span><span class="s">"All"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;PackageReference</span> <span class="na">Include=</span><span class="s">"Microsoft.AspNetCore.StaticFiles"</span> <span class="na">Version=</span><span class="s">"2.0.1"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;PackageReference</span> <span class="na">Include=</span><span class="s">"Microsoft.VisualStudio.Web.BrowserLink"</span> <span class="na">Version=</span><span class="s">"2.0.1"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/ItemGroup&gt;</span>
<span class="nt">&lt;ItemGroup&gt;</span>
<span class="nt">&lt;DotNetCliToolReference</span> <span class="na">Include=</span><span class="s">"Microsoft.VisualStudio.Web.CodeGeneration.Tools"</span> <span class="na">Version=</span><span class="s">"2.0.2"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/ItemGroup&gt;</span>
<span class="nt">&lt;/Project&gt;</span>
</code></pre></div></div>
<p>The biggest change: When you run under the full .NET Framework you can’t use the “All”-Meta-Package, because with version 2.0 the package is still .NET Core only, and need to point to each package manually.</p>
<p>Easy, right?</p>
<p>Be aware: Maybe with ASP.NET Core 2.1 the Meta-Package story with the full framework <a href="https://github.com/aspnet/Announcements/issues/287">might get easier</a>.</p>
<p><em>I’m still not sure why I struggled to find this option… Hope this helps!</em></p>
https://blog.codeinside.eu/2018/03/31/running-aspnet-core-2-under-the-full-dotnet-framework/
https://blog.codeinside.eu/2018/03/31/running-aspnet-core-2-under-the-full-dotnet-frameworkSat, 31 Mar 2018 23:35:00 +0000Windows Fall Creators Update 1709 and Docker Windows Containers
<h1 id="who-shrunk-my-windows-docker-image">Who shrunk my Windows Docker image?</h1>
<p>We started to package our ASP.NET/WCF/Full-.NET Framework based web app into Windows Containers, which we then publish to the Docker Hub.</p>
<p>Someday we discovered that one of our new build machines produced Windows Containers only <strong>half the size</strong>:
Instead of a 8GB Docker image we only got a 4GB Docker image. Yeah, right?</p>
<h1 id="the-problem-with-windows-server-2016">The problem with Windows Server 2016</h1>
<p>I was able to run the 4GB Docker image on my development machine without any problems and I thought that this is maybe a great new feature (it is… but!). My boss then told my that he was unable to run this on our <strong>Windows Server 2016</strong>.</p>
<h1 id="the-issue-windows-10-fall-creators-update">The issue: Windows 10 Fall Creators Update</h1>
<p>After some googling around we found the problem: Our build machine was a <strong>Windows 10 OS with the most recent “Fall Creators Update” (v1709)</strong> (which was a bad idea from the beginning, because if you want to run Docker as a Service you will need a Windows Server!). The older build machine, which produced the much larger Docker image, was running with the normal Creators Update from March(?).</p>
<p>Docker resolves the base images for Windows like this:</p>
<ul>
<li>If you pull the ASP.NET Docker image from a Windows 10 Client OS <strong>with the Fall Creators Update</strong> you will get this <a href="https://github.com/Microsoft/aspnet-docker/blob/master/4.7.1-windowsservercore-1709/runtime/Dockerfile">4.7.1-windowsservercore-1709 image</a></li>
<li>If you pull it from a Windows Server 2016 or a older Windows 10 Client OS you will get this <a href="https://github.com/Microsoft/aspnet-docker/blob/master/4.7.1-windowsservercore-ltsc2016/runtime/Dockerfile">4.7.1-windowsservercore-ltsc2016 image</a></li>
</ul>
<h1 id="compatibility-issue">Compatibility issue</h1>
<p>As it turns out: You can’t run the smaller Docker images on Windows Server 2016. Currently it is only possible to do it via the preview <a href="https://blogs.technet.microsoft.com/windowsserver/2017/10/26/faq-on-windows-server-version-1709-and-semi-annual-channel/">“Windows Server, version 1709”</a> or on the Windows 10 Client OS.</p>
<p>Oh… and the new Windows Server is not a simple update to Windows Server 2016, instead it is a completely new version. Thanks Microsoft.</p>
<h1 id="workaround">Workaround</h1>
<p>Because we need to run our images on Windows Server 2016, we just target the LTSC2016 base image, which will produce 8GB Docker images (which sucks, but works for us).</p>
<h2 id="further-links">Further Links:</h2>
<p>This post could also be in the RTFM-category, because there are some notes on the Docker page available, but it was quite easy to overread ;)</p>
<ul>
<li><a href="https://docs.docker.com/install/windows/ee-preview/">Preview Docker for Windows Server 1709 and Windows 10 Fall Creators Update</a></li>
<li><a href="https://blogs.technet.microsoft.com/windowsserver/2017/10/26/faq-on-windows-server-version-1709-and-semi-annual-channel/">FAQ on Windows Server, version 1709 and Semi-Annual Channel</a></li>
<li><a href="https://stefanscherer.github.io/docker-on-windows-server-1709/">Stefan Scherer has some good information on this topic as well</a></li>
</ul>
https://blog.codeinside.eu/2018/02/27/windows-fall-creators-update-1709-docker-windows-containers/
https://blog.codeinside.eu/2018/02/27/windows-fall-creators-update-1709-docker-windows-containersTue, 27 Feb 2018 23:35:00 +0000WCF Global Fault Contracts
<p>If you are still using WCF you might have stumbled upon this problem: WCF allows you to throw certain Faults in your operation, but unfortunatly it is a bit awkward to configure if you want “Global Fault Contracts”. With this solution here it should be pretty easy to get “Global Faults”:</p>
<h1 id="define-the-fault-on-the-server-side">Define the Fault on the Server Side:</h1>
<p>Let’s say we want to throw the following fault in all our operations:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[DataContract]
public class FoobarFault
{
}
</code></pre></div></div>
<h1 id="register-the-fault">Register the Fault</h1>
<p>The tricky part in WCF is to “configure” WCF that it will populate the fault. You can do this manually via the [FaultContract-Attribute] on each operation, but if you are looking for a <strong>global WCF fault</strong> configuration, you need to apply it as a contract behavior like this:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">GlobalFaultsAttribute</span> <span class="p">:</span> <span class="n">Attribute</span><span class="p">,</span> <span class="n">IContractBehavior</span>
<span class="p">{</span>
<span class="c1">// this is a list of our global fault detail classes.</span>
<span class="k">static</span> <span class="n">Type</span><span class="p">[]</span> <span class="n">Faults</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Type</span><span class="p">[]</span>
<span class="p">{</span>
<span class="k">typeof</span><span class="p">(</span><span class="n">FoobarFault</span><span class="p">),</span>
<span class="p">};</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">AddBindingParameters</span><span class="p">(</span>
<span class="n">ContractDescription</span> <span class="n">contractDescription</span><span class="p">,</span>
<span class="n">ServiceEndpoint</span> <span class="n">endpoint</span><span class="p">,</span>
<span class="n">BindingParameterCollection</span> <span class="n">bindingParameters</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">ApplyClientBehavior</span><span class="p">(</span>
<span class="n">ContractDescription</span> <span class="n">contractDescription</span><span class="p">,</span>
<span class="n">ServiceEndpoint</span> <span class="n">endpoint</span><span class="p">,</span>
<span class="n">ClientRuntime</span> <span class="n">clientRuntime</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">ApplyDispatchBehavior</span><span class="p">(</span>
<span class="n">ContractDescription</span> <span class="n">contractDescription</span><span class="p">,</span>
<span class="n">ServiceEndpoint</span> <span class="n">endpoint</span><span class="p">,</span>
<span class="n">DispatchRuntime</span> <span class="n">dispatchRuntime</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Validate</span><span class="p">(</span>
<span class="n">ContractDescription</span> <span class="n">contractDescription</span><span class="p">,</span>
<span class="n">ServiceEndpoint</span> <span class="n">endpoint</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">foreach</span> <span class="p">(</span><span class="n">OperationDescription</span> <span class="n">op</span> <span class="k">in</span> <span class="n">contractDescription</span><span class="p">.</span><span class="n">Operations</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">foreach</span> <span class="p">(</span><span class="n">Type</span> <span class="n">fault</span> <span class="k">in</span> <span class="n">Faults</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">op</span><span class="p">.</span><span class="n">Faults</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nf">MakeFault</span><span class="p">(</span><span class="n">fault</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">private</span> <span class="n">FaultDescription</span> <span class="nf">MakeFault</span><span class="p">(</span><span class="n">Type</span> <span class="n">detailType</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">string</span> <span class="n">action</span> <span class="p">=</span> <span class="n">detailType</span><span class="p">.</span><span class="n">Name</span><span class="p">;</span>
<span class="n">DescriptionAttribute</span> <span class="n">description</span> <span class="p">=</span> <span class="p">(</span><span class="n">DescriptionAttribute</span><span class="p">)</span>
<span class="n">Attribute</span><span class="p">.</span><span class="nf">GetCustomAttribute</span><span class="p">(</span><span class="n">detailType</span><span class="p">,</span> <span class="k">typeof</span><span class="p">(</span><span class="n">DescriptionAttribute</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="n">description</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
<span class="n">action</span> <span class="p">=</span> <span class="n">description</span><span class="p">.</span><span class="n">Description</span><span class="p">;</span>
<span class="n">FaultDescription</span> <span class="n">fd</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">FaultDescription</span><span class="p">(</span><span class="n">action</span><span class="p">);</span>
<span class="n">fd</span><span class="p">.</span><span class="n">DetailType</span> <span class="p">=</span> <span class="n">detailType</span><span class="p">;</span>
<span class="n">fd</span><span class="p">.</span><span class="n">Name</span> <span class="p">=</span> <span class="n">detailType</span><span class="p">.</span><span class="n">Name</span><span class="p">;</span>
<span class="k">return</span> <span class="n">fd</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Now we can apply this ContractBehavior in the Service just like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[ServiceBehavior(...), GlobalFaults]
public class FoobarService
...
</code></pre></div></div>
<p>To use our Fault, just throw it as a FaultException:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>throw new FaultException&lt;FoobarFault&gt;(new FoobarFault(), "Foobar happend!");
</code></pre></div></div>
<h1 id="client-side">Client Side</h1>
<p>On the client side you should now be able to catch this exception just like this:</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="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="k">if</span> <span class="p">(</span><span class="n">ex</span> <span class="k">is</span> <span class="n">FaultException</span> <span class="n">faultException</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">faultException</span><span class="p">.</span><span class="n">Action</span> <span class="p">==</span> <span class="k">nameof</span><span class="p">(</span><span class="n">FoobarFault</span><span class="p">))</span>
<span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Hope this helps!</p>
<p>(This old topic was still on my “To-blog” list, even if WCF is quite old, maybe someone is looking for something like this)</p>
<h2 id="further-links">Further Links:</h2>
<ul>
<li><a href="http://dkturner.blogspot.ch/2007/11/wcf-contract-level-faultcontract.html">WCF: Contract-level FaultContract</a> The code above was more or less adopted from his great blogpost!</li>
</ul>
https://blog.codeinside.eu/2018/01/31/wcf-faultcontracts/
https://blog.codeinside.eu/2018/01/31/wcf-faultcontractsWed, 31 Jan 2018 23:35:00 +0000First steps to enable login with Microsoft or Azure AD account for your application
<p>It is quite common these days to “Login with Facebook/Google/Twitter”. Of course Microsoft has something similar.
If I remember it correctly the first version was called “Live SDK” with the possibility to login with your personal Microsoft Account.</p>
<p>With Office 365 and the introduction of Azure AD we were able to build an application to sign-in with a personal account via the “Live SDK” and organizational account via “Azure AD”.</p>
<p>However: The developer and end user UX was far way from perfect, because the implementation for each account type was different and for the user it was not clear which one to choose.</p>
<h1 id="microsoft-graph--azure-ad-20">Microsoft Graph &amp; Azure AD 2.0</h1>
<p>Fast forward to the right way: Use the <strong><a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-app-registration">Azure AD 2.0 endpoint</a></strong>.</p>
<h2 id="step-1-register-your-own-application">Step 1: Register your own application</h2>
<p>You just need to register your own application in the <strong><a href="https://apps.dev.microsoft.com">Application Registration Portal</a></strong>. The registration itself is a typical OAuth-application registration and you get a ClientId and Secret for your application.</p>
<p>Warning: If you have “older” LiveSDK application registered under your account you need to choose <strong>Converged Applications</strong>. LiveSDK applications are more or less legacy and I wouldn’t use them anymore.</p>
<h2 id="step-2-choose-a-platform">Step 2: Choose a platform</h2>
<p>Now you need to choose your application platform. If you want to enable the sign-in stuff for your web application you need to choose “Web” and insert the redirect URL. After the sign-in process the token will be send to this URL.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-12-31/platforms.png" alt="x" title="Platforms" /></p>
<h2 id="step-3-choose-microsoft-graph-permissions-scopes">Step 3: Choose Microsoft Graph Permissions (Scopes)</h2>
<p>In the last step you need to select what permissions your applications need. A first-time user needs to accept your permission requests. The “Microsoft Graph” is a collection of APIs that works for personal Microsoft accounts <strong>and</strong> Office 365/Azure AD account.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-12-31/platforms.png" alt="x" title="Platforms" /></p>
<p>The “User.Read” permission is the most basic permission that would allow to sign-in, but if you want to access other APIs as well you just need to add those permissions to your application:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-12-31/scopes.png" alt="x" title="Scopes" /></p>
<h2 id="finish">Finish</h2>
<p>After the application registration and the selection of the needed permissions you are ready to go. You can even generate a sample application on the portal. For a <strong>quick start</strong> check this <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-app-registration#build-a-quick-start-app">page</a></p>
<h1 id="microsoft-graph-explorer">Microsoft Graph Explorer</h1>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-12-31/graphexplorer.png" alt="x" title="Microsoft Graph Explorer" /></p>
<p>As I already said: The Graph is the center of Microsofts Cloud Data and the easiest way to play around with the different scopes and possibilities is with the <strong><a href="https://developer.microsoft.com/en-us/graph/graph-explorer">Microsoft Graph Explorer</a></strong>.</p>
<p>Hope this helps.</p>
https://blog.codeinside.eu/2017/12/31/first-steps-to-login-with-your-ms-or-azure-ad-account/
https://blog.codeinside.eu/2017/12/31/first-steps-to-login-with-your-ms-or-azure-ad-accountSun, 31 Dec 2017 14:15:00 +0000Signing with SignTool.exe - don't forget the timestamp!
<p>If you currently not touching signtool.exe at all or have nothing to do with “signing” you can just pass this blogpost, because this is more or less a stupid “Today I learned I did a mistake”-blogpost.</p>
<h1 id="signing">Signing?</h1>
<p>We use authenticode code signing for our software just to prove that the installer is from us and “safe to use”, otherwise you might see a big warning from Windows that the application is from an “unknown publisher”:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-11-30/uac.png" alt="x" title="UAC" /></p>
<p>To avoid this, you need a code signing certificate and need to sign your program (e.g. the installer and the .exe)</p>
<h1 id="the-problem">The problem…</h1>
<p>We are doing this code signing since the first version of our application. Last year we needed to buy a new certificate because the first code signing certificate was getting stale. Sadly, after the first certificate was expired we got a call from a customer who recently tried to install our software and the installer was signed with the “old” certificate. The result was the big “Warning”-screen from above.</p>
<p>I checked the file and compared it to other installers (with expired certificates) and noticed that our signature didn’t had a timestamp:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-11-30/properties.png" alt="x" title="Properties" /></p>
<h1 id="the-solution">The solution</h1>
<p>I stumbled upon <a href="https://blogs.msdn.microsoft.com/ieinternals/2011/03/22/everything-you-need-to-know-about-authenticode-code-signing/">this great blogpost about authenticode code signing</a> and the timestamp was indeed important:</p>
<p><em>When signing your code, you have the opportunity to timestamp your code; you should definitely do this. Time-stamping adds a cryptographically-verifiable timestamp to your signature, proving when the code was signed. If you do not timestamp your code, the signature will be treated as invalid upon the expiration of your digital certificate. Since it would probably be cumbersome to re-sign every package you’ve shipped when your certificate expires, you should take advantage of time-stamping. A signed, time-stamped package remains valid indefinitely, so long as the timestamp marks the package as having been signed during the validity period of the certificate.</em></p>
<p>Time-stamping itself is pretty easy and only one parameter was missing all the time… now we invoke <a href="https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe">Signtool.exe</a> like this and we have a digitial signature <strong>with</strong> a timestamp:</p>
<p><em>(updated with /fd sha256 /td sha256 thanks to @Christoph Rüegg)</em></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>signtool.exe sign /tr http://timestamp.digicert.com /fd sha256 /td sha256 /sm /n "Subject..." /d "Description..." file.msi
</code></pre></div></div>
<p><strong>Notes:</strong></p>
<ul>
<li>/tr is the timestamp URL server</li>
<li>/fd &amp; /td sha256 specify the used digest algorithm</li>
<li>/sm is used to specify the machine certifaction store</li>
<li>/n is used for the Subject name</li>
<li>/d the description</li>
</ul>
<p><strong>Multiple Certs with the same subject?</strong></p>
<p>If you have multiple certificates with the same Subject you might want to use the “/sha1” option to specify the thumbprint, e.g.:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>signtool.exe sign /tr http://timestamp.digicert.com /fd sha256 /td sha256 /sm /sha1 "..." /d "Description..." file.msi
</code></pre></div></div>
<p>Remarks:</p>
<ul>
<li>Our code signing cert is from Digicert and they provide the timestamp URL.</li>
<li>SignTool.exe is part of the Windows SDK and currently is in the ClickOnce folder (e.g. C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool)</li>
<li>Checkout the <a href="https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe">Signtool.exe Microsoft Docs Page</a></li>
</ul>
<p>Hope this helps.</p>
https://blog.codeinside.eu/2017/11/30/signing-with-signtool-dont-forget-the-timestamp/
https://blog.codeinside.eu/2017/11/30/signing-with-signtool-dont-forget-the-timestampThu, 30 Nov 2017 23:15:00 +0000Introducing Electron.NET - building Electron Desktop Apps with ASP.NET Core
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-10-31/electron.net-logo.png" alt="x" title="Electron.NET" /></p>
<p>The last couple of weeks I worked with my buddy <a href="http://www.cross-platform-blog.com/">Gregor Biswanger</a> on a new project called <strong>“<a href="https://github.com/ElectronNET/Electron.NET">Electron.NET</a>“</strong>.</p>
<p>As you might already guess: It is some sort of bridge between the well known <a href="https://electron.atom.io/">Electron</a> and .NET.</p>
<p><em>If you don’t know what Electron is: It helps to build desktop apps written in HTML/CSS/Javascript</em></p>
<h1 id="the-idea">The idea</h1>
<p>Gregor asked me a while ago if it is possible to build desktop apps with ASP.NET Core (or .NET Core in general) and - indeed - there are some ideas how to make it, but unfortunatly there is no “official” UI stack available for .NET Core.
After a little chat we agreed that the best bet would be to use Electron as is and somehow “embed” ASP.NET Core in it.</p>
<p>I went to bed, but Gregor was keen on to build a prototyp and he did it: He was able to launch the ASP.NET Core application inside the electron app and invoke some Electron APIs from the .NET World.</p>
<p>First steps done, yeah! In the following weeks Gregor was able to “bridge” most Electron APIs and I could help him with the tooling via our dotnet-extension.</p>
<h1 id="overview">Overview</h1>
<p>The basic functionality is not too complex:</p>
<ul>
<li>We ship a “standard” (more or less blank) Electron app</li>
<li>Inside the Electron part two free ports are searched:
<ul>
<li>The first free port is used inside the Electron app itself</li>
<li>The second free port is used for the ASP.NET Core process</li>
</ul>
</li>
<li>The app launches the .NET Core process with ASP.NET Core port (e.g. localhost:8002) and injects the first port as parameter</li>
<li>Now we have a Socket.IO based linked between the launched ASP.NET Core app and the Electron app itself - this is our communication bridge!</li>
</ul>
<p>At this point you can write your Standard ASP.NET Core Code and can communicate via our Electron.API wrapper to the Electron app.</p>
<p>Gregor did a <strong><a href="http://www.cross-platform-blog.com/electron.net/electron.net-musicplayer-app-with-asp.net-core">fabulous blogpost with a great example</a></strong>.</p>
<h1 id="interested-this-way">Interested? This way!</h1>
<p>If you are interested, maybe take a look at the <strong><a href="https://github.com/ElectronNET">ElectronNET-Org on GitHub</a></strong>. The complete code is OSS and there are two demo repositories.</p>
<h1 id="no-way---this-is-a-stupid-idea">No way - this is a stupid idea!</h1>
<p>The last days were quite intersting. We got some nice comments about the project and (of course) there were some critics.</p>
<p>As far as I know the current “this is bad, because… “-list is like this:</p>
<ul>
<li>We still need node.js and Electron.NET is just a wrapper around Electron: Yes, it is.</li>
<li>Perf will suck: Well… to be honest - the current startup time does really suck, because we not only launch the Electron stuff, but we also need to start the .NET Core based WebHost - maybe we will find a solution</li>
<li>Starting a web server inside the app is bad on multiple levels because of security and perf: I agree, there are some <a href="https://github.com/ElectronNET/Electron.NET/issues/22">ideas how to fix it</a>, but this might take some time.</li>
</ul>
<p>There are lots of issues open and the project is pretty young, maybe we will find a solution for the above problems, maybe not.</p>
<h1 id="final-thoughts">Final thoughts</h1>
<p>The interesting point for me is, that we seem to hit a nerf with this project: There is demand to write X-Plat desktop applications.</p>
<p>We are looking for feedback - please share your opinion on the <a href="https://github.com/ElectronNET/Electron.NET">ElectronNET-GitHub-Repo</a> or try it out :)</p>
<p><em>Desktop is dead, long live the desktop!</em></p>
https://blog.codeinside.eu/2017/10/31/introducing-electrondotnet/
https://blog.codeinside.eu/2017/10/31/introducing-electrondotnetTue, 31 Oct 2017 23:15:00 +0000dnSpy - a OSS IL decompiler and debugger
<p>My colleague was fighting against a nasty bug, that only occures on one machine. Unfortunatly this machine was not a development machine (no VS installed) and we didn’t want to mess with VS remote debugging, because (AFAIK) his would need some additional setup but we were not allowed to install anything.</p>
<p>Soooo… he searched around and found this:</p>
<h2 id="dnspy---a-net-assembly-editor-decompiler-and-debugger">dnSpy - a .NET assembly editor, decompiler, and debugger</h2>
<p>The title contains the major points. It is a decompiler, like IL Spy, but addionaly it has a super nice debugger and it looks like a small Visual Studio.</p>
<p>Some pictures how I just decompile Paint.NET and attach the debugger:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-09-30/dnspy.png" alt="x" title="dnSpy without debugging" /></p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-09-30/dnspy_start_debug.png" alt="x" title="Start debugging" /></p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-09-30/dnspy_debugging.png" alt="x" title="Debugging" /></p>
<p>I think this is just awesome and it helped my colleague alot.</p>
<h2 id="oss--free">OSS &amp; Free</h2>
<p>The complete project is hosted <strong><a href="https://github.com/0xd4d/dnSpy">on GitHub</a></strong> and is <strong>“Open Source (GPLv3) and Free Forever”</strong></p>
<p>Checkout the GitHub project page - it contains a lot more information. The tool itself was just 18mb zipped and can be run everywhere.</p>
<h2 id="its-a-decompiler">Its a decompiler!</h2>
<p>And just to make sure you keep this in mind: The debugging works with every .NET application (at least in theory), because it decompiles the .NET IL language to C#. It is not a 1:1 debugger, but maybe it can help you.</p>
<p><strong><a href="https://github.com/0xd4d/dnSpy">Check out the dnSpy GitHub Site</a></strong></p>
https://blog.codeinside.eu/2017/09/30/dnspy-a-oss-il-decompiler-and-debugger/
https://blog.codeinside.eu/2017/09/30/dnspy-a-oss-il-decompiler-and-debuggerSat, 30 Sep 2017 23:15:00 +0000IdentityServer3 with WindowsAuthentication with ASP.NET WebApi & ASP.NET & WPF App
<p><strong>Please note</strong>: In my sample and in this blogpost I cover IdentityServer 3, because last year when I was working on the sample and our real implementation IdentityServer4 (a rewrite of IdentityServer 3) was in beta. My guess is, that most stuff should still apply even if you are using IdentityServer4, but I didn’t test it.</p>
<p>Also: I’m not a security expert - this might be all wrong, but currently this more or less works for us. If you find something strange, please let me know!</p>
<h2 id="overview">Overview</h2>
<p>The sample consists of the following projects:</p>
<p><strong>IdentityTest.IdServerHost:</strong> That’s the central IdentityServer in our solution. It contains all “clients” &amp; “identityprovider” settings.
<strong>IdentityTest.WinAuth:</strong> This is our Windows-Authentication provider. Because of the nature of WindowsAuth it needs to be an extra project. This needs to be hosted via IIS (or IIS Express) with Windows authentication enabled. The ASP.NET app acts as a bridge and will convert the Windows-Auth ticket into a SAML token, which can be integrated into the IdentityServer. It is more or less like a mini-ADFS.
<strong>IdentityTest.WebApp:</strong> The WebApp itself can be used via browser and also hosts a WebApi. The WebApi is secured by the IdentityServer and secured pages will trigger the authentication against the IdServerHost.
<strong>IdentityTest.WpfClient:</strong> With the WPFApp we want to get a AccessToken via a WebBrowser-Control from the IdServerHost and call the WebApi that is hosted and secured by the very same IdServerHost.</p>
<p>The IdentityServer team did a great job and have a large <strong><a href="https://github.com/IdentityServer/IdentityServer3.Samples">sample repository on GitHub</a></strong>.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-08-30/overview.png" alt="x" title="Overview" /></p>
<p>I will talk about each part in my sample. Now lets beginn with…</p>
<h3 id="the-idserverhost-project">The ‘IdServerHost’ Project</h3>
<p>The IdentityServerHost is a plain ASP.NET application. To include the IdentityServer3 you need to add <a href="https://www.nuget.org/packages/IdentityServer3/">IdentityServer3 NuGet-Package</a>.</p>
<p>The code is more or less identical with the <a href="https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/WebHost%20(minimal)/WebHost">Minimal-Sample from the IdentityServer3 team</a>, but I <strong>disabled the SSL</strong> requirements for my demo.</p>
<p>Be aware: The IdentityServer use a certificate to sign the tokens, but this has nothing to do with the SSL certificate. This was a hard learning curve for me and IISExpress or something messed things up. In the end I disabled the SSL requirements <strong>for my development enviroment</strong> and could start to understand how each part is communicating with each other.
The signing certificate in the sample is the sample .pfx file from the offical samples.</p>
<p>Remember: <strong>DO USE SSL IN PRODUCTION.</strong> Oh - and use the Cert-Store for the signing certificate as well!</p>
<p><strong>Cert-Handling in IdentityServer in a nutshell</strong>: Do use SSL in production with a valid SSL certificate and setup another certificate that the IdentityServer will use to sign the tokens.</p>
<p>Besides the SSL stuff the most important stuff might be the <a href="https://github.com/Code-Inside/Samples/blob/master/2016/IdentityTest/IdentityTest.IdServerHost/Configuration/Clients.cs">client-registration</a> and the <a href="https://github.com/Code-Inside/Samples/blob/79fda88113a4736a465ab275fe0745dfc6aefa9a/2016/IdentityTest/IdentityTest.IdServerHost/Startup.cs#L45-L65">identity-provider-registration</a>.</p>
<p>The IdentityServer - as the auth-central - knows each ‘client’ and each ‘identity-provider’. Make sure all URLs are correct otherwise you will end up with errors. Even a slightly difference like ‘http://test.com/’ and ‘http://test.com’ (without the trailing slash at the end) will result in strange errors.</p>
<h3 id="the-winauth-project">The ‘WinAuth’ Project</h3>
<p>As already written this is our Windows-Authentication provider. Of course, it is only needed if you need WinAuth. If you want to use any other provider, like a Google/Microsoft/Facebook/Twitter-Login, then this is not needed.
It is a bridge to the enterprise world and works quite well.</p>
<p>In the project I just reference the <a href="https://www.nuget.org/packages/IdentityServer.WindowsAuthentication/">IdentityServer.WindowsAuthentication</a> NuGet-Package and I’m nearly done.
In the config I need to insert the URL of my IdentityServer host - those two parts needs to know each other and they will exchange public keys so they can trust each other.</p>
<p>For this trust-relationship the WinAuth provider has its own certificate. Actually you can reuse the same cert from the IdentityServerHost but I’m not sure if this is super secure, but it works.</p>
<p>The code and sample can also be found on the offical <a href="https://github.com/IdentityServer/WindowsAuthentication">GitHub repo</a></p>
<h3 id="the-webapp-project">The ‘WebApp’ Project</h3>
<p>This project is a regular ASP.NET MVC project with WebApi 2 included. Nothing ASP.NET Core related, but the actual doing would be pretty similar.</p>
<p>On this page there are two ways to interact:</p>
<ul>
<li>Via Browser</li>
<li>Via the WebApi</li>
</ul>
<p><strong>Browser Auth via OpenIdConnect Auth:</strong></p>
<p>The NuGet Package <a href="https://www.nuget.org/packages/Microsoft.Owin.Security.OpenIdConnect">Microsoft.Owin.Security.OpenIdConnect</a> does the heavy lifting for us. In combination with the <a href="https://www.nuget.org/packages/Microsoft.Owin.Security.Cookies/">Microsoft.Owin.Security.Cookies</a> NuGet package the authentication will kick in when someone access a [Authorize] marked Controller. The Cookie-Auth will preserve the identity information.</p>
<p><strong>WebApi Auth:</strong></p>
<p>To use the protected WebApi with any HTTP client the request must have a JWT bearer token. The implementation is super simple with this NuGet package <a href="https://www.nuget.org/packages/IdentityServer3.AccessTokenValidation/">IdentityServer3.AccessTokenValidation</a>.</p>
<p><strong>Setup of both auth options:</strong></p>
<p>The setup is quite easy with the NuGet packages:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = ConfigurationManager.AppSettings["Security.Authority"],
RequiredScopes = new[] { "openid" }
});
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationType = "cookies",
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
AuthenticationType = "oidc",
SignInAsAuthenticationType = "cookies",
Authority = ConfigurationManager.AppSettings["Security.Authority"],
ClientId = "webapp",
RedirectUri = ConfigurationManager.AppSettings["Security.RedirectUri"],
ResponseType = "id_token",
Scope = "openid all_claims"
});
}
}
</code></pre></div></div>
<p>It is important to use the correct “clientIds” and URLs as configured in the IdentityServer, otherwise you will receive errors from the IdentityServer.</p>
<h3 id="the-wpfclient-project">The ‘WpfClient’ Project</h3>
<p>This project is a small version of the original <a href="https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/Clients/WpfOidcClientPop">WpfOidcClientPop</a> sample. The idea behind this sample is that a user can sign in with his regular account.</p>
<p><strong>Auth via browser:</strong></p>
<p>Instead of a Loginname/Password form rendered from the WPF app itself the authentication is delegated to a embedded browser control. Another option is to delegate it to the “real” installed browser, but this is another topic.
The Microsoft Account login in Visual Studio is made that way or think of any popular “Facebook-Login” mobile app on your phone: The auth-process is basically a typical Web signin.</p>
<p>This scenario is also convered as a offical <a href="https://tools.ietf.org/wg/oauth/draft-ietf-oauth-native-apps/">OpenID Connect specification</a>. In WPF your best and easiest choice would be the <a href="https://github.com/IdentityModel/IdentityModel.OidcClient2">IdentityModel.OidcClient2</a> package.</p>
<p><strong>Auth “Steps”</strong></p>
<p>The first step in the sample project is to aquire a access token from the IdentityServer. The actual implementation is thanks to the OidcClient quite simple as you can see <a href="https://github.com/Code-Inside/Samples/blob/c5d42f9b3ca61a6171eed684c57d94cac2297bf2/2016/IdentityTest/IdentityTest.WpfClient/MainWindow.xaml.cs#L44-L49">here</a>.</p>
<p>The OidcClient will try to get the needed accesstoken in the silent mode first (this can be configured) and if this fails a embedded browser will be rendered and the user needs to sign in there. After a successful signin you will get a <strong>accesstoken and refreshtoken</strong>.</p>
<p><strong>Sample note:</strong> If you try this on your local machine the auth-window should not appear, because it will just do a “silent” windows auth login.</p>
<p><strong>Multiple IdentityProvider:</strong> If you configure multiple identity provider, a simple designed identity selection will appear in the embedded browser window.</p>
<p>After the intial sign in you can regenerate new accesstokens via the refreshtoken.</p>
<p>With the accesstoken <a href="https://github.com/Code-Inside/Samples/blob/c5d42f9b3ca61a6171eed684c57d94cac2297bf2/2016/IdentityTest/IdentityTest.WpfClient/MainWindow.xaml.cs#L95-L99">we craft a HTTP request</a> to our beloved WebApi and write use the token in the authorization header and finally we are done.</p>
<p><strong>Things to consider:</strong></p>
<p>It is important <a href="https://github.com/Code-Inside/Samples/blob/c5d42f9b3ca61a6171eed684c57d94cac2297bf2/2016/IdentityTest/IdentityTest.WpfClient/MainWindow.xaml.cs#L77-L83">to setup the OIDCClient</a> the correct way with the values that you specified in your IdentityServer configuration. Also you should read about OpenID scopes because they are linked to the actual result. Without the correct scope you might not get a accesstoken or refreshtoken.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-08-30/wpf.png" alt="x" title="wpf" /></p>
<h1 id="summary">Summary</h1>
<p>With these 4 projects we have a quite mighty solution created. We can still use Windows Auth for enterprise needs, we can protect WebApis and WebPages via a central Identity solution and also use “native” apps. The IdentityServer itself has a wide range of configuration possibilities.</p>
<p>If you start doing something in this direction I would point you to the <a href="https://github.com/IdentityServer/IdentityServer4">IdentityServer4</a>, because new is always better, right?</p>
<h1 id="github-link">GitHub Link</h1>
<p>The full sample can be found on <a href="https://github.com/Code-Inside/Samples/tree/master/2016/IdentityTest">GitHub</a>.</p>
<p>Hope this helps.</p>
https://blog.codeinside.eu/2017/08/30/identityserver3-webapi-webapp-wpfapp-ohmy/
https://blog.codeinside.eu/2017/08/30/identityserver3-webapi-webapp-wpfapp-ohmyWed, 30 Aug 2017 23:15:00 +0000How to convert .crt & .key files to a .pfx
<p>The requirements are simple: You will need the .cer with the corresponding .key file and need to download <a href="https://wiki.openssl.org/index.php/Binaries">OpenSSL</a>.</p>
<p>If you are using Windows <strong>without the awesome Linux Subsystem</strong>, take the latest pre-compiled version <strong>for Windows</strong> <a href="https://indy.fulgan.com/SSL/">from this site</a>.</p>
<p>Otherwise with <strong>Bash on Windows</strong> you can just use OpenSSL via its “native” environment. <em>Thanks for the hint @kapsiR</em></p>
<p>After the download run this command:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> openssl pkcs12 -export -out domain.name.pfx -inkey domain.name.key -in domain.name.crt
</code></pre></div></div>
<p>This will create a <strong>domain.name.pfx</strong>. As far as I remember you will be asked to set a password for the generated private .pfx part.</p>
<p>If you are confused with .pfx, .cer, .crt take a look at this <a href="http://www.gtopia.org/blog/2010/02/der-vs-crt-vs-cer-vs-pem-certificates/">nice description blogpost</a>.</p>
<p>Hope this helps!</p>
https://blog.codeinside.eu/2017/07/31/how-to-convert-crt-and-key-to-pfx/
https://blog.codeinside.eu/2017/07/31/how-to-convert-crt-and-key-to-pfxMon, 31 Jul 2017 23:15:00 +0000Non-cryptographic hash functions for .NET
<p>Creating hashs is quite common to check if content X has changed without looking at the whole content of X.
Git for example uses SHA1-hashs for each commit. SHA1 itself is a pretty old cryptographic hash function, but in the case of Git there might have been better alternatives available, because the “to-be-hashed” content is not crypto relevant - it’s just content marker. Well… in the case of Git the current standard is SHA1, which works, but a ‘better’ way would be to use non-cryptographic functions for non-crypto purposes.</p>
<h2 id="why-you-should-not-use-crypto-hashs-for-non-crypto">Why you should not use crypto-hashs for non-crypto</h2>
<p>I discovered this topic via a Twitter-conversation and it started with this <a href="https://twitter.com/sfeldman/status/804984253985370112">Tweet</a>:</p>
<blockquote class="twitter-tweet" data-lang="de"><p lang="en" dir="ltr">Bend Message Deduplication on <a href="https://twitter.com/hashtag/azure?src=hash">#azure</a> <a href="https://twitter.com/hashtag/servicebus?src=hash">#servicebus</a> to Your Will <a href="https://t.co/zjIQFjt2c9">https://t.co/zjIQFjt2c9</a></p>&mdash; Sean Feldman (@sfeldman) <a href="https://twitter.com/sfeldman/status/804984253985370112">3. Dezember 2016</a></blockquote>
<script async="" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p><a href="https://twitter.com/clemensv/status/805499766264172548">Clemens Vasters</a> then came and pointed out why it would be better to use non-crypto hash functions:</p>
<blockquote class="twitter-tweet" data-lang="de"><p lang="en" dir="ltr">Rationale: Any use of broken crypto hashes may trip up security review processes.</p>&mdash; Clemens Vasters 🇪🇺 (@clemensv) <a href="https://twitter.com/clemensv/status/805499766264172548">4. Dezember 2016</a></blockquote>
<script async="" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>The reason makes perfect sense for me - next step: What other choice are available?</p>
<h2 id="non-cryptographic-hash-functions-in-net">Non-cryptographic hash functions in .NET</h2>
<p>If you are googleing around you will find many different hashing algorithm, like <a href="https://en.wikipedia.org/wiki/Jenkins_hash_function">Jenkins</a> or <a href="https://en.wikipedia.org/wiki/MurmurHash">MurmurHash</a>.</p>
<p>Sean Feldman, who more or less started the Twitter discussion mentioned a very good library for .NET developers:</p>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="de"><p lang="en" dir="ltr">for the hashing function, I think I&#39;ll lead readers to a better option here <a href="https://t.co/LDiJuLD5A5">https://t.co/LDiJuLD5A5</a></p>&mdash; Sean Feldman (@sfeldman) <a href="https://twitter.com/sfeldman/status/805516688816910336">4. Dezember 2016</a></blockquote>
<script async="" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>The author of this awesome package is <a href="https://github.com/brandondahler">Brandon Dahler</a>, who created .NET versions of the most well known algorithm and published them as NuGet packages.</p>
<p>The source and everything can be found on <strong><a href="https://github.com/brandondahler/Data.HashFunction/">GitHub</a></strong>.</p>
<h2 id="lessons-learned">Lessons learned</h2>
<p>If you want to hash something and it is not crypto relevant, then it would be better to look at one of those Data.HashFunctions - some a pretty crazy fast.</p>
<p>I’m not sure which one is ‘better’ - if you have some opinions please let me know. Brandon created a small description of each algorithm on the <strong><a href="http://datahashfunction.azurewebsites.net/">Data.HashFunction documentation page</a></strong>.</p>
<p><em>(my blogging backlog is quite long, so I needed 6 month to write this down ;) )</em></p>
https://blog.codeinside.eu/2017/06/30/non-cryptographic-hash-functions-for-dotnet/
https://blog.codeinside.eu/2017/06/30/non-cryptographic-hash-functions-for-dotnetFri, 30 Jun 2017 00:15:00 +0000Using Visual Studio Code & Team Foundation Version Control (TFVC)
<p>Recently we start working on a Angular 4 app but all other parts of the application (e.g. the backend stuff) were stored in a good old TFVC based repository (inside a Team Foundation Server 2015) .
Unfortunately building an Angular app with the full blown Visual Studio with the “default” Team Explorer workflow is not really practical.
Another point for using Visual Studio Code was that most other online resources about learning Angular are using VS Code.</p>
<p>Our goal was to keep <strong>one</strong> repository, otherwise it would be harder to build and maintain.</p>
<h2 id="first-plan-migrate-to-git">First plan: Migrate to Git</h2>
<p>First we tried to migrate our <strong>complete</strong> code base to Git with this <a href="https://github.com/git-tfs/git-tfs">generally awesome tool</a>. Unfortunately for us it failed because of our quite large branch-tree. I tried it on a smaller code base and it worked without any issues.</p>
<p>At this point we needed another solution, because we wanted to get started on the actual application - so we tried to stick with TFVC.</p>
<p><strong>Important:</strong> I always would recommend Git over TFVC, because it’s the way our industry is currently moving and at some point in the future we will do this too.</p>
<p><strong>If you have similar problems like us: Read on!</strong></p>
<h2 id="second-plan-get-the-tfvc-plugin-working-in-visual-studio-code">Second plan: Get the TFVC plugin working in Visual Studio Code</h2>
<p>Good news: Since <a href="https://blogs.msdn.microsoft.com/visualstudioalm/2017/04/12/official-release-of-tfvc-support-for-visual-studio-code/">April 2017</a> there is a Visual Studio Team Services extension for Visual Studio Code that also supports TFVC!</p>
<p>Requirements:</p>
<ul>
<li>Team Foundation Server 2015 Update 2</li>
<li>A existing <strong>local</strong> workspace configuration (at least currently, check this <a href="https://github.com/Microsoft/vsts-vscode/issues/176">GitHub issue</a> for further information)</li>
<li>The actual <a href="https://github.com/Microsoft/vsts-vscode">extension</a></li>
</ul>
<h2 id="be-aware-local-workspaces">Be aware: Local Workspaces!</h2>
<p>Even I’m using TFS since a couple of years I just recently discovered that the TFS supports to different “workflows”. The “default” workflow always needs a connection to the TFS to checkout files etc.
There is an alternative mode called “local” mode which seems to work like SVN. The difference is, that you can create a local file and the TFVC-client will “detect” those changes. Read more about the differences <a href="https://www.visualstudio.com/en-us/docs/tfvc/decide-between-using-local-server-workspace">here</a>.</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-05-29/local-workspace.png" alt="x" title="Local Workspace setting" /></p>
<h2 id="configuration">Configuration</h2>
<p>In our OnPremise TFS 2015 world I just needed only this configuration line in my user settings:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
"tfvc.location": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer\\TF.exe",
...
</code></pre></div></div>
<h2 id="action">Action!</h2>
<p>Now when I point VS Code to my local workspace folder, the TFVC plugin will kick in and I see the familiar “change”-tracking:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-05-29/changetracking.png" alt="x" title="Working with the extension" /></p>
<p>It is not perfect, because I still need to setup and “manage” (e.g. get the history etc.) via the full blown Visual Studio, but with this setup it is “do-able”.</p>
https://blog.codeinside.eu/2017/05/29/using-vscode-and-tfvc/
https://blog.codeinside.eu/2017/05/29/using-vscode-and-tfvcMon, 29 May 2017 23:45:00 +0000.NET CultureInfo in Windows 10
<p>Did you know that the CultureInfo behavior with <strong>“unkown”</strong> cultures has changed with Windows 10?</p>
<p>I stumbled two times about this “problem” - so this is enough to write a short blogpost about it.</p>
<h2 id="demo-code">Demo Code</h2>
<p>Lets use this democode:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> try
{
// ok on Win10, but not on pre Win10 if culture is not registred
CultureInfo culture1 = new CultureInfo("foo");
CultureInfo culture2 = new CultureInfo("xyz");
CultureInfo culture3 = new CultureInfo("en-xy");
// not ok even on Win 10 - exception
CultureInfo culture4 = new CultureInfo("foox");
}
catch (Exception exc)
{
}
</code></pre></div></div>
<h2 id="windows-10-case">Windows 10 Case</h2>
<p>If you run this code under Windows 10 it should fail for the “foox” culture, because it doesn’t seem to be a valid culture anyway.</p>
<p>“culture1”, “culture2”, “culture3” are all <strong>valid</strong> cultures in the Windows 10 world, but are resolved with <strong>Unkown Locale</strong> and <strong>LCID 4096</strong>.</p>
<p><em>I guess Windows will look for a 2 or 3 letter ISO style language, and “foox” doesn’t match this pattern.</em></p>
<h2 id="pre-windows-10---eg-running-on-win-server-2012r2">Pre Windows 10 - e.g. running on Win Server 2012R2</h2>
<p>If you would run the code unter Windows Server 2012 R2 it would fail on the first culture, because there is no “foo” culture registred.</p>
<h2 id="problem">“Problem”</h2>
<p>The main “problem” is that this behavior could lead to some production issues if you develop with Windows 10 and the software is running on a Win 2012 server.</p>
<p><strong>If</strong> you are managing “language” content in your application, be aware of this “limitation” on older Windows versions.</p>
<p>I discovered this problem while debugging our backend admin application. With this ASP.NET frontend it is possible to add or manage “localized” content and the dropdown for the possible language listed a whole bunch of very special, but “Unkown locale” cultures. So we needed to filter out all LCID 4096 cultures to ensure it would run under all Windows versions.</p>
<h2 id="msdn">MSDN</h2>
<p>This behavior is also documented on <strong><a href="https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.lcid%28v=vs.110%29.aspx?f=255&amp;MSPPError=-2147217396">MSDN</a></strong></p>
<p>The <strong><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd373745(v=vs.85).aspx">“Unkown culture” LCID 4096</a></strong> was introduced with Windows Vista, but only with Windows 10 it will be “easy” usable within the .NET Framework.</p>
<h2 id="update-lcid-8192">(update!) LCID 8192?</h2>
<p>Today I was preparing a new machine and I found a pretty interesting case and our application had some problems. I checked the CultureInfo stuff and this is what I got on a Windows 10 machine, that should be a EN-US machine, but somehow ended up with a “Swiss” configuration:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CurrentCulture.LCID: 8192 - English (Switzerland)
CurrentUICulture.LCID: 1033 - English (United States)
</code></pre></div></div>
<p>I have no idea why this machine had this configuration, but the CurrentCulture was set to 8192. After a bit of googling I found the confusing answer from this <a href="https://msdn.microsoft.com/en-us/library/dn363603.aspx?f=255&amp;MSPPError=-2147217396">MSDN “Locale Names without LCIDs”-Site</a>:</p>
<p><em>“If the user has configured any of these locales without LCIDs in their Language Profile, then the system MAY assign them additional values to provide applications with temporary unique identifiers. Those temporary LCIDs can differ between processes, machines, users, and application instances. If a temporary LCID is assigned it will be dynamically assigned at runtime to be 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, 0x4000, 0x4400, 0x4800, or 0x4C00, for the valid language-script-region tags not otherwise listed in this table.”</em></p>
<p>It seems you not only can end up with LCID 4096, but with a wild language combination you can get 8192 or any of those codes above. Be aware of the problems when you are working with LCIDs, because they are more or less <a href="https://blogs.msdn.microsoft.com/shawnste/2013/10/23/lcids-vs-locale-names-and-the-deprecation-of-lcids/">“deprecated”</a>.</p>
https://blog.codeinside.eu/2017/04/23/net-cultureinfo-in-windows10/
https://blog.codeinside.eu/2017/04/23/net-cultureinfo-in-windows10Sun, 23 Apr 2017 23:45:00 +0000How we moved to Visual Studio 2017
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-03-28/vs.png" alt="x" title="VS 2017 installer" /></p>
<p>Visual Studio 2017 has arrived and because of .NET Core and other goodies we wanted to switch fast to the newest release with our product <a href="http://oneoffixx.com/">OneOffixx</a>.</p>
<h2 id="company--product-environment">Company &amp; Product Environment</h2>
<p>In our solution we use some VC++ projects (just for Office Development &amp; building a .NET shim), Windows Installer XML &amp; many C# projects for desktop or ASP.NET stuff.</p>
<p>Our builds are scripted with <strong><a href="http://cakebuild.net">CAKE</a></strong> (see here for some more blogposts about [CAKE}(https://blog.codeinside.eu/2017/02/13/create-nuget-packages-with-cake/) and us the TFS vNext Build to orchestrate everything.</p>
<h2 id="step-1-update-the-development-workstations">Step 1: Update the Development Workstations</h2>
<p>The first step was to update my local dev enviroment and install Visual Studio 2017.</p>
<p>After the installation I started VS and opened our solution and because we have some WIX projects we needed the most recent <strong><a href="http://wixtoolset.org/releases/">Wix 3.11 toolset &amp; the VS 2017 extension</a></strong>.</p>
<h2 id="step-2-vc-update">Step 2: VC++ update</h2>
<p>We wanted a clean VS 2017 enviroment, so we decided to use the most recent <strong>VC++ 2017 runtime</strong> for our VC++ projects.</p>
<h2 id="step-3-project-update">Step 3: project update</h2>
<p>In the past we had some issues that MSBuild used the wrong MSBuild version. Maybe this step is not needed, but we pointed all .csproj files to the newest <strong>MSBuild ToolVersion 15.0</strong>.</p>
<h2 id="step-4-cake-update">Step 4: CAKE update</h2>
<p>The last step was to update the CAKE.exe (which is controlled by us and not automatically downloaded via a build script) to 0.18.</p>
<h2 id="step-5-minor-build-script-changes">Step 5: Minor build script changes</h2>
<p>We needed to adjust some paths (e.g. to the Windows SDK for signtool.exe) and ensure that we are using the most recent MSBuild.exe.</p>
<h2 id="step-6-create-a-new-build-agent">Step 6: Create a new Build-Agent</h2>
<p>We decided to create a <strong><a href="https://blog.codeinside.eu/2016/08/10/adding-a-new-windowsagent-to-tfs2015-build/">new TFS Build-Agent</a></strong> and do the usual build agent installation, imported the code-cert and do some magic because of some C++/COM-magic (don’t ask… COM sucks.)</p>
<h2 id="recap">Recap</h2>
<p>Besides the C++/COM/magic issue (see above) the migration was pretty easy and now our team works with Visual Studio 2017.</p>
https://blog.codeinside.eu/2017/03/27/how-we-moved-to-vs-2017/
https://blog.codeinside.eu/2017/03/27/how-we-moved-to-vs-2017Mon, 27 Mar 2017 23:45:00 +0000HowTo: Get User Information & Group Memberships from Active Directory via C#
<p>I had to find a way to access all group memberships from a given Active Directory user. The problem here is, that groups may contain other groups and I needed a list of “all” applied group memberships - directly or indirectly.</p>
<p>The “fastest” solution (without querying each group) is to use the <strong><a href="https://msdn.microsoft.com/en-us/library/ms680275(v=vs.85).aspx">Token-Groups attribute</a></strong>, which already does this magic for us.
This list should contain <strong>all</strong> applied groups.</p>
<p>The code would also allow to read any other AD property, e.g. the UPN or names etc.</p>
<h2 id="code">Code</h2>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class Program
{
static void Main(string[] args)
{
Console.WriteLine("ListAllGroupsViaTokenGroups:");
List&lt;string&gt; result = new List&lt;string&gt;();
try
{
result = ListAllGroupsViaTokenGroups("USERNAME", "DOMAIN");
foreach (var group in result)
{
Console.WriteLine(group);
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
Console.Read();
}
private static List&lt;string&gt; ListAllGroupsViaTokenGroups(string username, string domainName)
{
List&lt;string&gt; result = new List&lt;string&gt;();
using (PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, domainName))
using (var searcher = new DirectorySearcher(new DirectoryEntry("LDAP://" + domainContext.Name)))
{
searcher.Filter = String.Format("(&amp;(objectClass=user)(sAMAccountName={0}))", username);
SearchResult sr = searcher.FindOne();
DirectoryEntry user = sr.GetDirectoryEntry();
// access to other user properties, via user.Properties["..."]
user.RefreshCache(new string[] { "tokenGroups" });
for (int i = 0; i &lt; user.Properties["tokenGroups"].Count; i++)
{
SecurityIdentifier sid = new SecurityIdentifier((byte[])user.Properties["tokenGroups"][i], 0);
NTAccount nt = (NTAccount)sid.Translate(typeof(NTAccount));
result.Add(nt.Translate(typeof(NTAccount)).ToString() + " (" + sid + ")");
}
}
return result;
}
}
</code></pre></div></div>
<p>Hope this will help someone in the future.</p>
<p><strong><a href="https://github.com/Code-Inside/Samples/tree/master/2017/ADLookupWithGroups">Code @ GitHub</a></strong></p>
https://blog.codeinside.eu/2017/03/02/howto-get-user-information-and-groups-from-ad/
https://blog.codeinside.eu/2017/03/02/howto-get-user-information-and-groups-from-adThu, 02 Mar 2017 23:45:00 +0000Create NuGet packages with Cake
<p>This blogpost is a follow up to these <strong><a href="http://cakebuild.net/">Cake (C# Make)</a></strong> related blogpost:</p>
<ul>
<li><a href="https://blog.codeinside.eu/2016/07/09/cake-building-with-cake/">Building with Cake</a></li>
<li><a href="https://blog.codeinside.eu/2017/02/07/build-and-run-xunit-tests-with-cake/">Build &amp; run xUnit tests with Cake</a></li>
</ul>
<h2 id="scenario">Scenario</h2>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-02-13/proj.png" alt="x" title="Demo proj" /></p>
<p>Let’s say we have this project structure. The “Config”, “Result” and “Engine” projects contains a corresponding .nuspec, like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0"?&gt;</span>
<span class="nt">&lt;package</span> <span class="nt">&gt;</span>
<span class="nt">&lt;metadata&gt;</span>
<span class="nt">&lt;id&gt;</span>Sloader.Config<span class="nt">&lt;/id&gt;</span>
<span class="nt">&lt;version&gt;</span>$version$<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;title&gt;</span>Sloader.Config<span class="nt">&lt;/title&gt;</span>
<span class="nt">&lt;authors&gt;</span>Code Inside Team<span class="nt">&lt;/authors&gt;</span>
<span class="nt">&lt;owners&gt;</span>Code Inside Team<span class="nt">&lt;/owners&gt;</span>
<span class="nt">&lt;licenseUrl&gt;</span>https://github.com/Code-Inside/Sloader/blob/master/LICENSE<span class="nt">&lt;/licenseUrl&gt;</span>
<span class="nt">&lt;projectUrl&gt;</span>https://github.com/Code-Inside/Sloader<span class="nt">&lt;/projectUrl&gt;</span>
<span class="nt">&lt;requireLicenseAcceptance&gt;</span>false<span class="nt">&lt;/requireLicenseAcceptance&gt;</span>
<span class="nt">&lt;description&gt;</span>Sloader Config<span class="nt">&lt;/description&gt;</span>
<span class="nt">&lt;releaseNotes&gt;</span>
## Version 0.1 ##
Init
<span class="nt">&lt;/releaseNotes&gt;</span>
<span class="nt">&lt;copyright&gt;</span>Copyright 2017<span class="nt">&lt;/copyright&gt;</span>
<span class="nt">&lt;tags&gt;</span>Sloader<span class="nt">&lt;/tags&gt;</span>
<span class="nt">&lt;dependencies</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/metadata&gt;</span>
<span class="nt">&lt;/package&gt;</span>
</code></pre></div></div>
<p>Nothing fancy - pretty normal NuGet stuff, but be aware of the “$version$” variable. This variable is called a <a href="https://docs.microsoft.com/de-de/nuget/schema/nuspec#replacement-tokens">“replacement-token”</a>. When the NuGet package is created and it detects such a replacement-token, it will search for the AssemblyVersion (or other replacement-token sources).</p>
<p><strong>Versioning in NuGet:</strong></p>
<p>I’m not a NuGet expert, but you should also versioning your assembly info, otherwise some systems may have trouble to update your dll. The version inside the package can be different from the actual assembly version, but you should manage booth or use this replacement-token-mechanic.</p>
<h2 id="goal">Goal</h2>
<p>The goal is to create a NuGet package for each target project with Cake.</p>
<h2 id="buildcake">build.cake</h2>
<p>The usage in Cake is pretty much the same as with the normal <strong><a href="https://docs.microsoft.com/en-us/nuget/tools/nuget-exe-cli-reference#pack">nuget.exe pack</a></strong> command
The sample only shows the actual cake target - see the older blogposts for a more complete example:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Task("BuildPackages")
.IsDependentOn("Restore-NuGet-Packages")
.IsDependentOn("RunTests")
.Does(() =&gt;
{
var nuGetPackSettings = new NuGetPackSettings
{
OutputDirectory = rootAbsoluteDir + @"\artifacts\",
IncludeReferencedProjects = true,
Properties = new Dictionary&lt;string, string&gt;
{
{ "Configuration", "Release" }
}
};
MSBuild("./src/Sloader.Config/Sloader.Config.csproj", new MSBuildSettings().SetConfiguration("Release"));
NuGetPack("./src/Sloader.Config/Sloader.Config.csproj", nuGetPackSettings);
MSBuild("./src/Sloader.Result/Sloader.Result.csproj", new MSBuildSettings().SetConfiguration("Release"));
NuGetPack("./src/Sloader.Result/Sloader.Result.csproj", nuGetPackSettings);
MSBuild("./src/Sloader.Engine/Sloader.Engine.csproj", new MSBuildSettings().SetConfiguration("Release"));
NuGetPack("./src/Sloader.Engine/Sloader.Engine.csproj", nuGetPackSettings);
});
</code></pre></div></div>
<p>Easy, right? The most interesting part here is the <a href="http://cakebuild.net/api/Cake.Common.Tools.NuGet/NuGetAliases/EF4ED944">NuGetPack</a> command. Before we invoke this command we need to make sure that we build the last recent version - to enforce that we just rebuild each project in release mode.</p>
<h2 id="result">Result</h2>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-02-13/result.png" alt="x" title="NuGet packages!" /></p>
<p>The console output should make the flow pretty clear:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PS C:\Users\Robert\Documents\GitHub\Sloader&gt; .\build.ps1 -t BuildPackages
Preparing to run build script...
Running build script...
Analyzing build script...
Processing build script...
Installing tools...
Compiling build script...
========================================
Clean
========================================
Executing task: Clean
Cleaning directory C:/Users/Robert/Documents/GitHub/Sloader/artifacts
Finished executing task: Clean
========================================
Restore-NuGet-Packages
========================================
Executing task: Restore-NuGet-Packages
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
All packages listed in packages.config are already installed.
Finished executing task: Restore-NuGet-Packages
========================================
BuildTests
========================================
Executing task: BuildTests
Start Building Test: Sloader.Config.Tests
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Sloader.Config -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Config.Tests\Sloader.Config.dll
Sloader.Config.Tests -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Config.Tests\Sloader.Config
.Tests.dll
Start Building Test: Sloader.Result.Tests
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Sloader.Result -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Result.Tests\Sloader.Result.dll
Sloader.Result.Tests -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Result.Tests\Sloader.Result
.Tests.dll
Start Building Test: Sloader.Engine.Tests
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Sloader.Config -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Config.dll
Sloader.Result -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Result.dll
Sloader.Engine -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Engine.dll
Sloader.Engine.Tests -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Engine
.Tests.dll
Finished executing task: BuildTests
========================================
RunTests
========================================
Executing task: RunTests
Start Running Tests
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
Discovering: Sloader.Config.Tests
Discovered: Sloader.Config.Tests
Starting: Sloader.Config.Tests
Finished: Sloader.Config.Tests
Discovering: Sloader.Engine.Tests
Discovered: Sloader.Engine.Tests
Starting: Sloader.Engine.Tests
Finished: Sloader.Engine.Tests
Discovering: Sloader.Result.Tests
Discovered: Sloader.Result.Tests
Starting: Sloader.Result.Tests
Finished: Sloader.Result.Tests
=== TEST EXECUTION SUMMARY ===
Sloader.Config.Tests Total: 23, Errors: 0, Failed: 0, Skipped: 0, Time: 0.554s
Sloader.Engine.Tests Total: 17, Errors: 0, Failed: 0, Skipped: 0, Time: 1.070s
Sloader.Result.Tests Total: 4, Errors: 0, Failed: 0, Skipped: 0, Time: 1.061s
-- - - - ------
GRAND TOTAL: 44 0 0 0 2.684s (5.697s)
Finished executing task: RunTests
========================================
BuildPackages
========================================
Executing task: BuildPackages
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 2017-02-19 22:00:09.
The target "_ConvertPdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,37)" does not exist in the project, and will be ignored.
The target "_CollectPdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,70)" does not exist in the project, and will be ignored.
The target "_CollectMdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (41,38)" does not exist in the project, and will be ignored.
The target "_CopyMdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common
.targets\ImportAfter\Xamarin.Common.targets (41,71)" does not exist in the project, and will be ignored.
Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Config\Sloader.Config.csproj" on node 1 (Build target(s))
.
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the i
nput files.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
Sloader.Config -&gt; C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Config\bin\Release\Sloader.Config.dll
Done Building Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Config\Sloader.Config.csproj" (Build target
(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.22
Attempting to build package from 'Sloader.Config.csproj'.
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
Packing files from 'C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Config\bin\Release'.
Using 'Sloader.Config.nuspec' for metadata.
Found packages.config. Using packages listed as dependencies
Successfully created package 'C:\Users\Robert\Documents\GitHub\Sloader\artifacts\Sloader.Config.0.2.1.nupkg'.
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 2017-02-19 22:00:10.
The target "_ConvertPdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,37)" does not exist in the project, and will be ignored.
The target "_CollectPdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,70)" does not exist in the project, and will be ignored.
The target "_CollectMdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (41,38)" does not exist in the project, and will be ignored.
The target "_CopyMdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common
.targets\ImportAfter\Xamarin.Common.targets (41,71)" does not exist in the project, and will be ignored.
Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Result\Sloader.Result.csproj" on node 1 (Build target(s))
.
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the i
nput files.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
Sloader.Result -&gt; C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Result\bin\Release\Sloader.Result.dll
Done Building Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Result\Sloader.Result.csproj" (Build target
(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.24
Attempting to build package from 'Sloader.Result.csproj'.
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
Packing files from 'C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Result\bin\Release'.
Using 'Sloader.Result.nuspec' for metadata.
Found packages.config. Using packages listed as dependencies
Successfully created package 'C:\Users\Robert\Documents\GitHub\Sloader\artifacts\Sloader.Result.0.2.1.nupkg'.
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 2017-02-19 22:00:12.
The target "_ConvertPdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,37)" does not exist in the project, and will be ignored.
The target "_CollectPdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,70)" does not exist in the project, and will be ignored.
The target "_CollectMdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (41,38)" does not exist in the project, and will be ignored.
The target "_CopyMdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common
.targets\ImportAfter\Xamarin.Common.targets (41,71)" does not exist in the project, and will be ignored.
The target "_ConvertPdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,37)" does not exist in the project, and will be ignored.
The target "_CollectPdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,70)" does not exist in the project, and will be ignored.
The target "_CollectMdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (41,38)" does not exist in the project, and will be ignored.
The target "_CopyMdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common
.targets\ImportAfter\Xamarin.Common.targets (41,71)" does not exist in the project, and will be ignored.
Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Engine\Sloader.Engine.csproj" on node 1 (Build target(s))
.
Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Engine\Sloader.Engine.csproj" (1) is building "C:\Users\R
obert\Documents\GitHub\Sloader\src\Sloader.Config\Sloader.Config.csproj" (2) on node 1 (default targets).
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the i
nput files.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
Sloader.Config -&gt; C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Config\bin\Release\Sloader.Config.dll
Done Building Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Config\Sloader.Config.csproj" (default targ
ets).
The target "_ConvertPdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,37)" does not exist in the project, and will be ignored.
The target "_CollectPdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (34,70)" does not exist in the project, and will be ignored.
The target "_CollectMdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Com
mon.targets\ImportAfter\Xamarin.Common.targets (41,38)" does not exist in the project, and will be ignored.
The target "_CopyMdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common
.targets\ImportAfter\Xamarin.Common.targets (41,71)" does not exist in the project, and will be ignored.
Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Engine\Sloader.Engine.csproj" (1) is building "C:\Users\R
obert\Documents\GitHub\Sloader\src\Sloader.Result\Sloader.Result.csproj" (3) on node 1 (default targets).
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the i
nput files.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
Sloader.Result -&gt; C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Result\bin\Release\Sloader.Result.dll
Done Building Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Result\Sloader.Result.csproj" (default targ
ets).
BclBuildEnsureBindingRedirects:
Skipping target "BclBuildEnsureBindingRedirects" because all output files are up-to-date with respect to the input file
s.
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the i
nput files.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
_CopyAppConfigFile:
Skipping target "_CopyAppConfigFile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
Sloader.Engine -&gt; C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Engine\bin\Release\Sloader.Engine.dll
Done Building Project "C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Engine\Sloader.Engine.csproj" (Build target
(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.54
Attempting to build package from 'Sloader.Engine.csproj'.
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
Packing files from 'C:\Users\Robert\Documents\GitHub\Sloader\src\Sloader.Engine\bin\Release'.
Using 'Sloader.Engine.nuspec' for metadata.
Found packages.config. Using packages listed as dependencies
Successfully created package 'C:\Users\Robert\Documents\GitHub\Sloader\artifacts\Sloader.Engine.0.2.1.nupkg'.
Finished executing task: BuildPackages
Task Duration
--------------------------------------------------
Clean 00:00:00.1083837
Restore-NuGet-Packages 00:00:00.7808530
BuildTests 00:00:02.6296445
RunTests 00:00:05.9397822
BuildPackages 00:00:05.2679058
--------------------------------------------------
Total: 00:00:14.7265692
</code></pre></div></div>
https://blog.codeinside.eu/2017/02/13/create-nuget-packages-with-cake/
https://blog.codeinside.eu/2017/02/13/create-nuget-packages-with-cakeMon, 13 Feb 2017 23:45:00 +0000Build & run xUnit tests with Cake
<p>Last year I already covered the <strong><a href="https://blog.codeinside.eu/2016/07/09/cake-building-with-cake/">basic usage of Cake</a></strong>, which stands for “C# Make”. This time we want to build and run <strong><a href="https://xunit.github.io/">xUnit</a></strong> tests with Cake.</p>
<h2 id="scenario">Scenario</h2>
<p><img src="https://blog.codeinside.eu/assets/md-images/2017-02-07/proj.png" alt="x" title="Demo proj" /></p>
<p>Let’s say we have this project structure. Be aware that all our tests have the suffix “Tests” in the project name.</p>
<p>The files are organized like this, so we have all “Tests” in a “tests” folder and the actual code under “src”:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>src/Sloader.Config
src/Sloader.Engine
src/Sloader.Hosts.Console
src/Sloader.Result
tests/Sloader.Config.Tests
tests/Sloader.Engine.Tests
tests/Sloader.Result.Tests
.gitignore
build.cake
build.ps1
LICENSE
Sloader.sln
</code></pre></div></div>
<h2 id="goal">Goal</h2>
<p>Now we want to build all tests projects and run them with the xUnit console runner. Be aware that there are multiple ways of doing it, but I found this quite good.</p>
<h2 id="buildcake">build.cake</h2>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#tool "nuget:?package=xunit.runner.console"
//////////////////////////////////////////////////////////////////////
// ARGUMENTS
//////////////////////////////////////////////////////////////////////
var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
//////////////////////////////////////////////////////////////////////
// PREPARATION
//////////////////////////////////////////////////////////////////////
// Define directories.
var artifactsDir = Directory("./artifacts/");
var rootAbsoluteDir = MakeAbsolute(Directory("./")).FullPath;
//////////////////////////////////////////////////////////////////////
// TASKS
//////////////////////////////////////////////////////////////////////
Task("Clean")
.Does(() =&gt;
{
CleanDirectory(artifactsDir);
});
Task("Restore-NuGet-Packages")
.IsDependentOn("Clean")
.Does(() =&gt;
{
NuGetRestore("./Sloader.sln");
});
Task("Build")
.IsDependentOn("Restore-NuGet-Packages")
.Does(() =&gt;
{
});
Task("BuildTests")
.IsDependentOn("Restore-NuGet-Packages")
.Does(() =&gt;
{
var parsedSolution = ParseSolution("./Sloader.sln");
foreach(var project in parsedSolution.Projects)
{
if(project.Name.EndsWith(".Tests"))
{
Information("Start Building Test: " + project.Name);
MSBuild(project.Path, new MSBuildSettings()
.SetConfiguration("Debug")
.SetMSBuildPlatform(MSBuildPlatform.Automatic)
.SetVerbosity(Verbosity.Minimal)
.WithProperty("SolutionDir", @".\")
.WithProperty("OutDir", rootAbsoluteDir + @"\artifacts\_tests\" + project.Name + @"\"));
}
}
});
Task("RunTests")
.IsDependentOn("BuildTests")
.Does(() =&gt;
{
Information("Start Running Tests");
XUnit2("./artifacts/_tests/**/*.Tests.dll");
});
//////////////////////////////////////////////////////////////////////
// TASK TARGETS
//////////////////////////////////////////////////////////////////////
Task("Default")
.IsDependentOn("RunTests");
//////////////////////////////////////////////////////////////////////
// EXECUTION
//////////////////////////////////////////////////////////////////////
RunTarget(target);
</code></pre></div></div>
<h2 id="explanation-buildtests">Explanation: BuildTests?</h2>
<p>The default target “Default” will trigger “RunTests”, which depend on “BuildTests”.</p>
<p>Inside the “BuildTests”-target we use a handy helper from Cake and we parse the .sln file and search all “Test”-projects.
With that information we can build each test individually and don’t have to worry over “overlapping” files.
The output of this build will be saved at <strong>“artifacts/_tests”</strong>.</p>
<h2 id="running-xunit">Running xUnit</h2>
<p>To run <a href="http://cakebuild.net/dsl/xunit-v2/">xUnit</a> we have to include the runner at the top of the cake file:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#tool "nuget:?package=xunit.runner.console"
</code></pre></div></div>
<p>Now we can just invoke XUnit2 and scan for all Tests.dlls and we are done:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>XUnit2("./artifacts/_tests/**/*.Tests.dll");
</code></pre></div></div>
<h2 id="result">Result</h2>
<p>The console output should make the flow pretty clear:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PS C:\Users\Robert\Documents\GitHub\Sloader&gt; .\build.ps1
Preparing to run build script...
Running build script...
Analyzing build script...
Processing build script...
Installing tools...
Compiling build script...
========================================
Clean
========================================
Executing task: Clean
Creating directory C:/Users/Robert/Documents/GitHub/Sloader/artifacts
Finished executing task: Clean
========================================
Restore-NuGet-Packages
========================================
Executing task: Restore-NuGet-Packages
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
All packages listed in packages.config are already installed.
Finished executing task: Restore-NuGet-Packages
========================================
BuildTests
========================================
Executing task: BuildTests
Start Building Test: Sloader.Config.Tests
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Sloader.Config -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Config.Tests\Sloader.Config.dll
Sloader.Config.Tests -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Config.Tests\Sloader.Config
.Tests.dll
Start Building Test: Sloader.Result.Tests
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Sloader.Result -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Result.Tests\Sloader.Result.dll
Sloader.Result.Tests -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Result.Tests\Sloader.Result
.Tests.dll
Start Building Test: Sloader.Engine.Tests
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Sloader.Config -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Config.dll
Sloader.Result -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Result.dll
Sloader.Engine -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Engine.dll
Sloader.Engine.Tests -&gt; C:\Users\Robert\Documents\GitHub\Sloader\artifacts\_tests\Sloader.Engine.Tests\Sloader.Engine
.Tests.dll
Finished executing task: BuildTests
========================================
RunTests
========================================
Executing task: RunTests
Start Running Tests
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
Discovering: Sloader.Config.Tests
Discovered: Sloader.Config.Tests
Starting: Sloader.Config.Tests
Finished: Sloader.Config.Tests
Discovering: Sloader.Engine.Tests
Discovered: Sloader.Engine.Tests
Starting: Sloader.Engine.Tests
Finished: Sloader.Engine.Tests
Discovering: Sloader.Result.Tests
Discovered: Sloader.Result.Tests
Starting: Sloader.Result.Tests
Finished: Sloader.Result.Tests
=== TEST EXECUTION SUMMARY ===
Sloader.Config.Tests Total: 22, Errors: 0, Failed: 0, Skipped: 0, Time: 0.342s
Sloader.Engine.Tests Total: 9, Errors: 0, Failed: 0, Skipped: 0, Time: 0.752s
Sloader.Result.Tests Total: 4, Errors: 0, Failed: 0, Skipped: 0, Time: 0.475s
-- - - - ------
GRAND TOTAL: 35 0 0 0 1.569s (3.115s)
Finished executing task: RunTests
========================================
Default
========================================
Executing task: Default
Finished executing task: Default
Task Duration
--------------------------------------------------
Clean 00:00:00.0155255
Restore-NuGet-Packages 00:00:00.5065704
BuildTests 00:00:02.1590662
RunTests 00:00:03.2443534
Default 00:00:00.0061325
--------------------------------------------------
Total: 00:00:05.9316480
</code></pre></div></div>
https://blog.codeinside.eu/2017/02/07/build-and-run-xunit-tests-with-cake/
https://blog.codeinside.eu/2017/02/07/build-and-run-xunit-tests-with-cakeTue, 07 Feb 2017 23:45:00 +0000GitHub API: Create or update files
<p>This blogpost covers a pretty basic GitHub topic: Creating and updating content on GitHub. Of course, there are many ways to do it - e.g. you could do the full Git-ceremony and it would work with all Git hosts, but in my case I just wanted to target the <a href="https://developer.github.com/v3/"><strong>offical GitHub API</strong></a>.</p>
<h2 id="prerequisite-a-github-user-repo-and-token">Prerequisite: A GitHub User, Repo and Token</h2>
<p>To use this code you will need write access to a GitHub repository and you should have a valid <a href="https://github.com/settings/tokens">GitHub token</a>.</p>
<h2 id="code">Code</h2>
<p>The most simple way to communicate with the <a href="https://developer.github.com/v3/">GitHub API</a> is by using the <a href="https://www.nuget.org/packages/Octokit/">Octokit SDK</a> (from GitHub).</p>
<p>Description:
Inside the try-block we try to <a href="https://developer.github.com/v3/repos/contents/#get-contents">get the target file</a>, if it is already committed in the repo the API will return the last commit SHA.</p>
<p>With this SHA it is possible to <a href="https://developer.github.com/v3/repos/contents/#update-a-file">create a new commit to do the actual update</a>.</p>
<p>If the file was not found, <a href="https://developer.github.com/v3/repos/contents/#create-a-file">we create the file</a>. I’m not a huge fan of this try/catch block, but didn’t found any other way to check if the file is comitted or not (please give me a hint if this is wrong ;))</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Octokit;
namespace CreateOrUpdateGitHubFile
{
class Program
{
static void Main(string[] args)
{
Task.Run(async () =&gt;
{
var ghClient = new GitHubClient(new ProductHeaderValue("Octokit-Test"));
ghClient.Credentials = new Credentials("ACCESS-TOKEN");
// github variables
var owner = "OWNER";
var repo = "REPO";
var branch = "BRANCH";
var targetFile = "_data/test.txt";
try
{
// try to get the file (and with the file the last commit sha)
var existingFile = await ghClient.Repository.Content.GetAllContentsByRef(owner, repo, targetFile, branch);
// update the file
var updateChangeSet = await ghClient.Repository.Content.UpdateFile(owner, repo, targetFile,
new UpdateFileRequest("API File update", "Hello Universe! " + DateTime.UtcNow, existingFile.First().Sha, branch));
}
catch (Octokit.NotFoundException)
{
// if file is not found, create it
var createChangeSet = await ghClient.Repository.Content.CreateFile(owner,repo, targetFile, new CreateFileRequest("API File creation", "Hello Universe! " + DateTime.UtcNow, branch));
}
}).Wait();
}
}
}
</code></pre></div></div>
<p>The demo code is also available on <a href="https://github.com/Code-Inside/Samples/tree/master/2017/CreateOrUpdateGitHubFile"><strong>GitHub</strong></a>.</p>
<p>Hope this helps.</p>
https://blog.codeinside.eu/2017/01/02/create-or-update-files-via-the-github-api/
https://blog.codeinside.eu/2017/01/02/create-or-update-files-via-the-github-apiMon, 02 Jan 2017 23:45:00 +0000DbProviderFactories: Write database agnostic ADO.NET code
<p>Recently I needed to write a module that needs to connect to a wide range of SQL-DBs, e.g. MySQL, MS SQL, Oracle etc.</p>
<h2 id="problem-most-providers-will-use-their-concret-classes">Problem: Most providers will use their concret classes</h2>
<p>If you look at the C# example on the <a href="https://dev.mysql.com/doc/connector-net/en/connector-net-programming-connecting-open.html">MySQL dev page</a> you will see the MsSql-Namespace and classes:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MySql.Data.MySqlClient.MySqlConnection conn;
string myConnectionString;
myConnectionString = "server=127.0.0.1;uid=root;" +
"pwd=12345;database=test;";
try
{
conn = new MySql.Data.MySqlClient.MySqlConnection();
conn.ConnectionString = myConnectionString;
conn.Open();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
MessageBox.Show(ex.Message);
}
</code></pre></div></div>
<p>The same classes will probably not work for a MS SQL database.</p>
<h2 id="solution-use-the-dbproviderfactories">“Solution”: Use the DbProviderFactories</h2>
<p>For example if you install the <a href="https://www.nuget.org/packages/MySql.Data">MySql-NuGet package</a> you will also get this little enhancement to you app.config:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;system.data&gt;
&lt;DbProviderFactories&gt;
&lt;remove invariant="MySql.Data.MySqlClient" /&gt;
&lt;add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" /&gt;
&lt;/DbProviderFactories&gt;
&lt;/system.data&gt;
</code></pre></div></div>
<p>Now we can get a reference to the MySql client via the DbProviderFactories:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System;
using System.Data;
using System.Data.Common;
namespace DbProviderFactoryStuff
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("All registered DbProviderFactories:");
var allFactoryClasses = DbProviderFactories.GetFactoryClasses();
foreach (DataRow row in allFactoryClasses.Rows)
{
Console.WriteLine(row[0] + ": " + row[2]);
}
Console.WriteLine();
Console.WriteLine("Try to access a MySql DB:");
DbProviderFactory dbf = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
using (DbConnection dbcn = dbf.CreateConnection())
{
dbcn.ConnectionString = "Server=localhost;Database=testdb;Uid=root;Pwd=Pass1word;";
dbcn.Open();
using (DbCommand dbcmd = dbcn.CreateCommand())
{
dbcmd.CommandType = CommandType.Text;
dbcmd.CommandText = "SHOW TABLES;";
// parameter...
//var foo = dbcmd.CreateParameter();
//foo.ParameterName = "...";
//foo.Value = "...";
using (DbDataReader dbrdr = dbcmd.ExecuteReader())
{
while (dbrdr.Read())
{
Console.WriteLine(dbrdr[0]);
}
}
}
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
Console.ReadLine();
}
}
}
</code></pre></div></div>
<p>The most important line is this one:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DbProviderFactory dbf = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
</code></pre></div></div>
<p>Now with the <a href="https://msdn.microsoft.com/en-us/library/system.data.common.dbproviderfactory(v=vs.110).aspx"><strong>DbProviderFactory</strong></a> from the MySql client we can access the MySql database without using any MySql-specific classes.</p>
<p>There are a couple of “in-built” db providers registered, like the MS SQL provider or ODBC stuff.</p>
<p>The above code will output something like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>All registered DbProviderFactories:
Odbc Data Provider: System.Data.Odbc
OleDb Data Provider: System.Data.OleDb
OracleClient Data Provider: System.Data.OracleClient
SqlClient Data Provider: System.Data.SqlClient
Microsoft SQL Server Compact Data Provider 4.0: System.Data.SqlServerCe.4.0
MySQL Data Provider: MySql.Data.MySqlClient
</code></pre></div></div>
<h2 id="other-solutions">Other solutions</h2>
<p>Of course there are other solutions - some OR-Mapper like the EntityFramework have a provider model which might also work, but this one here is a pretty basic approach.</p>
<h2 id="sql-commands">SQL Commands</h2>
<p>The tricky bit here is that you need to make sure that your SQL commands work on your database - this is <strong>not a silver bullet</strong>, it <strong>just lets you connect and execute SQL commands to any ‘registered’ database</strong>.</p>
<p>The full demo code is also available on <a href="https://github.com/Code-Inside/Samples/tree/master/2016/DbProviderFactoryStuff"><strong>GitHub</strong></a>.</p>
<p>Hope this helps.</p>
https://blog.codeinside.eu/2016/12/31/dbproviderfactory-write-database-agnostic-adonet-code/
https://blog.codeinside.eu/2016/12/31/dbproviderfactory-write-database-agnostic-adonet-codeSat, 31 Dec 2016 14:00:00 +0000Enable SSL with custom domains on GitHub Pages via Cloudflare
<p>Two weeks ago I decided (finally!) that I should enable SSL on this blog.</p>
<h2 id="problem-github-pages-with-a-custom-domain">Problem: GitHub Pages with a custom domain</h2>
<p>This blog is hosted on GitHub Pages with a custom domain, which currently doesn’t support SSL out of the box. If you stick with a github.io domain SSL is not a problem.</p>
<h2 id="cloudflare-to-the-rescure">Cloudflare to the rescure</h2>
<p>I decided to take a deeper look at <strong><a href="https://www.cloudflare.com">Cloudflare</a></strong>, which provides DNS, CDN and other “network”-related services. For the “main” service Cloudflare serves as the DNS for your domain and is like a proxy.</p>
<p>With this setup you have some nice benefits:</p>
<ul>
<li>A free SSL certificate (AFAIK you can also use your own cert if you need)</li>
<li>A CDN cache</li>
<li>DDOS protection</li>
<li>“Analytics”</li>
</ul>
<p>Be aware: This is just the <strong>free plan</strong>.</p>
<p>And everything is pretty easy to manage via the web interface.</p>
<h3 id="setup">Setup</h3>
<p>The first step is to register at Cloudflare &amp; setup your domain. After the first step you need to change the name server for your domain to Cloudflares server.</p>
<p>All your domain belonging can now be managed inside Cloudflare:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2016-11-14/dns.png" alt="x" title="DNS" /></p>
<h3 id="setting-up-some-rules">Setting up some rules</h3>
<p>When your DNS changes are done (which can take a couple of hours) you might want to introduce some basic rules. I use these settings, which enforces HTTPS and Cloudflare cache:</p>
<p><img src="https://blog.codeinside.eu/assets/md-images/2016-11-14/rules.png" alt="x" title="Rules" /></p>
<h3 id="done-or-nearly-done">Done… or nearly done.</h3>
<p>Now we have done the “Cloudflare-part”. The next step is to make sure that everything on your page uses HTTPS instead of HTTP to avoid “mixed content”-errors.</p>
<p>Some notes from my own “migration”:</p>
<ul>
<li>If you have Google Analytics - make sure you change the property-settings to the HTTPS URL</li>
<li>If you use Disqus you <strong>need</strong> to migrate your comments from the HTTP url to the HTTPS URL. There is a migrate tool available, which uses a CSV file.</li>
</ul>
<h2 id="other-solutions">Other solutions…</h2>
<p>As far as I know there are other, similar, providers out there and of course you can host the page yourself.</p>
<p>Cloudflare is an easy solution if you are willing to hand of the DNS settings of your domain.</p>
<p>Hope this helps!</p>
https://blog.codeinside.eu/2016/11/14/ssl-with-custom-domains-on-gh-pages-via-cloudflare/
https://blog.codeinside.eu/2016/11/14/ssl-with-custom-domains-on-gh-pages-via-cloudflareMon, 14 Nov 2016 23:15:00 +0000