<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><generator uri="http://jekyllrb.com" version="3.1.6">Jekyll</generator><link href="http://teelahti.fi/feed.xml" rel="self" type="application/atom+xml" /><link href="http://teelahti.fi/" rel="alternate" type="text/html" /><updated>2016-06-29T08:14:21+03:00</updated><id>http://teelahti.fi/</id><title>Tero Teelahti</title><subtitle>Tero Teelahti&#39;s personal blog. Mostly development posts with a slight web focus.</subtitle><entry><title>Using Protocol buffers v3 with ASP.NET core</title><link href="http://teelahti.fi/using-google-proto3-with-aspnet-mvc/" rel="alternate" type="text/html" title="Using Protocol buffers v3 with ASP.NET core" /><published>2016-03-11T00:00:00+02:00</published><updated>2016-03-11T00:00:00+02:00</updated><id>http://teelahti.fi/using-google-proto3-with-aspnet-mvc</id><content type="html" xml:base="http://teelahti.fi/using-google-proto3-with-aspnet-mvc/">&lt;p&gt;By default &lt;a href=&quot;https://docs.asp.net/&quot;&gt;ASP.NET core&lt;/a&gt; API methods operate on JSON: they deserialize JSON from request/response
body to model type and back. JSON is everywhere and works well… unless you have very high
throughput requirements. There are many alternative formats, but
Google’s serialization format &lt;a href=&quot;https://developers.google.com/protocol-buffers/&quot;&gt;Protocol Buffers&lt;/a&gt;
is one of the most used. It has overgone some changes recently: the old &lt;a href=&quot;https://developers.google.com/protocol-buffers/docs/proto&quot;&gt;proto2&lt;/a&gt;
syntax is replaced with &lt;a href=&quot;https://developers.google.com/protocol-buffers/docs/proto3&quot;&gt;proto3&lt;/a&gt;. The latter
even has an official C# support.&lt;/p&gt;

&lt;p&gt;The old proto2 used to have unofficial C# ports, and many ASP.NET MVC samples on the internet
are based on those. I couldn’t find a working proto3 version, so I created my own.&lt;/p&gt;

&lt;p&gt;To create custom input and output types for ASP.NET two interfaces need to be fullfilled:
IInputFormatter and IOutputFormatter. The easiest way to do this is to inherit from
InputFormatter and OutputFormatter base classes. Basically ASP.NET MVC tells the
content type, content and desired target type, and then custom formatter needs to
act on those.&lt;/p&gt;

&lt;p&gt;Naturally this all needs to work for all possible types, otherwise the formatters would not
be reusable. Proto3 has some strangeness in its APIs, like some of the useful constructors being internal.
Luckily with some source code reading one can find the method that does the real work when
the actual type is not known on compile time: IMessage.MergeFrom(). Working Input and output formatters
are below:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// The input formatter reading request body and mapping it to given data object.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProtobufInputFormatter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InputFormatter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MediaTypeHeaderValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;protoMediaType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MediaTypeHeaderValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;application/x-protobuf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CanRead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputFormatterContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MediaTypeHeaderValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestContentType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MediaTypeHeaderValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TryParse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestContentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;requestContentType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestContentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsSubsetOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;protoMediaType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputFormatterResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ReadRequestBodyAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputFormatterContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Activator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MergeFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InputFormatterResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SuccessAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Exception: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InputFormatterResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FailureAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// The output object mapping returned object to Protobuf-serialized response body.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProtobufOutputFormatter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OutputFormatter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MediaTypeHeaderValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;protoMediaType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MediaTypeHeaderValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;application/x-protobuf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CanWriteResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutputFormatterCanWriteContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsSubsetOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;protoMediaType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Check whether the given object is a proto-generated object
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ObjectType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetTypeInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImplementedInterfaces&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetTypeInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsGenericType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetGenericTypeDefinition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&amp;gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;WriteResponseBodyAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutputFormatterWriteContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Proto-encode
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;protoObj&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serialized&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;protoObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToByteArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serialized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serialized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Formatters need to be registered for ASP.NET MVC to use them. This can be done
in the ConfigureServices method:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddMvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MvcOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputFormatters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ProtobufInputFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutputFormatters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ProtobufOutputFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And that’s it, now you can control the desired format with requests by using either
application/json or application/x-protobuf as content and accept types. You can
even mix and match: send in JSON but request protobuf back.&lt;/p&gt;</content><category term="web" /><category term="aspnet" /><summary>By default ASP.NET core API methods operate on JSON: they deserialize JSON from request/response
body to model type and back. JSON is everywhere and works well… unless you have very high
throughput requirements. There are many alternative formats, but
Google’s serialization format Protocol Buffers
is one of the most used. It has overgone some changes recently: the old proto2
syntax is replaced with proto3. The latter
even has an official C# support.</summary></entry><entry><title>Don’t let techies design game user experience</title><link href="http://teelahti.fi/dont-let-techies-design-game-ux/" rel="alternate" type="text/html" title="Don&#39;t let techies design game user experience" /><published>2016-02-02T00:00:00+02:00</published><updated>2016-02-02T00:00:00+02:00</updated><id>http://teelahti.fi/dont-let-techies-design-game-ux</id><content type="html" xml:base="http://teelahti.fi/dont-let-techies-design-game-ux/">&lt;p&gt;Today I had some 20 minutes spare time and I wanted to try games my co-workers had recommended for me.&lt;/p&gt;

