View on GitHub qJake's

Tidbits

Bits of development knowledge from experience and headache.

Generating a Json.NET-powered C# class from a JSON object using PowerShell

Posted on: Friday, June 2, 2017

I didn’t see any good JSON converters out there that would also generate the [JsonProperty("...")] attributes that Json.NET uses, so I thought I’d write a quick PowerShell function to do it for me.

With the help of some RegEx and the TextInfo.ToTitleCase() method, we can actually make proper C# property names, so instead of:

public string client_alternate_name { get; set; }

Or even

public string clientAlternateName { get; set; }

We generate correct property names that are capitalized (as is recommended by Microsoft) and use the [JsonProperty] attribute for the “real” name, like this:

[JsonProperty("client_alternate_name")]
public string ClientAlternateName { get; set; }

Usage

To use the script, have your JSON ready in a file, or get it using Invoke-WebRequest, then pipe in the JSON string to ConvertTo-CSharpJsonClass. The only other thing you’ll need is to specify a ClassName (or if you don’t, it defaults to "MyJsonDataClass"), like so:

'{"name": "Bob", "count": 5, "amount_received": 12.34, "isFlag": true}' | ConvertTo-CSharpJsonClass -ClassName Person

Or, alternately:

$myJsonString | ConvertTo-CSharpJsonClass -ClassName Person

Or:

ConvertTo-CSharpJsonClass -Json $myJsonString -ClassName Person

Produces the following output:

public class Person
{
    [JsonProperty("amount_received")]
    public decimal AmountReceived { get; set; }

    [JsonProperty("count")]
    public int Count { get; set; }

    [JsonProperty("isFlag")]
    public bool IsFlag { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }
}

If you don’t want the [JsonProperty] attribute or you aren’t using Json.NET, you can specify -BasicMode as a switch, and it will simply name the C# property the same as the JSON property with no alterations, like so:

public class Person
{
    public decimal amount_received { get; set; }

    public int count { get; set; }

    public bool isFlag { get; set; }

    public string name { get; set; }
}

Script

Here is the source to the PowerShell script:

function ConvertTo-CSharpJsonClass
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline = $true, Mandatory = $true)]
        [string] $Json,
        [Parameter()]
        [string] $ClassName = 'MyJsonDataClass',
        [Parameter()]
        [switch] $BasicMode
    )
    process
    {
        "public class $ClassName`r`n{"

        if ($BasicMode)
        {
            $Json | ConvertFrom-Json | gm | select -Skip 4 | % { "    public $($_.Definition.Split(' ')[0]) $($_.Name) { get; set; }`r`n" }
        }
        else
        {
            $Json | ConvertFrom-Json | gm | select -Skip 4 | % {
                $formattedName = [System.Text.RegularExpressions.Regex]::Replace($_.Name.Replace("_", " "), '([A-Z])', ' $1').Trim()
                $properName = [System.Threading.Thread]::CurrentThread.CurrentCulture.TextInfo.ToTitleCase($formattedName).Replace(" ", "");
                "    [JsonProperty(`"$($_.Name)`")]`r`n    public $($_.Definition.Split(' ')[0]) $($properName) { get; set; }`r`n"
            }
        }

        "}"
    }
}