.NET JSON Serialization and deserialization flavoured with some inheritance

Imagine, you have a base class.

    public class BaseClass
    {
        public string BaseProperty { get; set; }
    }

It can have a base property in it. To keep OOP principles in mind, you are creating a derived class by of it called “InheritedClass”

    public class InheritedClass : BaseClass
    {
        public string PlusProperty { get; set; }
    }

And you are defining a container class, which holds an instance of a BaseClass or an InheritedClass. You are defining a property with BaseClass type. It will fit to InheritedClass too.

    public class ContainerClass
    {
        public BaseClass Property { get; set; }
    }

If you are casting your object, the PlusProperty’s value never gets lost, because the framework allocates the memory for an InheritedClass.

But what about, if you are serialize this object, and then deserialize it back? What do you think, what will be the result of this program?

    class Program
    {
        static void Main(string[] args)
        {
            var toBeSerialized = new ContainerClass();
            toBeSerialized.Property = new InheritedClass()
            {
                BaseProperty = "I am base property",
                PlusProperty = "I am an inherited plus property"
            };

            string serializedJSON = JsonConvert.SerializeObject(toBeSerialized);

            ContainerClass deserialized = (ContainerClass)JsonConvert.DeserializeObject(serializedJSON, typeof(ContainerClass));

            Console.WriteLine(deserialized.Property.GetType().AssemblyQualifiedName);
            Console.WriteLine((deserialized.Property as InheritedClass)?.PlusProperty);
            Console.ReadLine();
        }
    }

This code snippet gives the following result:

TestConsoleApp.BaseClass, TestConsoleApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null


That is because JSON does not include type names when serializing and deserializing an object.

You can set TypeNameHandling = All for your JsonSerializerSettings, but it is highly unrecommended by Microsoft, because it can lead you into security issues, allows attackers remote code execution.

        static void Main(string[] args)
        {
            var toBeSerialized = new ContainerClass();
            toBeSerialized.Property = new InheritedClass()
            {
                BaseProperty = "I am base property",
                PlusProperty = "I am an inherited plus property"
            };

            string serializedJSON = JsonConvert.SerializeObject(toBeSerialized, new JsonSerializerSettings()
            {
                TypeNameHandling = TypeNameHandling.All
            });

            ContainerClass deserialized = (ContainerClass)JsonConvert.DeserializeObject(serializedJSON, typeof(ContainerClass), new JsonSerializerSettings()
            {
                TypeNameHandling = TypeNameHandling.All
            });

            Console.WriteLine(deserialized.Property.GetType().AssemblyQualifiedName);
            Console.WriteLine((deserialized.Property as InheritedClass)?.PlusProperty);
            Console.ReadLine();
        }

Output:

TestConsoleApp.InheritedClass, TestConsoleApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
I am an inherited plus property

” Insecure deserializers are vulnerable when deserializing untrusted data. An attacker could modify the serialized data to include unexpected types to inject objects with malicious side effects. An attack against an insecure deserializer could, for example, execute commands on the underlying operating system, communicate over the network, or delete files. ” More details at: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2326

.NET Core: Type serialization denied

When trying to return with a complex object in .NET Core API, which has a Type property in it, the serializer gives the following exception :

System.NotSupportedException: Serialization and deserialization of 'System.Type' instances are not supported and should be avoided since they can lead to security issues.

Passing Type, DataSet, DataTable through the JSON or XML serializer gives possibility to remote code execution for attackers. More information available at https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/dataset-datatable-dataview/security-guidance

Workaround:
Declare an enumeration for your types (ex: enum { string, int, etc }) you can parse the value for the requested type explicitly.

Xamarin.Android: Missing aapt.exe

When trying to deploy an application to simulator or device, Visual Studio gives the following error:

Cannot find `aapt.exe`. Please install the Android SDK Build-Tools package with the `C:\Program Files (x86)\Android\android-sdk\tools\android.bat` program.

To solve this problem you sould go to Visual Studio’s Tools then Android and select SDK Manager option.

Navigate to this option

It will give an error dialog, that the SDK tool files are corrupted. Click repair.

Click on Repair

The mentioned batch command in the error message is deprecated by the way.

Microsoft Windows [Version 10.0.19042.804]
(c) 2020 Microsoft Corporation. All rights reserved.

C:\Users\banditoth>cd C:\Program Files (x86)\Android\android-sdk\tools\

C:\Program Files (x86)\Android\android-sdk\tools>android.bat
**************************************************************************
The "android" command is deprecated.
For manual SDK, AVD, and project management, please use Android Studio.
For command-line tools, use tools\bin\sdkmanager.bat
and tools\bin\avdmanager.bat
**************************************************************************

Invalid or unsupported command ""

Supported commands are:
android list target
android list avd
android list device
android create avd
android move avd
android delete avd
android list sdk
android update sdk

C:\Program Files (x86)\Android\android-sdk\tools>

.NET Core : Logging with Log4NET in .NET Core application

There are tons of newly created logging engines for .NET Core. Log4Net is stable, old school technology in the market. Consider using newer logging technologies, such as NLog or Serilog. But if you want to use this engine, you can make it work.

Start with the Microsoft’s tutorial, “Logging in .NET Core”. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0

Install log4Net NuGet Package, and Microsoft.Extensions.Logging.Log4Net.AspNetCore package.

Install-Package log4Net
Install-Package Microsoft.Extensions.Logging.Log4Net.AspNetCore

Make changes in your Program.cs file. In the CreateHostBuilder method, configure logging with the following code:

                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.AddConsole();
                    logging.AddLog4Net();
                })

If the “AddLog4Net” method call is unrecognized by IntelliSense, make sure you have installed the Logging extension NuGet package mentioned above.

Add a new file to your project, and name it log4Net.config. The template should be used is Web Configuration file.

Make changes in the newly generated file, here you can configure the applications logging. I’ve skipped Console logging, Microsoft’s console logger visualize logs much greater. You can learn configuring Log4Net more at https://logging.apache.org/log4net/release/manual/configuration.html
A quick start configuration example:

<?xml version="1.0" encoding="utf-8"?>
<log4net>
	<root>
		<level value="ALL" />
		<appender-ref ref="file" />
	</root>
	<appender name="file" type="log4net.Appender.RollingFileAppender">
		<file value="myapp.log" />
		<appendToFile value="true" />
		<rollingStyle value="Size" />
		<maxSizeRollBackups value="5" />
		<maximumFileSize value="10MB" />
		<staticLogFileName value="true" />
		<layout type="log4net.Layout.PatternLayout">
			<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
		</layout>
	</appender>
</log4net>

Windows : Allow your programs through Windows Firewall

Search for applications with “firewall” keyword.
On Windows 10 – You will need Windows Defender Firewall with Advanced Security.

Click on “Inbound rules”, and on the right pane, select “New Rule..”.

Select The Port Option

If you want a specific port to unlock, select the port option. Select the correct transport protocol and port number on the next step

You can name your rule. It is recommended to choose a name, that describes the application which uses this port.

Your port now accessible on your local network. If you want to unlock a port to the Internet, you need to set up a port forward in your router’s settings.