&lt;h2 id=&quot;heartstone&quot;&gt;Heartstone&lt;/h2&gt;

&lt;p&gt;First off was &lt;a href=&quot;http://us.battle.net/hearthstone/en/&quot;&gt;Heartstone - Heroes of warcraft&lt;/a&gt;. I had opened 
the game day before, and was in the middle of the tutorial story. Opening the game again got me slowly
to the same tutorial spot… except when I clicked “Play” I got this:&lt;/p&gt;

&lt;figure&gt;
	&lt;img src=&quot;/images/2016-02-02/heartstone-maintenance-break.png&quot; alt=&quot;Heartstone maintenance break.&quot; /&gt;
    &lt;figcaption&gt;Smells like an american engineer.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Three hour maintenance break is looong, but I can live with that; there might be a valid reason (like 
earthquake or tsunami or blown up data center). Instead, what irritated me, was that&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the game did not tell me from the get-go that service is closed. Made me wait extra 30 s.&lt;/li&gt;
  &lt;li&gt;times are not in local format; it should not come as a surprise to anyone that AM and PM are not universal notations.&lt;/li&gt;
  &lt;li&gt;I’m required to know both current time, and my time difference to PST time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last one is the worst: it puts extra cognitive load on the player. Personally I never figured out 
when the maintenance break ends - I would have needed to open a timezone application or google 
timezones to figure that out.&lt;/p&gt;

&lt;p&gt;Instead of the above message I would like to see maintenance break expressed as duration, e.g.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;We are back online in 1 hour.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;vain-glory&quot;&gt;Vain glory&lt;/h2&gt;

&lt;p&gt;As I never got to play Heartstone, I took the next game in queue: &lt;a href=&quot;http://www.vainglorygame.com/&quot;&gt;Vain Glory&lt;/a&gt;. 
This game I had installed, but never opened. The first user experience I got when opening was this:&lt;/p&gt;

&lt;figure&gt;
	&lt;img src=&quot;/images/2016-02-02/vain-glory-downloading-asset-file.png&quot; alt=&quot;Vain Glory downloading asset file.&quot; /&gt;
    &lt;figcaption&gt;Some game jargon for you.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;First of all: why does the load take 15 minutes when I’m on a 100 Mb network? Very few people are willing to 
wait this long for a game session. Normally 500 MB of content downloads fast, but this game is different.&lt;/p&gt;

&lt;p&gt;Secondly, what are the random numbers on the lower right of the modal window: no units, no formatting, 
just random. There already is a very clear percentage and the progress bar, why add extra clutter?&lt;/p&gt;

&lt;p&gt;And last: does “Asset File” mean something for normal people? In my opinion that is pure game development 
jargon and should not be shown to players. Most people don’t even know that there are real files loaded 
in the background.&lt;/p&gt;

&lt;p&gt;After all the waiting - just when I thought I would get to play - the game disappointed me with second 
obligatory wait! And of course with another completely meaningless message: “Installing Data”:&lt;/p&gt;

&lt;figure&gt;
	&lt;img src=&quot;/images/2016-02-02/vain-glory-installing-data.png&quot; alt=&quot;Vain Glory installing data.&quot; /&gt;
    &lt;figcaption&gt;Installing what?&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I have the most powerful Android device ever made - the Nexus 6P - and this phase still took 10 minutes. 
And I have no idea what the game did for all that time; maybe it calculated prime numbers or did some 
crowdsourced computing for public good? If there is this heavy computing involved, why isn’t it 
pre-computed on the game backend?&lt;/p&gt;

&lt;p&gt;As a player I would like to see a maximum of one wait with clear progress bar. It should take max minute or two 
on a fast network, and have an uplifting message made for humans. I’m not an english native, but something 
along the lines of&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;We are loading some high quality content for you and it will take a while, but it will be awesome!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alternatively no waiting at all for first time experience, and downloads could continue 
in the background or when player advances in the game.&lt;/p&gt;

