Olivier Muhring

Olivier Muhring

  • 2k
  • 150
  • 4.2k

Serializing a C# class into a complex JSON

May 15 2022 5:50 PM

Gentlemen,
Ladies,

I have been working on an application for a legacy project. This application uses OAuth for user authentication. 

For this purpose, the application builds a JSON and then adds this to a request sent to the authentication server. This JSON looks like this:

{
    "scope": [
        "SomeCompany"
    ],
    "data": "{\"username\":\"Gebruiker1\",\"password\":\"Sterk2020\"}",
    "profile_id": "654321"
}

My application generates this JSON at each authentication attempt by serializing 2 separate C# classes to simulate the structures seen here.

I do this to avoid complications with special characters inside the user name or the password. Assuming of course my plan works.

In addition, since all of this is legacy, I'm no longer allowed to add or upgrade any packages, which tends to limit my option, given the age (15+ years) of the codebase. 

The 1st class is UserPasswordJson:

    using System;
    using System.IO;
    using System.Runtime.Serialization.Json;

    namespace JsonSerialization.Json
    {
        using System.Collections.Generic;
        using System.Runtime.Serialization;
    
        [DataContract]
        public class UserPasswordJson
        {
            [DataMember(Name = "scope", IsRequired = true, Order = 1)]
            public List<string> Scope { get; set; }
            [DataMember(Name = "data", IsRequired = true, Order = 2)]
            public string Data { get; set; }
            [DataMember(Name = "profile_id", IsRequired = true, Order = 3)]
            public string ProfileId { get; set; }
            
    
            public UserPasswordJson(string userName, string password)
            {
                Scope = new List<string> { "SomeCompany" };
    
                var randomGenerator = new Random();
    
                var randomNumber = randomGenerator.Next(999999);
                ProfileId = randomNumber.ToString("D6");
    
                var userPassword = new UserPasswordCombination(userName, password);
                var stream = new MemoryStream();
                var serializer = new DataContractJsonSerializer(typeof(UserPasswordCombination));
                serializer.WriteObject(stream, userPassword);
    
                stream.Position = 0;
                var streamReader = new StreamReader(stream);
    
                var jsonString = streamReader.ReadToEnd();
    
                Data = jsonString;
            }
        }
    }

The 2nd class is UserPasswordCombination:

    using System.Runtime.Serialization;
    
    namespace JsonSerialization.Json
    {
        [DataContract]
        public class UserPasswordCombination
        {
            [DataMember(Name = "username", IsRequired = true, Order = 1)]
            public string UserName { get; set; }
            [DataMember(Name = "password", IsRequired = true, Order = 2)]
            public string Password { get; set; }
    
            public UserPasswordCombination(string userName, string password)
            {
                UserName = userName;
                Password = password;
            }
        }
    }

So, whenever I want to serialize the objects I do:

    public static string BuildJson(string userName, string password)
    {
        var jsonObject = new UserPasswordJson(userName, password);
    
        var stream = new MemoryStream();
        var serializer = new DataContractJsonSerializer(typeof(UserPasswordJson));
        serializer.WriteObject(stream, jsonObject);
    
        stream.Position = 0;
        var streamReader = new StreamReader(stream);
        var result = streamReader.ReadToEnd();
    
        return result;
    }

I've been playing around with this in a console application, to easily check the JSON file it generates. So far I've done 3 separate tests:

1. No special characters

{
    "scope": [ "SomeCompany" ],
    "data": "{\"username\":\"Gebruiker1\",\"password\":\"Sterk2020\"}",
    "profile_id": "964701"
}

2. 1 special character

{
    "scope": [ "SomeCompany" ],
    "data": "{\"username\":\"Gebruiker1\",\"password\":\"Sterk2020\"}",
    "profile_id": "964701"
}

3. A bunch of special characters

{
    "scope": [ "SomeCompany" ],
    "data": "{\"username\":\"abcdéf@\\\\\",\"password\":\"ükdsfdjnè!ç\"}",
    "profile_id": "550256"
}

Each JSON file is valid, but I'm not sure they will deserialize properly. I have no idea how the other side will deal with these files, so I'm trying to double-check things.

Anyone here has an idea of whether or not I'm still missing something, or if the idea I had will actually do what I intend it to do?

 


Answers (1)