Dapplo.Jira icon indicating copy to clipboard operation
Dapplo.Jira copied to clipboard

Migrate from Newtonsoft.Json to System.Text.Json with Source Generation

Open Copilot opened this issue 2 months ago • 3 comments

Replaced JSON.NET with System.Text.Json throughout the library to use modern .NET serialization and eliminate security vulnerabilities.

Changes

Dependencies

  • Added System.Text.Json 9.0.1 (fixes CVE in 8.0.4)
  • Removed Newtonsoft.Json 13.0.3
  • Removed Dapplo.HttpExtensions.JsonNet 1.1.2

Attribute Migration (100+ entity files)

  • [JsonProperty("name")][JsonPropertyName("name")]
  • [JsonObject] → removed (unnecessary in System.Text.Json)
  • StringEnumConverterJsonStringEnumConverter
  • CustomDateTimeOffsetConverterJiraDateTimeOffsetConverter

Core Infrastructure

  • Created SystemTextJsonSerializer : IJsonSerializer to replace JsonNetJsonSerializer
  • Created JiraJsonSerializerOptions for shared serialization configuration
  • Created JiraJsonContext with source generation support for .NET 6+ (AOT-friendly, high-performance)
  • Updated JiraClient to use new serializer

Source Generation

  • Implemented compile-time JSON serialization for .NET 6.0 and greater
  • Automatically activated when targeting modern .NET frameworks
  • Provides better performance and AOT compatibility
  • Falls back to reflection-based serialization for .NET Framework 4.8.1
  • Includes all major entity types (Issue, User, Project, Board, Sprint, etc.) and collections

Code Patterns

// Before: Newtonsoft.Json
var jsonContent = new JObject { { "username", username }, { "password", password } };
var content = new StringContent(jsonContent.ToString(Formatting.None));

// After: System.Text.Json
var credentials = new { username, password };
var json = JsonSerializer.Serialize(credentials, JiraJsonSerializerOptions.Default);
var content = new StringContent(json);
// Before: JArray/JToken manipulation
if (!(customField is JArray jArray)) return null;
return jArray[0]?.ToObject<Sprint>();

// After: JsonElement
if (!(customField is JsonElement jsonElement)) return null;
var jArray = jsonElement.EnumerateArray().ToArray();
return JsonSerializer.Deserialize<Sprint>(jArray[0].GetRawText(), JiraJsonSerializerOptions.Default);

Dependency Impact

System.Text.Json is now required:

  • Built-in for .NET 5.0+
  • NuGet package for .NET Framework 4.8.1
  • More performant than JSON.NET, actively maintained, no security vulnerabilities
  • Source generation provides additional performance benefits for .NET 6+
Original prompt

This section details on the original issue you should resolve

<issue_title>Replace the usage of json.net with System.Text.Json</issue_title> <issue_description>Replace the usage of json.net with System.Text.Json, if possible with code generation. Is it possible to remov3 the need for a dependency on System.Text.Json for the project using Dapplo.Jira?</issue_description>

Comments on the Issue (you are @copilot in this section)

  • Fixes dapplo/Dapplo.Jira#84

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot avatar Dec 24 '25 23:12 Copilot