&lt;h2 id=&quot;result&quot;&gt;Result?&lt;/h2&gt;

&lt;p&gt;In the end my 20 minute of time was spent and I did not get to play for a second. Game studios did not 
get a dime from me, and my time was wasted. Loose-loose.&lt;/p&gt;</content><category term="games" /><category term="ux" /><summary>Today I had some 20 minutes spare time and I wanted to try games my co-workers had recommended for me.</summary></entry><entry><title>Using VS Team Services with go get</title><link href="http://teelahti.fi/using-vs-team-services-with-go-get/" rel="alternate" type="text/html" title="Using VS Team Services with go get" /><published>2016-01-19T00:00:00+02:00</published><updated>2016-01-19T00:00:00+02:00</updated><id>http://teelahti.fi/using-vs-team-services-with-go-get</id><content type="html" xml:base="http://teelahti.fi/using-vs-team-services-with-go-get/">&lt;p&gt;I use &lt;a href=&quot;https://www.visualstudio.com/products/visual-studio-team-services-vs&quot;&gt;VS Team Services&lt;/a&gt; 
for some of my repositories. I use the Git repository type, and most of the time 
everything works fine. Until today I reorganized some of my &lt;a href=&quot;https://golang.org/&quot;&gt;Go&lt;/a&gt; 
code to be more idiomatic, meaning that I leverage the native Go package system as it 
is designed: the only way to reference packages is by their full repository URL:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;using&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myorg.visualstudio.com/DefaultCollection/_git/MyRepo&quot;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and you can also load packages with Go get command, like:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;go get myorg.visualstudio.com/DefaultCollection/_git/MyRepo
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I can (barely) live with the fact that VS Team Services adds the unnecessarily ugly 
“DefaultCollection” and “_git” in to the URL. But the real problem is that the above 
doesn’t work with go cmd, you just get very misguiding message:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;package myorg.visualstudio.com/DefaultCollection/_git/MyRepo: 
unrecognized import path “myorg.visualstudio.com/DefaultCollection/_git/MyRepo”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Adding the verbose flag (-v) to the command gives one extra tidbit of information:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Parsing meta tags from https://myorg.visualstudio.com/DefaultCollection/_git/MyRepo?go-get=1 (status code 203)
import “myorg.visualstudio.com/DefaultCollection/_git/MyRepo”: 
parsing myorg.visualstudio.com/DefaultCollection/_git/MyRepo: 
http: read on closed response body&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My first guess was an authentication issue, and making a curl request for the address 
supported my guess as it was an authentication redirect. But Go uses Git internally, 
and git clone worked. I couldn’t find this issue anywhere related to VS Team Services 
(maybe gophers don’t use it?), but I found a same issue for Gitlab. It turned out, that 
neither Gitlab or VS Team Services adds automatically the .git ending to the URL, and 
therefore go get command never reaches the actual repository. This is fixed in Gitlab 
since, but issue remains in VS Team Services. The fix is to make the URL even uglier:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;using&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myorg.visualstudio.com/DefaultCollection/_git/MyRepo.git&quot;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and the corresponding go get command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;go get myorg.visualstudio.com/DefaultCollection/_git/MyRepo.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I hope this helps someone else to fix the problem quicker.&lt;/p&gt;</content><category term="go" /><summary>I use VS Team Services 
for some of my repositories. I use the Git repository type, and most of the time 
everything works fine. Until today I reorganized some of my Go 
code to be more idiomatic, meaning that I leverage the native Go package system as it 
is designed: the only way to reference packages is by their full repository URL:</summary></entry><entry><title>Azure Blob Storage CORS headers and ScriptCS</title><link href="http://teelahti.fi/blob-storage-cors-headers-and-scriptcs/" rel="alternate" type="text/html" title="Azure Blob Storage CORS headers and ScriptCS" /><published>2015-05-29T00:00:00+03:00</published><updated>2015-05-29T00:00:00+03:00</updated><id>http://teelahti.fi/blob-storage-cors-headers-and-scriptcs</id><content type="html" xml:base="http://teelahti.fi/blob-storage-cors-headers-and-scriptcs/">&lt;p&gt;One of &lt;a href=&quot;http://www.basware.com&quot;&gt;Basware’s&lt;/a&gt; products I work for uses CDN to deliver content for end users. 
CDN provider is Edgecast, and primary &amp;amp; secondary origins are Azure Blob storage accounts. So far we 
have not needed any cross domain access to the CDN, but now a new feature required Javascript requests 
from our application domain to the CDN domain… and browsers naturally block this nowadays.&lt;/p&gt;

