Fluent Assertions Vs MS Test Assertions

I appreciate what fluent assertions have got to offer. Fluent Assertions have benefits of clear error messages, more readable test code and fewer lines of code needed for writing tests as iterated from the previous paragraph. The descriptive outcomes that Fluent Assertions offers also suits TDD and BDD testing methodologies.

Source: Fluent Assertions Vs MS Test Assertions

C# .net core how to get access to content file below bin\Debug\net6.0

In a .NET Core (now called .NET) application, you can access content files that are located below the bin\Debug\net6.0 (or bin\Release\net6.0 for release builds) directory using relative paths. The bin\Debug\net6.0 directory is the output directory where the compiled application and its associated files are located during development.

Here’s how you can access content files located below this directory:

  1. Set the Build Action for Content Files: First, make sure that the content files you want to access are marked with the appropriate build action. Right-click the file in Solution Explorer, go to Properties, and set the Build Action to “Content”. This ensures that the file gets copied to the output directory during the build process.
  2. Accessing Content Files: You can access content files using the System.IO namespace to manipulate file paths and read the content. Here’s an example of how you can read the content of a text file located below the bin\Debug\net6.0 directory:
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string basePath = AppDomain.CurrentDomain.BaseDirectory;
        string contentFilePath = Path.Combine(basePath, "myfile.txt");

        if (File.Exists(contentFilePath))
        {
            string content = File.ReadAllText(contentFilePath);
            Console.WriteLine("Content of the file:");
            Console.WriteLine(content);
        }
        else
        {
            Console.WriteLine("File not found.");
        }
    }
}

In this example, AppDomain.CurrentDomain.BaseDirectory gives you the path to the directory where your executable is located (bin\Debug\net6.0), and then you use Path.Combine to form the full path to the content file you want to access.

Remember that this approach works well during development, but in a production scenario, the location of the content files might differ, so you should consider different strategies for handling content files in production deployments.

Source: Chat GPT, https://chat.openai.com

How to Deserialize JSON to C# cherry-picking a small portion of JSON data

JSON deserialization in C# refers to the process of forming up .NET objects from a JSON string. Most of the time, this means creating strongly-typed POCOs. However, there are certain situations when we may prefer flexibility over type-inference. For example, cherry-picking a small portion of JSON data, dealing with external JSON data whose structure is largely unknown or changes very often, etc. Dynamic deserialization comes into play for such cases. This does not necessarily mean the use of language’s inbuilt dynamic keyword. There are other ways as well.We are going to see how we can do this using the native System.Text.Json library and the popular Newtonsoft.Json library.

Source: How to Deserialize JSON Into Dynamic Object in C# – Code Maze

Try the new System.Text.Json source generator – .NET Blog

In .NET 6.0, we are shipping a new C# source generator to help improve the performance of applications that use System.Text.Json. In this post, I’ll go over why we built it, how it works, and what benefits you can experience in your application.

Source: Try the new System.Text.Json source generator – .NET Blog

Task Async handling cancellation – Cancellation in Managed Threads | Microsoft Docs

How to handle cancellation of x number of running background tasks.

Source: Cancellation in Managed Threads | Microsoft Docs
Code examples: https://docs.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads#code-example

SharpLab Online Tool – Reveal what happens during compilation of C#

SharpLab is a .NET code playground that shows intermediate steps and results of code compilation. Some language features are thin wrappers on top of other features — e.g. using() becomes try/finally. SharpLab allows you to see the code as compiler sees it, and get a better understanding of .NET languages.

Recent versions include experimental support for running code, with some limitations.

Online tool: SharpLab

Readme: https://discoverdot.net/projects/sharplab

Working with Equals() and GetHashCode() to compare your objects in C#

In general these interfaces and methods are good to implement when working with comparing objects of the same type in C#:

Interfaces:
System.IEquatable<T> – strongly typed implementation
IComparable<T> – strongly typed implementation

Override methods:
An override of Object.Equals(Object).
An override of Object.GetHashCode().
An override of Object.ToString() is usually a good idea.
Operator overloads for operator == and operator !=.

General rule of GetHashCode():
If two objects is equal then their hashvalues should be the same.
E.g.:
If Equals == true then
x.GetHashCode() == y.GetHashCode()
GetHashCode() is frequently used by collections like Dictionary<Key, Value> and HashSet<T>

Links:
Guidelines for Overloading Equals() and Operator == (C# Programming Guide)
https://msdn.microsoft.com/en-us/library/ms173147.aspx

Visual Studio – Snippet for Arrange Act Assert comments

I like to comment my tests following the arrange, act, assert pattern.

E.g.
//Arrange
//Act
//Assert

Here is a snippet you can add to “your” snippets folder in Visual Studio 2019:
(or use menu Tools -> Code snippet manager to find your correct path to add to / or Import file).
Filename: C:\Users\andreasp\Documents\Visual Studio 2019\Code Snippets\Visual C#\My Code Snippets\testmethodcomment_act_arrange_assert.snippet

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>Test Method Comment - Act Arrange Assert</Title>
      <Shortcut>testaaa</Shortcut>
      <Description>Code snippet for a test method structure comments. Act arrange assert</Description>
    </Header>
    <Snippet>
      <Code Language="csharp">
    <![CDATA[//Arrange
    $end$
    
    //Act 
    
    //Assert
    ]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Restart Visual Studio.

Usage:
Inside testmethod, type:

testaaa [tab]

The 3 comments will be inserted, and cursor below //Arrange comment line.

c# – Ignore XML namespace when modelbinding in asp net core web api

So, in order to be able to modelbind XML to a class without taking namespaces into consideration I created new InputFormatter. And I use XmlTextReader in order to ignore namespaces. Microsoft recommends to use XmlReader rather than XmlTextReader. But since XmlTextReader is there still (in .Net 6.0 Preview 3) I’ll use it for now.

Simply create an inputformatter that inherits from XmlSerializerInputFormatter like so:

public class XmlNoNameSpaceInputFormatter : XmlSerializerInputFormatter
{
    private const string ContentType = "application/xml";
    public XmlNoNameSpaceInputFormatter(MvcOptions options) : base(options)
    {
        SupportedMediaTypes.Add(ContentType);
    }

    public override bool CanRead(InputFormatterContext context)
    {
        var contentType = context.HttpContext.Request.ContentType;
        return contentType.StartsWith(ContentType);
    }

    public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
    {
        var type = GetSerializableType(context.ModelType);
        var request = context.HttpContext.Request;

        using (var reader = new StreamReader(request.Body))
        {
            var content = await reader.ReadToEndAsync();
            Stream s = new MemoryStream(Encoding.UTF8.GetBytes(content));

            XmlTextReader rdr = new XmlTextReader(s);
            rdr.Namespaces = false;
            var serializer = new XmlSerializer(type);
            var result = serializer.Deserialize(rdr);
            return await InputFormatterResult.SuccessAsync(result);
        }
    }
}

Then add it to the inputformatters like so to startup.cs:

        services.AddControllers(o => 
        {
            o.InputFormatters.Add(new XmlNoNameSpaceInputFormatter(o));
        })
        .AddXmlSerializerFormatters();

Now we can modelbind Person or any other class no matter if there is namespaces or not in the incoming XML. Thanks to @yiyi-you

Source: c# – Ignore XML namespace when modelbinding in asp net core web api – Stack Overflow