<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>csharp — Attach to Process</title>
    <link>https://devblog.dinobansigan.com/tag:csharp</link>
    <description>Thoughts and Notes on Software Development</description>
    <pubDate>Fri, 13 Nov 2026 00:57:23 +0000</pubDate>
    <image>
      <url>https://i.snap.as/4wmUdb6N.png</url>
      <title>csharp — Attach to Process</title>
      <link>https://devblog.dinobansigan.com/tag:csharp</link>
    </image>
    <item>
      <title>DevLog – 005: The Write.as Archive Page Generator Is Back</title>
      <link>https://devblog.dinobansigan.com/devlog-005-the-write-as-archive-page-generator-is-back?pk_campaign=rss-feed</link>
      <description>In my last DevLog, I mentioned that I took down apps.dinobansigan.com, and with it, the Write.as Archive Page Generator. I said I was let...</description>
      <content:encoded><![CDATA[<p>In my <a href="https://devblog.dinobansigan.com/devlog-004">last DevLog</a>, I mentioned that I took down apps.dinobansigan.com, and with it, the Write.as Archive Page Generator. I said I was letting it go. Well, that lasted about two months.</p>

<p>So, I went to update one of my other blogs recently, and realized the archive page on it was way out of date. The tool I used to update it was gone. Turns out I still needed it after all.</p>

<h2 id="why-it-can-t-just-be-a-website">Why it can&#39;t just be a website</h2>

<p>The old version was a Blazor WASM app. Since it ran in the browser, it couldn&#39;t call the Write.as API directly because of CORS. My workaround was to write my own API for the Blazor app to call, running as an Azure App Service. That API ran on free Azure credits that I&#39;ve since lost access to.</p>

<p>I didn&#39;t want to host something again, since that means paying for it. And I didn&#39;t want to fight CORS again either. So this time around, the answer was an app that runs locally on my own machine. CORS only applies to browsers, so a regular app can call the Write.as API just fine.</p>

<h2 id="rebuilding-it-with-claude-code">Rebuilding it with Claude Code</h2>

<p>I rebuilt this one with Claude Code. I treated it like pairing with another developer. Claude wrote most of the code, and I reviewed every change before it went in. Good news was, I still had the source code for both the old Blazor app and the API on my machine, so we had something to work off of. We ended up with a simple .NET console app. You run it with your blog&#39;s alias, and it spits out the HTML for your archive page. Same output as before, same CSS classes, so if you customized the look of your archive page, it should still work.</p>

<p>It still uses my <a href="https://github.com/DinoBansigan/WriteAs.NET">WriteAs.NET</a> library to talk to the Write.as API. But we swapped out CommonMark.NET and HtmlAgilityPack for Markdig, which turns the Markdown of untitled posts into plain text in a single line of code. CommonMark.NET hasn&#39;t been updated in years, so it was time anyway. Going through my old code also turned up a few bugs, like the app crashing on short untitled posts. Oops.</p>

<p>From reading through the old code to having a working app up on GitHub, the whole thing took one afternoon.</p>

<h2 id="rate-limiting">Rate limiting</h2>

<p>The biggest surprise was that Write.as now heavily rate limits calls to its API. And because of how I wrote WriteAs.NET, a rate limited call just comes back empty instead of throwing an error. So the first test run fetched 20 out of 55 posts, and would have happily given me an incomplete archive page without me knowing.</p>

<p>The fix was to slow things down. The app now waits 10 seconds between each page of posts, retries if it still gets rate limited, and checks the number of posts it got against what the blog says it has. It&#39;s slow, but it gets all of them. Funny enough, that&#39;s an improvement over the old version, which used to time out on blogs with a lot of posts. An API key would probably help with the rate limiting, but I don&#39;t have one set up right now.</p>

<p>There was also a bug in the new version where some emojis in post titles showed up as code instead of the actual emoji. That one got fixed real quick.</p>

<h2 id="it-s-on-github">It&#39;s on GitHub</h2>

<p>Back in 2022, I said I&#39;d share the source code for the WPF version of this tool if there was enough interest. This time around, I&#39;m just putting it out there: <a href="https://github.com/DinoBansigan/writeas-archive-generator">writeas-archive-generator</a>. It&#39;s a console app, so no pretty UI, but it does the job. You&#39;ll need the .NET 10 SDK to run it, and the README has all the details.</p>

<p>Eventually, I want to build a Windows desktop app with a UI for it. But for now, this works, and my archive page is up to date again. Thanks for reading, and I&#39;ll catch you in the next DevLog.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:DevLog" class="hashtag"><span>#</span><span class="p-category">DevLog</span></a> <a href="https://devblog.dinobansigan.com/tag:ClaudeCode" class="hashtag"><span>#</span><span class="p-category">ClaudeCode</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a> <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:WriteAs" class="hashtag"><span>#</span><span class="p-category">WriteAs</span></a> <a href="https://devblog.dinobansigan.com/tag:WriteAsNet" class="hashtag"><span>#</span><span class="p-category">WriteAsNet</span></a></em></p>



<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/devlog-005-the-write-as-archive-page-generator-is-back">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/devlog-005-the-write-as-archive-page-generator-is-back</guid>
      <pubDate>Wed, 14 Oct 2026 21:30:31 +0000</pubDate>
    </item>
    <item>
      <title>DevNotes - 005</title>
      <link>https://devblog.dinobansigan.com/devnotes-005?pk_campaign=rss-feed</link>
      <description>Fire and forget template for C#/.NET to run something that you don&#39;t need to wait on and don&#39;t care about the results. Task.Run(() =&gt; { /...</description>
      <content:encoded><![CDATA[<p>Fire and forget template for C#/.NET to run something that you don&#39;t need to wait on and don&#39;t care about the results.</p>

<pre><code class="language-csharp">Task.Run(() =&gt;
{
	//code goes here
});
</code></pre>

<hr/>

<p>In ReactJS, if ESLint says you cannot use inline arrow functions to pass in props in JSX, a solution is to wrap them with the <code>useCallback</code> hook.</p>

<p>Reference: <a href="https://stackoverflow.com/a/36677798/5041911">https://stackoverflow.com/a/36677798/5041911</a></p>

<hr/>

<p><a href="https://react-bootstrap.netlify.app/docs/components/modal/">Modals</a> — can be used to add dialog or popup info boxes on your ReactJS app.</p>

<hr/>

<p>So using <a href="https://www.npmjs.com/package/flat">this library</a> actually helped me solve my Azure Application Insights logging issue. The issue being, since I had a <code>dateOfBirth</code> object in my <code>formData</code> object, app insights would save it as an object, as opposed to something like <code>dateOfBirth: 2024-04-16</code>. The solution was to flatten the <code>formData</code> object so it will get logged properly in Azure App Insights.</p>

<hr/>

<p><a href="https://reactgo.com/react-render-html/">Rendering the HTML string in React</a> — short tutorial on how to render an HTML string in ReactJS/Gatsby.</p>

<hr/>

<p><strong>Series:</strong> <a href="https://devblog.dinobansigan.com/tag:DevNotes" class="hashtag"><span>#</span><span class="p-category">DevNotes</span></a>
<strong>Tags:</strong> <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a> <a href="https://devblog.dinobansigan.com/tag:Template" class="hashtag"><span>#</span><span class="p-category">Template</span></a> <a href="https://devblog.dinobansigan.com/tag:ReactJS" class="hashtag"><span>#</span><span class="p-category">ReactJS</span></a> <a href="https://devblog.dinobansigan.com/tag:Azure" class="hashtag"><span>#</span><span class="p-category">Azure</span></a> <a href="https://devblog.dinobansigan.com/tag:ApplicationInsights" class="hashtag"><span>#</span><span class="p-category">ApplicationInsights</span></a> <a href="https://devblog.dinobansigan.com/tag:Gatsby" class="hashtag"><span>#</span><span class="p-category">Gatsby</span></a></p>



<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/devnotes-005">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/devnotes-005</guid>
      <pubDate>Tue, 23 Apr 2024 17:18:27 +0000</pubDate>
    </item>
    <item>
      <title>Useful Array Functions in JavaScript and C#</title>
      <link>https://devblog.dinobansigan.com/useful-array-functions-in-javascript-and-csharp?pk_campaign=rss-feed</link>
      <description>How to check if array contains a specific item To check if an object or item is contained in a JavaScript array, you can use the includes...</description>
      <content:encoded><![CDATA[<h3 id="how-to-check-if-array-contains-a-specific-item">How to check if array contains a specific item</h3>

<p>To check if an object or item is contained in a JavaScript array, you can use the <code>includes</code> function, like so:</p>

<pre><code class="language-js">const customerIds = [1, 2, 3, 4, 5];
console.log(&#39;IsIncludedInArray&#39;, customerIds.includes(3));
</code></pre>

<p>To do the same thing in C#, you can use the <code>Contains</code> or <code>Any</code> LINQ method, like so:</p>

<pre><code class="language-cs">var customerIds = new int[5] { 1, 2, 3, 4, 5};
Console.WriteLine(&#34;IsIncludedInArray &#34; + customerIds.Contains(3));
Console.WriteLine(&#34;IsIncludedInArray &#34; + customerIds.Any(n =&gt; n == 3));
</code></pre>

<hr/>

<h3 id="how-to-filter-out-contents-in-an-array">How to filter out contents in an array</h3>

<p>To filter out the contents of an array in JavaScript, you can use the <code>filter</code> function., like so:</p>

<pre><code class="language-js">const customerIds = [1, 2, 3, 4, 5];
const filteredCustomerIds = customerIds.filter(n =&gt; n &lt;= 3);
console.log(&#39;Filtered CustomerIds&#39;, filteredCustomerIds);
</code></pre>

<p>To do the same thing in C#, you can use the <code>Where</code> LINQ method.</p>

<pre><code class="language-cs">var customerIds = new int[5] { 1, 2, 3, 4, 5};
var filteredCustomerIds = customerIds.Where(n =&gt; n &lt;= 3);

foreach (var n in filteredCustomerIds)
{
  Console.WriteLine(n);
}
</code></pre>

<p>Tags: <a href="https://devblog.dinobansigan.com/tag:JavaScript" class="hashtag"><span>#</span><span class="p-category">JavaScript</span></a> <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/useful-array-functions-in-javascript-and-csharp">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/useful-array-functions-in-javascript-and-csharp</guid>
      <pubDate>Sat, 05 Feb 2022 13:46:15 +0000</pubDate>
    </item>
    <item>
      <title>WCF BindingConfiguration Error</title>
      <link>https://devblog.dinobansigan.com/wcf-bindingconfiguration-error?pk_campaign=rss-feed</link>
      <description>A week ago I was running a test and kept running into a WCF BindingConfiguration Error. I would not allow myself to check-in my code unle...</description>
      <content:encoded><![CDATA[<p>A week ago I was running a test and kept running into a WCF BindingConfiguration Error. I would not allow myself to check-in my code unless my tests passed. So, I battled with this error for over an hour.</p>

<blockquote><p>The binding at system.serviceModel/bindings/basicHttpBinding does not have a configured binding named ‘BasicHttpBinding_IXXXXXX’. This is an invalid value for bindingConfiguration.</p></blockquote>

<p><em>It&#39;s your basic, run of the mill, WCF BasicHttpBinding configuration error.</em></p>

<p>I double-checked my test project&#39;s app.config file and the relevant client.config files – everything looked right. I know it was a configuration issue. The error message itself made it obvious that it was a configuration issue. But everything looked right. I didn&#39;t see any issues with the config files I was looking at.</p>

<p><em>It must be noted that it was already close to midnight at this point. I was working late that day and decided to push myself by resolving to check-in my changes before the night ends. I have no doubt that being tired and sleepy didn&#39;t help.</em></p>

<p>Anyway, after awhile I realized that the service method that I was trying to test, was running inside another service. So, in addition to the test project’s app.config file, I also needed to double-check that other service’s Web.config file. When I ran into this error earlier that night, I actually updated that other Web.config file. I added the entry it needed just to cover my bases. I didn&#39;t know then that it was the Web.config file that was causing the error.</p>

<p>For some reason, possibly due to fatigue and needing sleep, I didn&#39;t think about checking that Web.config file again. Out of frustration, I decided to take a break and headed to the kitchen to drink a glass of water. After hanging out in the kitchen for a bit, then listening to some good music, I finally had the bright idea to check this other Web.config file again. And there it was, a typo on the BasicHttpBinding entry I added. Can&#39;t believe I didn&#39;t check on it sooner.</p>

<p>Lesson learned here is to take a break whenever you&#39;re stuck with a problem. Give your mind time to rest. Chances are, your subconscious will kick in and tell you what to try next. And if the problem points to a configuration issue, with WCF, it most likely is. So, check all the config files, again.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:WCF" class="hashtag"><span>#</span><span class="p-category">WCF</span></a> <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a></em></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/wcf-bindingconfiguration-error">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/wcf-bindingconfiguration-error</guid>
      <pubDate>Tue, 18 Aug 2020 23:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Single Responsibility Principle</title>
      <link>https://devblog.dinobansigan.com/single-responsibility-principle?pk_campaign=rss-feed</link>
      <description>In this post, I&#39;ll share my thoughts regarding the use of the Single Responsibility Principle based on my experiences with it. The Single...</description>
      <content:encoded><![CDATA[<p>In this post, I&#39;ll share my thoughts regarding the use of the <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a> based on my experiences with it.</p>

<p>The Single Responsibility Principle is one of the five design principles listed in <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a>. Gary McLean Hall in his book <em>“Adaptive Code via C#”</em> says,</p>

<blockquote><p>“The single responsibility principle instructs developers to write code that has one <em>and only one</em> reason to change. If a class has more than one reason to change, it has more than one responsibility. Classes with more than a single responsibility should be broken down into smaller classes, each of which should have only one responsibility and reason to change.”</p></blockquote>

<p>It is my favorite principle out of the five because of two reasons:</p>

<h3 id="1-easy-to-implement">1. Easy to Implement</h3>

<p>First, it is very easy to implement. You don&#39;t have to be an experienced software developer to start implementing the single responsibility principle in your code. All you need to keep in mind when writing code for a new class or sometimes even a method is, <em>this block of code should be responsible for only one thing.</em></p>

<p>Are you writing code for a class to parse text files? Then make sure all the code in that class is oriented towards parsing text files. Are you writing code for a class that is supposed to send email notifications? Then keep the code focused on sending email notifications.</p>

<h3 id="2-better-code">2. Better Code</h3>

<p>Second reason is that it will always make your code better. Better in the sense that it helps decouples your classes/methods, which reduces the potential for bugs when refactoring code. This in turn also makes your code easier to test. In my experience, I have never seen code that was made worse by implementing the single responsibility principle.</p>

<h3 id="drawbacks">Drawbacks?</h3>

<p>The only argument or drawback I&#39;ve heard to the use of this principle, is the possibility of increased maintenance of the code. Since each class is responsible for doing only one thing, you could end up with a lot more classes, methods, files and projects in your solution. Still, in my opinion, that is preferable if it means I have stable code that is less prone to bugs, than to have code that is low maintenance but is susceptible to bugs.</p>

<p>There is also the chance that a developer will try to implement this principle on a very simple app that doesn&#39;t need to change after it&#39;s been written. In this case, trying to implement the single responsibility principle will probably take more time and add complexity to the code. <em>(I haven&#39;t exactly ran into a situation like this with this principle, but I think that&#39;s a possibility.)</em> Sometimes you will have to pick and choose where and when to implement this principle, and that can only come with experience.</p>

<h3 id="example">Example</h3>

<p>Let me go through an example where I think the use of the single responsibility principle would help.</p>

<p>Say you have a business rule that needs to be implemented for various products. Say that Product A, B and C all use this business rule. One thing I&#39;ve seen in my experience is that if the business rule logic is similar between Products A, B or C, some developers will opt to create just one class to implement the business rule for all products. Again the argument here is that since the business logic is the same, it is easier to maintain just one class for the specific business rule. Okay, fair enough. As long as the business rule doesn&#39;t have to change between any of the products, having one class/method for the business rule is acceptable. <em>It is in violation of the single responsibility principle, but if the business rules won&#39;t ever change, then it is an acceptable implementation.</em></p>

<p>But what if the business rules does change for one product, say for Product C? Now you&#39;ll have to modify the one class that all products use, to accommodate changes for just one product. What this means is that while working on the new changes, you have an increased chance of introducing bugs to the rest of the products. This also means that any changes to that business rule for any one product, means you have to perform testing for all other products affected by the changes. That is extra work that could have been avoided by following the single responsibility principle.</p>

<p>Now what if you have to add new products that will also have the same business rule, except the new products have slightly different business rule logic in them? Will you modify the existing class to accommodate changes for the new products? If so, you&#39;ll run into the same issue above. Adding new products will almost feel like a way to introduce bugs to your code. You can avoid that by following the single responsibility principle.</p>

<p>With the use of the single responsibility principle, each product would have one class that implements a specific business rule. Any changes to the business rules for one product, will not affect the other products. Which means going forward, you only need to worry about testing the changes for the products that changed or the products that were added. Everything else should keep working the same way they&#39;ve been working before. Stress free coding with minimal chances of introducing bugs, just the way I like it.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a> <a href="https://devblog.dinobansigan.com/tag:SolidPrinciples" class="hashtag"><span>#</span><span class="p-category">SolidPrinciples</span></a> <a href="https://devblog.dinobansigan.com/tag:SoftwareDesignPrinciples" class="hashtag"><span>#</span><span class="p-category">SoftwareDesignPrinciples</span></a></em></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/single-responsibility-principle">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/single-responsibility-principle</guid>
      <pubDate>Thu, 23 Jan 2020 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Getting .NET Core 3.0</title>
      <link>https://devblog.dinobansigan.com/getting-net-core-3-0?pk_campaign=rss-feed</link>
      <description>The most convenient way it seems to get .NET Core 3.0 installed on a Windows PC, is to download the free Microsoft Visual Studio 2019 Com...</description>
      <content:encoded><![CDATA[<p>The most convenient way it seems to get .NET Core 3.0 installed on a Windows PC, is to download the free <a href="https://visualstudio.microsoft.com/vs/community/">Microsoft Visual Studio 2019 Community edition</a>. Installing Visual Studio 2019 will also install .NET Core 3.0 and after the installation is done, you can start playing around with it.</p>

<p>If you want to download the SDK or just the runtime separately, you can find them <a href="https://dotnet.microsoft.com/download/dotnet-core/3.0">here</a>.</p>

<p>To check if you already have .NET Core 3.0 installed, you can pull up a Command Prompt and run the <code>dotnet --version</code> command.</p>

<p>Lastly, if you&#39;re trying to learn ASP.NET Core like I am, this <a href="https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-3.0#recommended-learning-path">recommended learning path</a> seems to be a good starting point.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNetCore" class="hashtag"><span>#</span><span class="p-category">DotNetCore</span></a></em></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/getting-net-core-3-0">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/getting-net-core-3-0</guid>
      <pubDate>Thu, 21 Nov 2019 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>String Comparisons in C#</title>
      <link>https://devblog.dinobansigan.com/string-comparisons-in-csharp?pk_campaign=rss-feed</link>
      <description>For the past month or so, I have noticed that I&#39;ve been pointing out the need to do case-insensitive string comparisons in the code revie...</description>
      <content:encoded><![CDATA[<p>For the past month or so, I have noticed that I&#39;ve been pointing out the need to do case-insensitive string comparisons in the code reviews that I&#39;ve done. In light of that, I thought now would be a good time to do a refresher on string comparisons in C#.</p>

<h3 id="using-the-operator">Using the <code>==</code> operator</h3>

<p>Doing string comparisons in C# is easy, and the easiest way to do it, is with the <code>==</code> operator.</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = &#34;dino&#34;;
   bool areStringsEqual = userName1 == userName2;
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>True</code></p>

<p>The main drawback to this approach is that it will only do a case-sensitive comparison. So, any typo like in the sample code below, will not work.</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = &#34;dinO&#34;;
   bool areStringsEqual = userName1 == userName2;
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>False</code></p>

<p>So, let&#39;s look at another approach to comparing strings...</p>

<h3 id="using-toupper-or-tolower">Using <code>ToUpper()</code> or <code>ToLower()</code></h3>

<p>For quick case-insensitive string comparisons, you can call <code>ToUpper()</code> or <code>ToLower()</code> on your strings before doing the comparison using the <code>==</code> operator.</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = &#34;DiNo&#34;;
   bool areStringsEqual = userName1.ToUpper() == userName2.ToUpper();
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>True</code></p>

<p>I don&#39;t see much drawbacks to using this approach, except if one of your strings is null, in which case you&#39;ll then have a NullReferenceException on your hands, like in the sample code below.</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = null;
   bool areStringsEqual = userName1.ToUpper() == userName2.ToUpper();
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---&gt; System.NullReferenceException: Object reference not set to an instance of an object.</code></p>

<p><em>Note: The exception message above might look weird, but that is because I am running the sample code on <a href="https://try.dot.net/">TryDotNet</a>.</em></p>

<p>So, there is an extra step of making sure the strings are not null before you call one of its methods, like in the sample code below.</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = null;
   bool areStringsEqual = userName1 != null &amp;&amp; userName2 != null &amp;&amp; (userName1.ToUpper() == userName2.ToUpper());
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>False</code></p>

<p>The sample code above is still very much usable code, but having to do the null checks all the time can be tiring, which leads me to another way of doing string comparisons...</p>

<h3 id="using-string-compare">Using <code>String.Compare</code></h3>

<p>Using the static <code>Compare</code> method from the <code>String</code> class allows you to easily do a case-sensitive or case-insensitive string comparison using the <code>ignoreCase</code> parameter, like in the sample codes below.</p>

<p>Case-insensitive comparison:</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = &#34;DiNo&#34;;
   bool areStringsEqual = String.Compare(userName1, userName2, ignoreCase: true) == 0;
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>True</code></p>

<p>Case-sensitive comparison:</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = &#34;DiNo&#34;;
   bool areStringsEqual = String.Compare(userName1, userName2, ignoreCase: false) == 0;
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>False</code></p>

<p>The beauty of using the <code>Compare</code> method is that I don&#39;t even have to do null checks. So, taking the sample code above where I had to do null checks, and replacing it with a call to <code>String.Compare</code>, results in the much cleaner sample code below.</p>

<pre><code class="language-cs">public static void Main()
{
   string userName1 = &#34;dino&#34;;
   string userName2 = null;
   bool areStringsEqual = String.Compare(userName1, userName2, ignoreCase: true) == 0;
   Console.WriteLine(areStringsEqual.ToString());
}
</code></pre>

<p>Result:
<code>False</code></p>

<p>The only drawback to this approach is that it might be harder to <em>read</em> the first time around, because the <code>String.Compare</code> method returns an <code>int</code>, instead of a <code>boolean</code> value.</p>

<p>Normally when comparing strings, we are asking the question, are the strings equal? True or False? So, we are expecting a <code>boolean</code> value back. With the use of <code>String.Compare</code> method, you must compare the results to 0 to determine if the strings are equal. It might take a while to get used to, but the fact that you can throw any string object at this method and not worry about null checks and typos, to me that makes it the superior approach to string comparisons.</p>

<h3 id="which-one-do-i-use-the-most">Which One Do I Use the Most?</h3>

<p>When developing prototype applications or generally when I&#39;m just testing something, I am fine with using the <code>ToUpper()</code> or <code>ToLower()</code> approach. When I&#39;m guaranteed that none of the strings will be null, I would use the <code>ToUpper()</code> or <code>ToLower()</code> approach. Any other scenario, I prefer to use the <code>String.Compare</code> method.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a></em></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/string-comparisons-in-csharp">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/string-comparisons-in-csharp</guid>
      <pubDate>Thu, 07 Nov 2019 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Delaying Message Processing in RabbitMQ</title>
      <link>https://devblog.dinobansigan.com/delaying-message-processing-in-rabbitmq?pk_campaign=rss-feed</link>
      <description>If you search for “how to delay message processing in RabbitMQ”, you&#39;ll most likely run into two possible solutions for it. One solution ...</description>
      <content:encoded><![CDATA[<p>If you search for <em>“how to delay message processing in RabbitMQ”</em>, you&#39;ll most likely run into two possible solutions for it.</p>
<ul><li>One solution is to make use of the <a href="https://www.rabbitmq.com/ttl.html#per-message-ttl">message TTL argument</a> with additional queues to route messages through. <em>If I understood this approach correctly, you basically route your message to Queue A, where it will sit for some time before it expires and gets moved to another queue, say Queue B. Then you will have your consumer looking for messages at Queue B.</em></li>
<li>The second solution is to use the official <a href="https://github.com/rabbitmq/rabbitmq-delayed-message-exchange">RabbitMQ Delayed Message Plugin</a>.</li></ul>

<p>Both solutions presented above are valid solutions, but I ended up not implementing any of those solutions, and instead went with a solution that is configurable via the consumer application. First, my reasons for not going with the established solutions listed above.</p>
<ul><li>I did not want to add any more queues or exchanges, especially if their purpose is to just move messages around.</li>
<li>The <a href="https://github.com/rabbitmq/rabbitmq-delayed-message-exchange">RabbitMQ Delayed Message Plugin</a> as of this writing is still listed as an <em>“experimental yet fairly stable”</em> plugin. The <em>“experimental”</em> disclaimer is a matter of concern to me and I would prefer to wait until it matures enough that it is no longer called as such.</li>
<li>Lastly, I really wanted a solution that is configurable via the consumer application.</li></ul>

<p>So, the solution I went with was to add a PublishDate via the message headers and then the consumer can delay message processing based on this date value.</p>

<p>Adding a PublishDate header value is easy, you add it to the Properties.Headers dictionary before publishing the message.</p>

<pre><code class="language-cs">var properties = channel.CreateBasicProperties();
properties.Persistent = true;

properties.Headers = new Dictionary&lt;string, object&gt;();
properties.Headers.Add(&#34;PublishDate&#34;, DateTime.Now.ToString());

channel.BasicPublish(exchange: &#34;&#34;,
    routingKey: &#34;task_queue&#34;,
    basicProperties: properties,
    body: body);
</code></pre>

<p><em>Note that I&#39;m adding the PublishDate value as a string, instead of a DateTime value. For some reason, adding it to the dictionary as a DateTime value causes an error. I don&#39;t remember what the error was, something about an invalid table value, so I just went with a string value.</em></p>

<p>On the consumer side, you will need to add code to retrieve the Publish Date from the headers.</p>

<pre><code class="language-cs">consumer.Received += (model, ea) =&gt;
{
    byte[] publishDateHeader = (byte[])ea.BasicProperties.Headers[&#34;PublishDate&#34;];
    DateTime publishDate = Convert.ToDateTime(Encoding.UTF8.GetString(publishDateHeader));
    // Now you can delay message processing based on the publish date value

    var body = ea.Body;
    var message = Encoding.UTF8.GetString(body);
    Console.WriteLine(&#34; [x] Received {0}&#34;, message);

    channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
</code></pre>

<p><em>Note that I&#39;m first casting the header value to a byte array, before converting it to a string, then finally to a DateTime value. For some reason, adding a string as a custom header turns it into a byte array. Thankfully somebody else ran into this issue before and <a href="http://gigi.nullneuron.net/gigilabs/rabbitmq-string-headers-received-as-byte-arrays/">shared a solution for it</a>.</em></p>

<p>With a PublishDate value available, you can now delay message processing however you would like. In my case, I opted to compare the PublishDate value to the DateTime.Now value, which allowed me to check how old the message was. For example, if a message was 5 minutes old, it has been delayed enough and gets processed right away. If the message was only a minute old, the consumer thread will wait until such time that the message was now 5 minutes old, before it processes it.</p>

<p>There are some drawbacks to this approach, namely, you will have to go through the Publisher/Consumer classes to add the code for handling a PublishDate header value. Depending on how your queues are structured and how many publisher-consumer class files you have, you could end up with changes to multiple files just to add this feature. On the flip side though, if only one queue needs this “delayed message processing” feature, then you&#39;ll have minimal changes while your other queues continue as is. There are probably more pros and cons to this approach that I haven&#39;t thought of. Still I prefer the flexibility with this approach as I only must worry about editing a consumer&#39;s config file and it allows me to run multiple consumers each with their own specific message processing setting.</p>

<p>Have you had to design a solution to delay message processing in RabbitMQ? If so, I am curious to hear what approach you went with and why. Please do share in the comments below or send me an email and we can discuss.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a> <a href="https://devblog.dinobansigan.com/tag:RabbitMQ" class="hashtag"><span>#</span><span class="p-category">RabbitMQ</span></a></em></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/delaying-message-processing-in-rabbitmq">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/delaying-message-processing-in-rabbitmq</guid>
      <pubDate>Mon, 17 Jun 2019 23:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Problems with Simplifying Object Initializations</title>
      <link>https://devblog.dinobansigan.com/problems-with-simplifying-object-initializations?pk_campaign=rss-feed</link>
      <description>This is a problem I&#39;ve seen in the past and just recently actually, where exceptions are made harder to troubleshoot, because of the way ...</description>
      <content:encoded><![CDATA[<p>This is a problem I&#39;ve seen in the past and just recently actually, where exceptions are made harder to troubleshoot, because of the way objects are instantiated. Allow me to explain.</p>

<pre><code class="language-cs">class Program
{
    static void Main(string[] args)
    {
        try
        {
            UserDto dto = new UserDto()
            {
                UserName = &#34;Apatosaurus&#34;,
                LastLoginDate = null
            };

            User user = new User()
            {
                UserName = dto.UserName,
                LastLoginDate = dto.LastLoginDate.Value.ToString(&#34;MM-dd-yyyy&#34;)
            };

            Console.WriteLine(&#34;User Info:&#34;);
            Console.WriteLine(&#34;Username: &#34; + user.UserName);
            Console.WriteLine(&#34;LastLoginDate: &#34; + user.LastLoginDate);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }
    }
}

class User
{
    public string UserName { get; set; }
    public string LastLoginDate { get; set; }
}

class UserDto
{
    public string UserName { get; set; }
    public DateTime? LastLoginDate { get; set; }
}
</code></pre>

<p>Take for example the code above. What happens if the <code>dto.LastLoginDate</code> property is actually null when instantiating a <code>User</code> object?</p>

<pre><code>at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Nullable`1.get_Value()
at NullRefErrorExample.Program.Main(String[] args) in C:\Users\dbansigan\source\repos\NullRefErrorExample\NullRefErrorExample\Program.cs:line 21
</code></pre>

<p>The error message above is what was displayed in the console app I was running. Line 21 points to <code>User user = new User()</code>, which is the line of code that was instantiating an object, but not the line of code that caused the exception. It should have pointed to Line 24 instead, <code>LastLoginDate = dto.LastLoginDate.Value.ToString(&#34;MM-dd-yyyy&#34;)</code>. However, since I followed Visual Studio&#39;s suggestion (<em>IDE0017 Object initialization can be simplified</em>), to simplify object initialization, this is what happened. So now you can see how it can make troubleshooting a more time-consuming task.</p>

<p><em>Note that this is a very simple example. Imagine if you had big class that had like 20 properties and multiple lines of initialization code that could cause an exception? It would be pretty hard to figure out which line of code caused the exception without having to debug the application.</em></p>

<h3 id="so-how-do-we-fix-it-should-we-even-still-try-to-simplify-object-initialization">So how do we fix it? Should we even still try to simplify object initialization?</h3>

<p>Yes, we can still simplify object initializations, however we just have to be wary of using code that can cause exceptions when assigning property values. So the rule that I follow is that any line of code that could throw a null reference exception, or any exception for that matter, is taken out of the code that simplifies object initialization; they are instead moved to their own line.</p>

<p>So, taking the example from above, this is how I would initialize the object with the rule in mind. I basically just take out the code that assigns the value to the <code>user.LastLoginDate</code> property and move it outside the brackets containing the simplified initialization code.</p>

<pre><code class="language-cs">User user = new User()
{
    UserName = dto.UserName
};
user.LastLoginDate = dto.LastLoginDate.Value.ToString(&#34;MM-dd-yyyy&#34;);
</code></pre>

<p>I run the app once again and this is what the stack trace tells me.</p>

<pre><code>at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Nullable`1.get_Value()
at NullRefErrorExample.Program.Main(String[] args) in C:\Users\dbansigan\source\repos\NullRefErrorExample\NullRefErrorExample\Program.cs:line 25
</code></pre>

<p>Notice how the stack trace now points to Line 25 <code>user.LastLoginDate = dto.LastLoginDate.Value.ToString(&#34;MM-dd-yyyy&#34;);</code>, which is exactly the line of code that caused the exception. So now I get a head start on troubleshooting the exception. Also, any experienced developer will be able to tell almost immediately what caused the exception, if all they had to do was look at 1 line of code.</p>

<h3 id="are-there-alternative-solutions-to-this">Are there alternative solutions to this?</h3>

<p>An alternative is to check for null before even considering instantiating an object, like in the code below. I think this is a valid solution and it allows you to throw an exception with a detailed/specific message, or throw a custom exception. That said, if you are throwing an exception only because you cannot instantiate an object, then I don&#39;t see how it is significantly better than just letting it error out on the line of code assigning the property value. Your application is not going anywhere anyway, since you still cannot instantiate the object you need for your application to move forward.</p>

<pre><code class="language-cs">if (!dto.LastLoginDate.HasValue)
{
    throw new NullReferenceException(&#34;dto.LastLoginDate cannot be null&#34;);
}
</code></pre>

<p><em>Another possible alternate solution could come from the use of nullable reference types in C# 8. However, this is something I have not been able to play with yet, so I cannot comment on the use of it.</em></p>

<p>I&#39;ve seen this problem occur on other types of code as well, like for instance code where method chaining happens. If there is an exception, the end result is the same; you can hardly tell which method parameter, or which method call, or which specific part of the code caused the exception, because they are all essentially just one line of code. In situations like this, it is often advisable to break up the chain of method calls, unless you are absolutely sure that it can never cause an exception.</p>

<p>I&#39;m curious to think if other developers also instantiate objects in this manner to avoid exceptions when creating objects. If you do, or you don&#39;t, I&#39;m curious to hear your reasons for doing so. Please do <a href="https://write.as/attach-to-process/contact">send me a message</a> so we can discuss.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a></em></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/problems-with-simplifying-object-initializations">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/problems-with-simplifying-object-initializations</guid>
      <pubDate>Thu, 16 May 2019 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>How to Sync System Date/Time to Domain Controller</title>
      <link>https://devblog.dinobansigan.com/how-to-sync-system-date-time-to-domain-controller?pk_campaign=rss-feed</link>
      <description>Have you ever had to do testing wherein you had to move your system date/time forward or back? If so, you will probably agree that one of...</description>
      <content:encoded><![CDATA[<p>Have you ever had to do testing wherein you had to move your system date/time forward or back? If so, you will probably agree that one of the annoying things is remembering to reset the system date/time back to the current date/time. Most people will manually do this, which can be tiring when done multiple times during the day. If you are working in an office environment, then your workstation&#39;s system date/time can most likely be synced to a domain controller. Here is how you can easily do that using the command prompt in Windows.</p>

<p>Open up the command prompt and type in the command listed below:</p>

<pre><code>net time /domain /set /y
</code></pre>

<p><em>You might have to open the command prompt in Administrator mode to get it to work.</em></p>

<p>Taking this a step further, what if you can automatically reset the system date/time on your workstation after a test finishes? I&#39;ve had to do something similar since I&#39;ve had to maintain some Coded UI tests, that can change the system date/time as part of their testing. So I wrote a utility method in C# that will reset the system date/time after a Coded UI test ends. This is called via the TestCleanup method that will run after a test ends.</p>

<pre><code class="language-cs">[TestCleanup]
public void CleanUp()
{
    ResetLocalSystemTime();
}

private void ResetLocalSystemTime()
{
    using (Process netTime = new Process())
    {
        netTime.StartInfo.FileName = &#34;NET.exe&#34;;
        netTime.StartInfo.Arguments = @&#34;TIME /DOMAIN /SET /Y&#34;;
        netTime.StartInfo.UseShellExecute = false;
        netTime.StartInfo.CreateNoWindow = false;
        netTime.Start();

        Task.Delay(1000);
    }
}
</code></pre>

<p>Hope this helps some of the devs out there doing some testing. If you have a different way of doing this, do share them in the comments below or <a href="https://write.as/attach-to-process/contact">share them in a message</a>.</p>

<p><em>Tags: <a href="https://devblog.dinobansigan.com/tag:CSharp" class="hashtag"><span>#</span><span class="p-category">CSharp</span></a> <a href="https://devblog.dinobansigan.com/tag:DotNet" class="hashtag"><span>#</span><span class="p-category">DotNet</span></a> <a href="https://devblog.dinobansigan.com/tag:Tests" class="hashtag"><span>#</span><span class="p-category">Tests</span></a></em></p>

<p><strong><a href="https://remark.as/p/devblog.dinobansigan.com/how-to-sync-system-date-time-to-domain-controller">Discuss...</a></strong> or leave a comment below.</p>
]]></content:encoded>
      <guid>https://devblog.dinobansigan.com/how-to-sync-system-date-time-to-domain-controller</guid>
      <pubDate>Thu, 07 Mar 2019 00:00:00 +0000</pubDate>
    </item>
  </channel>
</rss>