&lt;p&gt;I knew right away that I need to set the &lt;a href=&quot;http://en.wikipedia.org/wiki/Cross-origin_resource_sharing&quot;&gt;Cross Origin Resource Sharing (CORS)&lt;/a&gt;
headers to our origin servers, but setting this up was harder than it is supposed to be: Azure’s Powershell
SDK does not have support to alter this value, and there is no UI to set it in the management portal. There 
is of course the &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/azure/ee460799.aspx&quot;&gt;management REST API&lt;/a&gt; you can 
use to do anything, but calling it with curl is hard due to the authentication scheme. Setting the 
&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/azure/dd894041.aspx&quot;&gt;DefaultServiceVersion property&lt;/a&gt; proved to be 
as complex before, so I knew what to expect.&lt;/p&gt;

&lt;p&gt;I checked Github and there were &lt;a href=&quot;https://github.com/search?q=azure+cors&quot;&gt;a couple of projects that matched my problem&lt;/a&gt;. 
Still I found none of them immediately useful; this kind of tool that you use only once should have a very 
low barrier of entry: git clone and run. So I decided to try to create one myself. With some help from 
blog posts like &lt;a href=&quot;http://blog.codingoutloud.com/2014/02/21/stupid-azure-trick-6-a-cors-toggler-command-line-tool-for-windows-azure-blobs/&quot;&gt;Bill Wilders post on the subject&lt;/a&gt;
I was able to create a working version in an hour. My tech stack for this is 
&lt;a href=&quot;http://scriptcs.net/&quot;&gt;ScriptCS&lt;/a&gt;, as it supports Nuget references out of the box. I referenced the 
&lt;a href=&quot;http://www.nuget.org/packages/WindowsAzure.Storage/&quot;&gt;WindowsAzure.Storage package&lt;/a&gt; that had the methods I needed.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/teelahti/AzureCorsSetter&quot;&gt;The end result is a tool&lt;/a&gt; that (given you have ScriptCS installed) 
you can just clone and run - ScriptCS takes care of the package restoration automatically. Tool supports dumping current 
values to console, adding CORS rules, and clearing rules. And the syntax is easy enough for anyone to use:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-bat&quot;&gt;scriptcs addCors.csx -- [storageAccount] [storageAccountKey] [origins]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ScriptCS runs also on &lt;a href=&quot;http://www.mono-project.com/&quot;&gt;Mono&lt;/a&gt;, so you could even say this is cross platform. 
Not as good as Node or Go based solution would have been, but still good enough.&lt;/p&gt;

&lt;p&gt;Naming is the hardest part… this tool turned out to be just &lt;a href=&quot;https://github.com/teelahti/AzureCorsSetter&quot;&gt;“AzureCorsSetter”&lt;/a&gt;.&lt;/p&gt;</content><category term="azure" /><category term="web" /><category term="scriptcs" /><summary>One of Basware’s products I work for uses CDN to deliver content for end users. 
CDN provider is Edgecast, and primary &amp;amp; secondary origins are Azure Blob storage accounts. So far we 
have not needed any cross domain access to the CDN, but now a new feature required Javascript requests 
from our application domain to the CDN domain… and browsers naturally block this nowadays.</summary></entry><entry><title>ASP.NET vNext presentation at Microsoft devdays 2014</title><link href="http://teelahti.fi/aspnet-vnext-presentation/" rel="alternate" type="text/html" title="ASP.NET vNext presentation at Microsoft devdays 2014" /><published>2014-12-02T00:00:00+02:00</published><updated>2014-12-02T00:00:00+02:00</updated><id>http://teelahti.fi/aspnet-vnext-presentation</id><content type="html" xml:base="http://teelahti.fi/aspnet-vnext-presentation/">&lt;p&gt;At the beginning of October Microsoft Finland held the yearly developer conference, this time with name &lt;a href=&quot;http://www.namesday.fi/&quot;&gt;Devdays&lt;/a&gt;. This year’s conference felt slightly smaller than previously.&lt;/p&gt;

&lt;p&gt;As there is is lots of churn around the ASP.NET right now and I have a history with that framework, I proposed a presentation about &lt;a href=&quot;http://www.asp.net/vnext&quot;&gt;ASP.NET vNext&lt;/a&gt;. Gladly it got accepted, and I had to dig deeper into what’s coming from the ASP.NET team. I played with the framework, watched every video and and read every blogpost about it from &lt;a href=&quot;http://www.hanselman.com/&quot;&gt;Scott Hanselman&lt;/a&gt;, &lt;a href=&quot;http://davidfowl.com/&quot;&gt;David Fowler&lt;/a&gt; and others. I also prepared some demos, even a Linux demo which I had to scrap on last minute because I had only 45 minutes time to present. I tried to give the audience some guidelines how they can prepare to what’s coming, in order for the upgrade from current ASP.NET to be as easy as possible. It was nice to prepare and present, I hope it helped someone.&lt;/p&gt;

