Jekyll2019-08-03T14:09:02+00:00https://ion-sapoval.github.io/feed.xmlThoughts Compiler"If you can't explain it simply, you don't understand it well enough." - Albert Einstein
Released version 2.1.0 of Google Measurement Protocol library2019-08-03T00:00:00+00:002019-08-03T00:00:00+00:00https://ion-sapoval.github.io/.net/c%23/google-measurement-protocol/2019/08/03/google-measurement-protocol-dotnet-2-1-0<h1 id="released-version-210-of-google-measurement-protocol-library">Released version 2.1.0 of Google Measurement Protocol library</h1>
<ul>
<li>Added possibility to inject HttpClient</li>
<li>Async actions are no longer dependent on captured context.</li>
</ul>
<p><strong><a href="https://github.com/ion-sapoval/google-measurement-protocol-dotnet">google-measurement-protocol-dotnet 2.1.0</a></strong></p>
<script>
var disqus_config = function () {
this.page.url = google-measurement-protocol-dotnet-2-1-0; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = google-measurement-protocol-dotnet-2-1-0; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>Released version 2.1.0 of Google Measurement Protocol libraryReleased version 2.0.0 of Google Measurement Protocol library2018-12-14T00:00:00+00:002018-12-14T00:00:00+00:00https://ion-sapoval.github.io/.net/c%23/google-measurement-protocol/2018/12/14/google-measurement-protocol-dotnet-2-0-0<h1 id="released-version-200-of-google-measurement-protocol-library">Released version 2.0.0 of Google Measurement Protocol library</h1>
<ul>
<li>Added support for batch requests</li>
<li>Added support for decimal values for Custom Metrics</li>
<li>Removed non async methods</li>
<li>Performance improvements and bug fixes</li>
</ul>
<p><strong><a href="https://github.com/ion-sapoval/google-measurement-protocol-dotnet">google-measurement-protocol-dotnet 2.0.0</a></strong></p>
<script>
var disqus_config = function () {
this.page.url = google-measurement-protocol-dotnet-2-0-0; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = google-measurement-protocol-dotnet-2-0-0; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>Released version 2.0.0 of Google Measurement Protocol libraryReleased version 1.4.3 of Google Measurement Protocol library2017-10-28T00:00:00+00:002017-10-28T00:00:00+00:00https://ion-sapoval.github.io/.net/c%23/google-measurement-protocol/2017/10/28/google-measurement-protocol-dotnet-1-4-3<h1 id="released-version-143-of-google-measurement-protocol-library">Released version 1.4.3 of Google Measurement Protocol library</h1>
<ul>
<li>Signed assembly with a Strong Name.</li>
<li>Converted to a .Net Standard library.</li>
</ul>
<p><strong><a href="https://github.com/ion-sapoval/google-measurement-protocol-dotnet">google-measurement-protocol-dotnet 1.4.3</a></strong></p>
<script>
var disqus_config = function () {
this.page.url = google-measurement-protocol-dotnet-1-4-3; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = google-measurement-protocol-dotnet-1-4-3; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>Released version 1.4.3 of Google Measurement Protocol libraryReleased version 1.4.2 of Google Measurement Protocol library2017-10-11T00:00:00+00:002017-10-11T00:00:00+00:00https://ion-sapoval.github.io/.net/c%23/google-measurement-protocol/2017/10/11/google-measurement-protocol-dotnet-1-4-2<h1 id="released-version-142-of-google-measurement-protocol-library">Released version 1.4.2 of Google Measurement Protocol library</h1>
<ul>
<li>Fixed type inconsistencies between ValueType property and type of “value” param from constructor.</li>
<li>Added extra unit tests</li>
</ul>
<p><strong><a href="https://github.com/ion-sapoval/google-measurement-protocol-dotnet">google-measurement-protocol-dotnet 1.4.2</a></strong></p>
<script>
var disqus_config = function () {
this.page.url = google-measurement-protocol-dotnet-1-4-2; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = google-measurement-protocol-dotnet-1-4-2; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>Released version 1.4.2 of Google Measurement Protocol libraryBlog resurrection2017-09-04T00:00:00+00:002017-09-04T00:00:00+00:00https://ion-sapoval.github.io/blog/resurrection/2017/09/04/blog-resurrection<h1 id="blog-resurrection">Blog resurrection</h1>
<p>The time has come! My blog had to be migrated to another platform, due multiple reasons (hosting, obsolete platform, ease of use etc.).<br />
After a hour of browsing through Internet to see what will be the options, the decision had been made: I will use as a new platform <a href="https://pages.github.com">GitHub Pages</a> + <a href="https://jekyllrb.com">Jekyll</a>.<br />
These are the facts that have determined me to make this decision:</p>
<ul>
<li>GitHub Pages provide a seamless integration on the repo level</li>
<li>Jekyll is a very versatile static site generator with an included support for blogging (no DB dependencies, support for templates and much more)</li>
<li>Out of the box integration between GitHub Pages and Jekyll</li>
</ul>
<p>Basically publishing a post will involve:</p>
<ol>
<li>Create a markup file</li>
<li>Push it in the corresponding git repository</li>
</ol>
<p>That’s it! And this is the exact flow I was looking for.<br />
But as we all know there should be a catch, and here it is: Jekyll requires Ruby and other gem dependencies which require a Linux machine for being able to run without any problems a preview version of the blog on the local machine. Being a .Net developer it’s kinda equivalent with a PC fan and owner which will result in <img src="https://ion-sapoval.github.io/assets/img/linuxVSwindows.png" alt="linux vs windows" title="Linux VS Windows" /><br />
Fortunately Microsoft implemented Linux Subsystem on Windows which works like a charm. I didn’t have any problems with installing all the prerequisites and running development server for Jekyll.</p>
<p>So now I have no excuse for not to blog!</p>
<script>
var disqus_config = function () {
this.page.url = blog-resurrection; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = blog-resurrection; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>Blog resurrectionReleased version 1.4.0 of Google Measurement Protocol library2017-08-18T00:00:00+00:002017-08-18T00:00:00+00:00https://ion-sapoval.github.io/.net/c%23/google-measurement-protocol/2017/08/18/google-measurement-protocol-dotnet-1-4-0<h1 id="released-version-140-of-google-measurement-protocol-library">Released version 1.4.0 of Google Measurement Protocol library</h1>
<ul>
<li>Added support for Validating Hits - Measurement Protocol.</li>
<li>Added missing parameters.</li>
<li>Added possibility to create a request based on UserId instead of ClientId.</li>
<li>Fixes and improvements.</li>
</ul>
<p><strong><a href="https://github.com/ion-sapoval/google-measurement-protocol-dotnet">google-measurement-protocol-dotnet 1.4.0</a></strong></p>
<script>
var disqus_config = function () {
this.page.url = google-measurement-protocol-dotnet-1-4-0; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = google-measurement-protocol-dotnet-1-4-0; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>Released version 1.4.0 of Google Measurement Protocol libraryASP.NET CORE cross-platform adventures2016-03-02T00:00:00+00:002016-03-02T00:00:00+00:00https://ion-sapoval.github.io/asp.net/core/linux/cross-platform/2016/03/02/asp-net-core-cross-platform-adventures<h1 id="aspnet-core-cross-platform-adventures">ASP.NET CORE cross-platform adventures</h1>
<p>After I’ve finished developing a pet project with ASP.NET CORE and test it successfully on Windows, I’ve decided to host it on a Raspberry PI with Linux on it.</p>
<p>Having an ARM processor I was forced to use Mono, that means some extra installations, but in the end I’ve managed to install all prerequisites. After all configurations have been finished, with much hope and optimism I’ve tried to access my Linux hosted web site … and of course the result was a Mono exception regarding some cast errors in my database entities.
After some digging, I found that the problem is caused by datetime2 type of a table column from my database, apparently Mono can’t handle this type, so I changed column type to datetime and everything went smoothly, at least on server side.</p>
<p>I’m hitting refresh button and see how my main web page is loading, but fate decided it was too easy so, a lot of JavaScript errors popped out because the content of one JavaScript file could not be loaded, strange thing was that exactly the same thing was working perfectly on Windows. Basically the request for loading js file …/product.js on Linux wasn’t working and on Windows was. When trying to figure out what the problem was, I saw that corresponding file for product.js was Product.js (with capital P), but being used with Windows which is a case insensitive OS it didn’t ring a bell right away.</p>
<p>After an hour of investigation, I learned the hard way that Linux is case sensitive OS and Product.js != product.js != product.JS etc. After renaming the file to product.js, at last I had my first .net web site running on Linux.</p>
<script>
var disqus_config = function () {
this.page.url = asp-net-core-cross-platform-adventures; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = asp-net-core-cross-platform-adventures; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>ASP.NET CORE cross-platform adventuresWhat is the best starting point for becoming a programmer?2016-01-21T00:00:00+00:002016-01-21T00:00:00+00:00https://ion-sapoval.github.io/beginners/programming/2016/01/21/what-is-the-best-starting-point-for-becoming-a-programmer<h1 id="what-is-the-best-starting-point-for-becoming-a-programmer">What is the best starting point for becoming a programmer?</h1>
<p>In the last couple of month several of my friends, which don’t have programming background, decided to learn how to code for being able to work as a freelancers in their spare time and to make some extra money. In their situation what would you do? Call one of your programmer friends and ask him what should you learn.</p>
<p>Being in the position to give an advice regarding what technology stack should they choose, I took into consideration the following points:</p>
<ol>
<li>They want to practice programming as a hobby or at most as a project based/part time job</li>
<li>They don’t have any programming background (except some Pascal and C from high school and college)</li>
<li>They need free and easy access to learning materials</li>
<li>They need free developing tools</li>
<li>For making things easier for them, it will be perfect if the chosen technology would not have to many dependencies on other technologies/frameworks for being able to create a complete application by themselves</li>
<li>One very important aspect is the existence of the demand for projects developed with this technology
What did I recommend based on the points from above? After some thinking I decided to recommend learning Android programming. I’ll try to explain myself and how I got to make this decision.</li>
</ol>
<p>First thing I have done was to limit possibilities to web and mobile programming(native), because, I think you’ll agree with me, the biggest percent of the projects available for freelancers are from these 2 categories. If I would go with web then most probably I would have recommended PHP. I know, it is very odd to hear this from a .Net developer, but lets face it, that learning curve for PHP is one of the easiest and it has free developing tools, you can develop on different platforms, meanwhile it has evolve very much and most important the biggest share of the web projects on the market that can be accessed by a freelancer is for PHP. But regarding web development we have a problem with point 5, because for being a complete web developer you need at least to know: backend language(in our case is PHP), HTML, JavaScript, CSS, HTTP principles, some JavaScript frameworks, a database engine, minimum web server management. Believe me if you give to a beginner this list he will be overwhelmed and most probably he will give up before event started.</p>
<p>After I excluded web development the only viable option remained mobile development. From mobile platforms I chose Android because it has the biggest share of the market, free tools and support development on different platforms. For learning Android a beginner need some Java basics and Android framework and only with this 2 he can build a mobile application, at least for the beginning.</p>
<p>I hope that my reasoning was a good one, but if you don’t think so please let me know and maybe it would not be to late for changing my recommendation made to my friends.</p>
<script>
var disqus_config = function () {
this.page.url = what-is-the-best-starting-point-for-becoming-a-programmer; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = what-is-the-best-starting-point-for-becoming-a-programmer; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>What is the best starting point for becoming a programmer?FlightJS - first contact2014-11-23T00:00:00+00:002014-11-23T00:00:00+00:00https://ion-sapoval.github.io/javascript/framework/twitter/2014/11/23/twitter-flightjs<h1 id="flightjs---first-contact">FlightJS - first contact</h1>
<p><img src="https://ion-sapoval.github.io/assets/img/Flight.png" alt="FlightJS" title="Flight" /></p>
<p>Twitter developers made available to community another interesting JavaScript framework which has a great potential: “FlightJS”. This is Twitter’s team description of the product: “<em>Flight is a lightweight, component-based JavaScript framework that maps behavior to DOM nodes</em>”.
I decided to take a closer look to this framework because of:</p>
<ol>
<li>Curiosity</li>
<li>It’s based on different philosophy (a cleaner one) than AngularJS, Knockout or other popular MV* frameworks, to be clear, FlightJS isn’t a MV* framework.</li>
<li>Let face it, till now Twitter’s developers released only good stuff to the “market”.</li>
</ol>
<p>I took a look to the FlightJS documentation but it wasn’t too useful to me, I couldn’t get how it works and how it should be used, but after digging into their mail client demo app, things became more clearer for me and till now I can say the following:</p>
<ol>
<li>It doesn’t pollute your html markup from views, there’re no custom attributes and so on.</li>
<li>Twitter devs didn’t try to reinvent the wheel, instead they used JQuery as component used by the framework and for dependency control recommends RequireJS</li>
<li>It doesn’t enforce a certain way of structuring your app, this is kind a good but sometimes it can lead to negative results</li>
<li>Separation of concerns is one of the main pillars of the FlightJS, every component you create or use, can communicate with other components only through events which offers the best decoupling mechanism from the architecture point of view</li>
<li>Components contexts are bind to DOM elements which basically permits to control component’s events visibility and accessibility</li>
<li>With this framework everything seems so clean and well organized and which is more important everything is easy to test</li>
<li>There’re 2 things that worry me:
<ul>
<li>It is relatively hard to discover connections between views and JavaScript components. For example if you’ll have to fix a bug related to the information from a textbox it will not be trivial to find what components are involved in populating/updating it.</li>
<li>For large applications I think the big number of custom events can be a problem, especially in development process.</li>
</ul>
</li>
</ol>
<p>Next step for me, will be usage of this framework in some small applications and to see it in action, but sincerely, I’m very optimistic about the results.</p>
<script>
var disqus_config = function () {
this.page.url = twitter-flightjs; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = twitter-flightjs; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>FlightJS - first contactAdd custom SOAP headers to your service requests2014-07-29T00:00:00+00:002014-07-29T00:00:00+00:00https://ion-sapoval.github.io/.net/c%23/soap/headers/2014/07/29/create-custom-soap-header<h1 id="add-custom-soap-headers-to-your-service-requests">Add custom SOAP headers to your service requests</h1>
<p>In .Net adding a service reference is a very simple and intuitive process, but when it comes to adding custom SOAP headers to your request made by using generated proxy, suddenly everything becomes obscure and tricky. Below I’ll give you an example of how to add this custom header:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt"><soapenv:Header</span> <span class="na">xmlns:soapenv=</span><span class="s">"http://schemas.xmlsoap.org/soap/envelope/"</span><span class="nt">></span>;
<span class="nt"><pfx:info</span> <span class="na">soapenv:actor=</span><span class="s">"http://schemas.xmlsoap.org/soap/actor/next"</span> <span class="na">soapenv:mustUnderstand=</span><span class="s">"0"</span> <span class="na">xmlns:pfx=</span><span class="s">"http://somedomain.com"</span><span class="nt">></span>
<span class="nt"><pfx:credentials></span>
<span class="nt"><pfx:username</span> <span class="na">xsi:type=</span><span class="s">"soapenc:string"</span> <span class="na">xmlns:soapenc=</span><span class="s">"http://schemas.xmlsoap.org/soap/encoding/"</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span><span class="nt">></span>USERNAME<span class="nt"></pfx:username></span>
<span class="nt"><pfx:password</span> <span class="na">xsi:type=</span><span class="s">"soapenc:string"</span> <span class="na">xmlns:soapenc=</span><span class="s">"http://schemas.xmlsoap.org/soap/encoding/"</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span><span class="nt">></span>PASSWORD<span class="nt"></pfx:password></span>
<span class="nt"></pfx:credentials></span>
<span class="nt"></pfx:info></span>
<span class="nt"></soapenv:Header></span></code></pre></figure>
<p>And I want the header to look exactly like in the sample, even with the same namespace prefixes. For this I will define a CustomHeader class which will be derived from MessageHeader base class.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="k">public</span> <span class="k">class</span> <span class="nc">CustomHeader</span> <span class="p">:</span> <span class="n">MessageHeader</span>
<span class="p">{</span>
<span class="k">private</span> <span class="k">readonly</span> <span class="kt">string</span> <span class="n">_user</span><span class="p">;</span>
<span class="k">private</span> <span class="k">readonly</span> <span class="kt">string</span> <span class="n">_password</span><span class="p">;</span>
<span class="k">public</span> <span class="nf">CustomHeader</span><span class="p">(</span><span class="kt">string</span> <span class="n">user</span><span class="p">,</span> <span class="kt">string</span> <span class="n">password</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">_user</span> <span class="p">=</span> <span class="n">user</span><span class="p">;</span>
<span class="n">_password</span> <span class="p">=</span> <span class="n">password</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">Name</span>
<span class="p">{</span>
<span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"info"</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">Namespace</span>
<span class="p">{</span>
<span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"http://somedomain.com"</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">override</span> <span class="kt">bool</span> <span class="n">MustUnderstand</span>
<span class="p">{</span>
<span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="k">false</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="c1">//override this method for being able to specify namespace prefix name</span>
<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnWriteStartHeader</span><span class="p">(</span><span class="n">XmlDictionaryWriter</span> <span class="n">writer</span><span class="p">,</span> <span class="n">MessageVersion</span> <span class="n">messageVersion</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">writer</span><span class="p">.</span><span class="nf">WriteStartElement</span><span class="p">(</span><span class="s">"pfx"</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="n">Name</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="n">Namespace</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nf">WriteHeaderAttributes</span><span class="p">(</span><span class="n">writer</span><span class="p">,</span> <span class="n">messageVersion</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">Actor</span>
<span class="p">{</span>
<span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"http://schemas.xmlsoap.org/soap/actor/next"</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="c1">//this method will be used for adding content to your header</span>
<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnWriteHeaderContents</span><span class="p">(</span><span class="n">XmlDictionaryWriter</span> <span class="n">writer</span><span class="p">,</span> <span class="n">MessageVersion</span> <span class="n">messageVersion</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">writer</span><span class="p">.</span><span class="nf">WriteRaw</span><span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="nf">Format</span><span class="p">(</span><span class="s">@"<soapenv:Header xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"">
<pfx:info soapenv:actor=""http://schemas.xmlsoap.org/soap/actor/next"" soapenv:mustUnderstand=""0"" xmlns:pfx=""http://somedomain.com"">
<pfx:credentials>
<pfx:username xsi:type=""soapenc:string"" xmlns:soapenc=""http://schemas.xmlsoap.org/soap/encoding/""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">{0}</pfx:username>
<pfx:password xsi:type=""soapenc:string"" xmlns:soapenc=""http://schemas.xmlsoap.org/soap/encoding/""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">{1}</pfx:password>
</pfx:credentials>
</pfx:info>
</soapenv:Header>
"</span><span class="p">,</span><span class="n">_user</span><span class="p">,</span><span class="n">_password</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Lets say that “client” is the name of our web service proxy instance, then we have to write the following code for adding our custom header:</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">operationContextScope</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">OperationContextScope</span><span class="p">(</span><span class="n">client</span><span class="p">.</span><span class="n">InnerChannel</span><span class="p">))</span>
<span class="p">{</span>
<span class="n">OperationContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">OutgoingMessageHeaders</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="k">new</span> <span class="nf">CustomHeader</span><span class="p">(</span><span class="s">"User name"</span><span class="p">,</span><span class="s">"Password"</span><span class="p">));</span>
<span class="c1">//to this call will be prepended custom header that we instantiated earlier</span>
<span class="n">client</span><span class="p">.</span><span class="nf">TestMethod</span><span class="p">();</span>
<span class="p">}</span></code></pre></figure>
<script>
var disqus_config = function () {
this.page.url = create-custom-soap-header; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = create-custom-soap-header; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
</script>Add custom SOAP headers to your service requests