&lt;p&gt;P.s. I waited for Microsoft to release the video recordings before posting this, but still after two months there is only a couple of videos available, and they are on &lt;a href=&quot;https://www.youtube.com/user/VideonetChannel/videos&quot;&gt;strangely named Youtube channel&lt;/a&gt;, different from previous years. I do not know what happened as I have not seen any communication from MS about the recordings, and I have yet received no answer to my question. So I have to say this aspect of the conference was poorly executed this year. Also, there was no common feedback collection, which means that presenters did not get any proper feedback. For me it is important to see the video and get some feedback to be able to do better next year.&lt;/p&gt;</content><category term="aspnet" /><category term="presentation" /><summary>At the beginning of October Microsoft Finland held the yearly developer conference, this time with name Devdays. This year’s conference felt slightly smaller than previously.</summary></entry><entry><title>How-to deploy to Azure website deployment slot from TFS</title><link href="http://teelahti.fi/howto-deploy-to-azure-websites-deployment-slot-from-tfs/" rel="alternate" type="text/html" title="How-to deploy to Azure website deployment slot from TFS" /><published>2014-10-24T00:00:00+03:00</published><updated>2014-10-24T00:00:00+03:00</updated><id>http://teelahti.fi/howto-deploy-to-azure-websites-deployment-slot-from-tfs</id><content type="html" xml:base="http://teelahti.fi/howto-deploy-to-azure-websites-deployment-slot-from-tfs/">&lt;p&gt;I changed some of my websites deployment to use different &lt;a href=&quot;http://azure.microsoft.com/en-us/documentation/articles/web-sites-staged-publishing/&quot;&gt;deployment slots on a single Azure web site&lt;/a&gt; instead of having different web sites for different staging areas. I deploy all my staging areas automatically from TFS (using the GitContinuousDeploymentTemplate.12.xaml process), each area from different Git branch. Works for my setup.&lt;/p&gt;

&lt;p&gt;What did not work was deploying to other slots than the main slot. On &lt;a href=&quot;https://portal.azure.com&quot;&gt;Azure portal&lt;/a&gt; different slots have name and address scheme like &lt;strong&gt;mywebsite-slotname&lt;/strong&gt;. I tried to use this name as deployment target:&lt;/p&gt;

&lt;figure&gt;
	&lt;img src=&quot;/images/2014-10-24-failing-configuration.png&quot; alt=&quot;Failing configuration.&quot; /&gt;
    &lt;figcaption&gt;Failing configuration.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;…and got failed build with error like:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;An attempted http request against URI https://management.core.windows.net/long-guid-string-here-53e1f2/services/webspaces/WestEuropewebspace/sites/mywebsite-slotname/publishxml returned an error: (404) Not Found.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So clearly &lt;strong&gt;mywebsite-slotname&lt;/strong&gt; is not the correct scheme. And there is no documentation available, thus this blog post.&lt;/p&gt;

&lt;p&gt;I went on and downloaded publishing profile for the site slot. It had double underscore naming &lt;strong&gt;mywebsite__slotname&lt;/strong&gt;, but that did not work either. Nor did single underscore. What finally worked, was the name the &lt;a href=&quot;https://manage.windowsazure.com&quot;&gt;old Azure portal&lt;/a&gt; used: &lt;strong&gt;mywebsite(slotname)&lt;/strong&gt;. This is how my build process deployment target looks now, and deployment to the slot works.&lt;/p&gt;

&lt;figure&gt;
	&lt;img src=&quot;/images/2014-10-24-working-configuration.png&quot; alt=&quot;Working configuration.&quot; /&gt;
    &lt;figcaption&gt;Working configuration.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I hope this gets better documented. Luckily one can &lt;a href=&quot;https://github.com/Azure/azure-content/blob/master/CONTRIBUTING.md&quot;&gt;create pull request for Azure documentation&lt;/a&gt; nowadays; I might document this myself.&lt;/p&gt;</content><category term="azure" /><category term="deployment" /><summary>I changed some of my websites deployment to use different deployment slots on a single Azure web site instead of having different web sites for different staging areas. I deploy all my staging areas automatically from TFS (using the GitContinuousDeploymentTemplate.12.xaml process), each area from different Git branch. Works for my setup.</summary></entry><entry><title>How to change your Outlook default calendar</title><link href="http://teelahti.fi/how-to-change-your-outlook-default-calendar/" rel="alternate" type="text/html" title="How to change your Outlook default calendar" /><published>2014-08-06T00:00:00+03:00</published><updated>2014-08-06T00:00:00+03:00</updated><id>http://teelahti.fi/how-to-change-your-outlook-default-calendar</id><content type="html" xml:base="http://teelahti.fi/how-to-change-your-outlook-default-calendar/">&lt;p&gt;Since Office 2013 was launched, I’ve had some problems with Outlook and account settings: I can set up all the accounts, but Outlook refuses to display my default Exchange calendar on the todo-pane, and instead shows an empty calendar from one of the other accounts that I use for email only. I like the todo-pane as its easy to glance whats coming with it. I’ve searched for resolution a couple of times, and most Microsoft community answers suggest to change the default data file on via Outlook &amp;gt; Account Settings:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2014-08-06-outlook-default-data-file.PNG&quot; alt=&quot;Outlook default data file settings&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately changing that setting back and forth does not affect what’s shown on the todo-pane; I already had my Exchange account as default. Next suggestion I found was to change the same setting via Windows Control Panel’s mail section:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2014-08-06-control-panel-mail-settings.PNG&quot; alt=&quot;Control panel mail settings&quot; /&gt;&lt;/p&gt;

&lt;p&gt;…but that was exactly the same setup than the previous one done via Outlook, nothing changed. Out of curiosity I decided to check what’s under the mail profiles section.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2014-08-06-control-panel-mail-profiles.PNG&quot; alt=&quot;Control panel mail profiles&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And from there I hit properties, and under properties you can find yet another data file selection dialog. Changing this data file under the profile finally changed my Outlook’s default calendar. Shouldn’t be this hard.&lt;/p&gt;

&lt;figure class=&quot;half&quot;&gt;
	&lt;img src=&quot;/images/2014-08-06-control-panel-mail-profiles-setup.PNG&quot; alt=&quot;Control panel mail setup for a profile&quot; /&gt;
	&lt;img src=&quot;/images/2014-08-06-control-panel-mail-profiles-default-data-file.PNG&quot; alt=&quot;Default data file for a profile&quot; /&gt;
	&lt;figcaption&gt;Yet another place to set the default Outlook data file.&lt;/figcaption&gt;
&lt;/figure&gt;</content><category term="tools" /><summary>Since Office 2013 was launched, I’ve had some problems with Outlook and account settings: I can set up all the accounts, but Outlook refuses to display my default Exchange calendar on the todo-pane, and instead shows an empty calendar from one of the other accounts that I use for email only. I like the todo-pane as its easy to glance whats coming with it. I’ve searched for resolution a couple of times, and most Microsoft community answers suggest to change the default data file on via Outlook &amp;gt; Account Settings:</summary></entry><entry><title>What has pharmacy to do with programming?</title><link href="http://teelahti.fi/what-has-pharmacy-to-do-with-programming/" rel="alternate" type="text/html" title="What has pharmacy to do with programming?" /><published>2014-06-03T00:00:00+03:00</published><updated>2014-06-03T00:00:00+03:00</updated><id>http://teelahti.fi/what-has-pharmacy-to-do-with-programming</id><content type="html" xml:base="http://teelahti.fi/what-has-pharmacy-to-do-with-programming/">&lt;p&gt;I visited my local pharmacy last Friday to get some prescription drug. I sat in front of the pharmacist, who gave me very thorough guidance about the usage. At the time of payment - before she handed me the boxes - she suddenly said:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Excuse me, but I need to get a signature from someone else, as I am a trainee.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Immediately another pharmacist came by, put her smart card into the computer, checked the boxes against the electronic prescription, and then signed the delivery. The whole process took maybe 20 seconds, and I’m certain trainee felt safer as her work is checked against mistakes. And myself - as a client - I felt like they care.&lt;/p&gt;

&lt;p&gt;With the risk of sounding like &lt;a href=&quot;http://blog.8thlight.com/uncle-bob/2013/11/19/HoardsOfNovices.html&quot;&gt;Uncle Bob&lt;/a&gt;: this episode reminded me about how one should act if you really care about quality. This model of signing other people’s work is built into some software development processes, like &lt;a href=&quot;https://guides.github.com/introduction/flow/index.html&quot;&gt;the Github flow&lt;/a&gt;. If you are not using pull requests, you can still simulate this kind of apprenticeship model with strict use of code reviews before merging into your trunk. Remember, that this must not be for all your codebase; you can be very strict on important, core modules, and let others evolve freely.&lt;/p&gt;</content><category term="profession" /><summary>I visited my local pharmacy last Friday to get some prescription drug. I sat in front of the pharmacist, who gave me very thorough guidance about the usage. At the time of payment - before she handed me the boxes - she suddenly said:


  Excuse me, but I need to get a signature from someone else, as I am a trainee.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://teelahti.fi{&quot;feature&quot;=&gt;&quot;pharmacy.jpg&quot;, &quot;credit&quot;=&gt;&quot;Apothecary Now by Simon Harrod&quot;, &quot;creditlink&quot;=&gt;&quot;https://www.flickr.com/photos/sidibousaid/7064590663&quot;}" /></entry><entry><title>The promise of OWIN starts to materialize</title><link href="http://teelahti.fi/the-promise-of-owin-starts-to-materialize/" rel="alternate" type="text/html" title="The promise of OWIN starts to materialize" /><published>2014-05-09T00:00:00+03:00</published><updated>2014-05-09T00:00:00+03:00</updated><id>http://teelahti.fi/the-promise-of-owin-starts-to-materialize</id><content type="html" xml:base="http://teelahti.fi/the-promise-of-owin-starts-to-materialize/">&lt;p&gt;&lt;a href=&quot;http://owin.org/&quot;&gt;OWIN&lt;/a&gt; stands for the “Open web interface for .NET”. Basically it is a reasonably simple specification that defines how data goes through the request pipeline, and how to attach to that pipeline. It is a specification for both the server and the application (middleware on OWIN’s terms) part.&lt;/p&gt;

&lt;p&gt;When I first saw the project I was not that convinced, but since then lots of applications that rely on OWIN and not the old System.Web stack has emerged, and also there are some hosting components that implement the spec. &lt;a href=&quot;http://signalr.net/&quot;&gt;SignalR&lt;/a&gt; is a good example of middleware, and &lt;a href=&quot;http://katanaproject.codeplex.com/documentation&quot;&gt;Katana&lt;/a&gt; a host. For me the new &lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2014/02/18/introducing-asp-net-project-helios.aspx&quot;&gt;project Helios&lt;/a&gt; is also very interesting and I hope the project succeeds, as that would make hosting ASP.NET WebApi very lightweight. And light is never bad.&lt;/p&gt;

&lt;p&gt;So the ecosystem has matured, then what? What really made me to support OWIN is what it did to my codebase. In one of my pet projects I use claims based authentication and authorization with Windows Azure Access Control Services; That is a great project (although being replaced with Azure AD), but on the .NET MVC application side it has been a pain to integrate. The amount of web.config carbage it needs is huge, and I have broken it multiple times. Luckily &lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2014/02/21/using-claims-in-your-web-app-is-easier-with-the-new-owin-security-components.aspx&quot;&gt;Microsoft released some OWIN-based implementation&lt;/a&gt; of the server side components, and promised drastically simplified configuration model. You just register th middleware to OWIN, specify where to find the metadata, and give the application identifier:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureAuth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IAppBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseCookieAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CookieAuthenticationOptions&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;AuthenticationType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
               &lt;span class=&quot;n&quot;&gt;WsFederationAuthenticationDefaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AuthenticationType&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseWsFederationAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WsFederationAuthenticationOptions&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;MetadataAddress&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://login.windows.net/some-azure-ad.onmicrosoft.com/federationmetadata/2007-06/federationmetadata.xml&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Wtrealm&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://myapps/somerealm&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For me simplified configuration was not the only benefit: OWIN registration also gave me an option to register &lt;em&gt;everything authentication related&lt;/em&gt; at the same place, which makes the code very readable. Before OWIN I had :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Various XML configurations for WS Federation registration&lt;/li&gt;
  &lt;li&gt;Custom ClaimsAuthenticationManager to do in-the-app claims transformation (look for database for some extra information and include that in claims)&lt;/li&gt;
  &lt;li&gt;Account controller to handle sign in and sign out actions&lt;/li&gt;
  &lt;li&gt;Handler to add user’s roles to all outgoing request for better usability (hide client side elements on single page application based on user’s role)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now I have instead something along these lines:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureAuth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IAppBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetDefaultSignInAsAuthenticationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WsFederationAuthenticationDefaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AuthenticationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseCookieAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
		 &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CookieAuthenticationOptions&lt;/span&gt;
		 &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			 &lt;span class=&quot;n&quot;&gt;AuthenticationType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WsFederationAuthenticationDefaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AuthenticationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

			 &lt;span class=&quot;c1&quot;&gt;// Make claims transformation to avoid using an external
&lt;/span&gt;			 &lt;span class=&quot;c1&quot;&gt;// STS to map certain users to certain role claims
&lt;/span&gt;			 &lt;span class=&quot;n&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CookieAuthenticationProvider&lt;/span&gt;
			 &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				 &lt;span class=&quot;n&quot;&gt;OnResponseSignIn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
				 &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
					 &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Identity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TransformClaims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Identity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
				 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
			 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		 &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseWsFederationAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WsFederationAuthenticationOptions&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;MetadataAddress&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigurationManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AppSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;medatata&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;Wtrealm&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigurationManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AppSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;realm&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Map sign in action
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/signin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Authentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt;
				&lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Authentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Identity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsAuthenticated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StatusCode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;401&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Redirect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Map signout action
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/signout&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Authentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SignOut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Redirect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ClaimsIdentity&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TransformClaims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ClaimsIdentity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;identity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// ... add what ever claims needed based on your own data source
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;identity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Kudos for &lt;a href=&quot;http://leastprivilege.com/&quot;&gt;Dominick Baier&lt;/a&gt; for his &lt;a href=&quot;http://leastprivilege.com/2014/02/21/test-driving-the-ws-federation-authentication-middleware-for-katana/&quot;&gt;clear post on this subject&lt;/a&gt; that helped me forward with sign in and out actions.&lt;/p&gt;

&lt;h2 id=&quot;webapi--owin&quot;&gt;WebApi + OWIN&lt;/h2&gt;

&lt;p&gt;At the same time I also moved Web API to OWIN based hosting, even though I actually run on IIS. Reasoning was the same than with claims auth: I find the configuration model better.&lt;/p&gt;

&lt;p&gt;If you’re an ASP.NET developer, I suggest you start experimenting with the OWIN pipeline. It will pay out.&lt;/p&gt;</content><category term="web" /><category term="IIS" /><category term=".NET" /><category term="authentication" /><summary>OWIN stands for the “Open web interface for .NET”. Basically it is a reasonably simple specification that defines how data goes through the request pipeline, and how to attach to that pipeline. It is a specification for both the server and the application (middleware on OWIN’s terms) part.</summary></entry><entry><title>Yet another take on Internet Explorer compatibility mode</title><link href="http://teelahti.fi/yet-another-take-on-internet-explorer-compatibility-mode/" rel="alternate" type="text/html" title="Yet another take on Internet Explorer compatibility mode" /><published>2014-02-04T00:00:00+02:00</published><updated>2014-02-04T00:00:00+02:00</updated><id>http://teelahti.fi/yet-another-take-on-internet-explorer-compatibility-mode</id><content type="html" xml:base="http://teelahti.fi/yet-another-take-on-internet-explorer-compatibility-mode/">&lt;p&gt;I have touched this subject already twice: first I &lt;a href=&quot;/blog/disable-internet-explorer-compatibility-view-via-web-config&quot;&gt;I blogged about forcing site rendering to be done with Internet Explorer’s latest engine&lt;/a&gt;. Then &lt;a href=&quot;/blog/problems-with-internet-explorer-compatibility-view/&quot;&gt;I faced a situation where separate intranet zone (bad idea, Microsoft!) fallbacks to compatibility mode&lt;/a&gt; and does not respect the IE=edge meta tag as internet zone web sites do.&lt;/p&gt;

&lt;p&gt;Well… the saga isn’t over, as I faced this situation at work today. Again. I was going to put the IE=11 meta tag in place to force normal mode, but then I started to doubt how older IE’s (9, 10) would interpret the “11” tag. Short answer is: they don’t. &lt;a href=&quot;http://twigstechtips.blogspot.fi/2010/03/css-ie8-meta-tag-to-disable.html&quot;&gt;Luckily you can specify many different modes&lt;/a&gt;, and the browser will pick the first one it supports. To apply this use either a meta tag in your page:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;http-equiv=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;IE=11; IE=10; IE=9; IE=8; IE=7; IE=edge&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Or apply this IIS configuration to add the correct headers:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;system.webserver&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;httpProtocol&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;customHeaders&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- No need to expose the platform --&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;remove&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-Powered-By&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Do not show IE compatibility view --&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;remove&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;add&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;IE=11; IE=10; IE=9; IE=8; IE=7; IE=edge&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/customHeaders&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/httpProtocol&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/system.webserver&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Not nice, but works.&lt;/p&gt;</content><category term="IIS" /><category term="web" /><category term="browsers" /><summary>I have touched this subject already twice: first I I blogged about forcing site rendering to be done with Internet Explorer’s latest engine. Then I faced a situation where separate intranet zone (bad idea, Microsoft!) fallbacks to compatibility mode and does not respect the IE=edge meta tag as internet zone web sites do.</summary></entry></feed>
