From 5dbb622ce887ee9e579f2aaa42eb0b8ecd8019a4 Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Fri, 21 Nov 2025 19:47:27 -0800 Subject: [PATCH 1/2] Add `System.Text.Json` attributes Prepare codebase for migration to System.Text.Json by adding `JsonPropertyName` attributes to all serializable models while maintaining `Newtonsoft.Json` compatibility. Changes: - Add `JsonPropertyName` attributes to serializable model properties - Add `JsonIgnore(Condition.WhenWritingNull)` to optional properties - Explicitly specify `[JsonConverter(typeof(JsonStringEnumConverter))]` for serializable enums All serialization tests pass. Both `Newtonsoft.Json` and `System.Text.Json` attributes now coexist, enabling gradual migration. --- .../BcdeModels/ContainerDetails.cs | 9 +++++++++ .../BcdeModels/DefaultGraphScanResult.cs | 2 ++ .../BcdeModels/DependencyGraphWithMetadata.cs | 5 +++++ .../BcdeModels/DependencyScope.cs | 3 +++ .../BcdeModels/Detector.cs | 5 +++++ .../BcdeModels/DockerLayer.cs | 6 ++++++ .../BcdeModels/LayerMappedLinuxComponents.cs | 3 +++ .../BcdeModels/ScanResult.cs | 9 ++++++++- .../BcdeModels/ScannedComponent.cs | 13 ++++++++++++- .../Internal/NpmAuthor.cs | 3 +++ .../ProcessingResultCode.cs | 3 +++ .../TypedComponent/CargoComponent.cs | 15 ++++++++++++--- .../TypedComponent/ComponentType.cs | 2 ++ .../TypedComponent/ConanComponent.cs | 6 ++++++ .../TypedComponent/CondaComponent.cs | 10 ++++++++++ .../TypedComponent/DockerImageComponent.cs | 5 +++++ .../TypedComponent/DockerReferenceComponent.cs | 6 ++++++ .../TypedComponent/DotNetComponent.cs | 4 ++++ .../TypedComponent/GitComponent.cs | 4 ++++ .../TypedComponent/GoComponent.cs | 4 ++++ .../TypedComponent/LinuxComponent.cs | 7 +++++++ .../TypedComponent/MavenComponent.cs | 4 ++++ .../TypedComponent/NpmComponent.cs | 5 +++++ .../TypedComponent/NugetComponent.cs | 4 ++++ .../TypedComponent/OtherComponent.cs | 5 +++++ .../TypedComponent/PipComponent.cs | 11 +++++++++-- .../TypedComponent/PodComponent.cs | 4 ++++ .../TypedComponent/RubyGemsComponent.cs | 4 ++++ .../TypedComponent/SpdxComponent.cs | 7 +++++++ .../TypedComponent/SwiftComponent.cs | 3 +++ .../TypedComponent/TypedComponent.cs | 1 + .../TypedComponent/VcpkgComponent.cs | 8 ++++++++ .../pip/Contracts/PipInstallationMetadata.cs | 18 +++++++++++++++--- .../pip/Contracts/PipInstallationReport.cs | 5 +++++ .../pip/Contracts/PipInstallationReportItem.cs | 7 +++++++ .../pip/Contracts/PythonProjectInfo.cs | 7 +++++++ .../pip/Contracts/PythonProjectRelease.cs | 5 +++++ .../swiftpm/Contracts/SwiftResolvedFile.cs | 10 ++++++++++ .../vcpkg/Contracts/ManifestInfo.cs | 2 ++ 39 files changed, 224 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ContainerDetails.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ContainerDetails.cs index 246b5a756..ba914f94a 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ContainerDetails.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ContainerDetails.cs @@ -3,6 +3,7 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -13,33 +14,41 @@ public class ContainerDetails { // Summary: // ImageId for the docker container. + [JsonPropertyName("imageId")] public string ImageId { get; set; } // Summary: // Unique id for the container. + [JsonPropertyName("id")] public int Id { get; set; } // Summary: // Digests for the container + [JsonPropertyName("digests")] public IEnumerable Digests { get; set; } // Summary: // The Repository:Tag for the base image of the docker container // ex: alpine:latest || alpine:v3.1 || mcr.microsoft.com/dotnet/sdk:5.0 + [JsonPropertyName("baseImageRef")] public string BaseImageRef { get; set; } // Summary: // The digest of the exact image used as the base image // This is to avoid errors if there are ref updates between build time and scan time + [JsonPropertyName("baseImageDigest")] public string BaseImageDigest { get; set; } // Summary: // The time the container was created + [JsonPropertyName("createdAt")] public DateTime CreatedAt { get; set; } // Summary: // Tags for the container + [JsonPropertyName("tags")] public IEnumerable Tags { get; set; } + [JsonPropertyName("layers")] public IEnumerable Layers { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DefaultGraphScanResult.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DefaultGraphScanResult.cs index 1582d4c86..1de94cfa0 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DefaultGraphScanResult.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DefaultGraphScanResult.cs @@ -1,11 +1,13 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.BcdeModels; +using System.Text.Json.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))] public class DefaultGraphScanResult : ScanResult { + [JsonPropertyName("dependencyGraphs")] public DependencyGraphCollection DependencyGraphs { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyGraphWithMetadata.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyGraphWithMetadata.cs index ab07b020e..19df9830c 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyGraphWithMetadata.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyGraphWithMetadata.cs @@ -2,17 +2,22 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))] public class DependencyGraphWithMetadata { + [JsonPropertyName("graph")] public DependencyGraph Graph { get; set; } + [JsonPropertyName("explicitlyReferencedComponentIds")] public HashSet ExplicitlyReferencedComponentIds { get; set; } + [JsonPropertyName("developmentDependencies")] public HashSet DevelopmentDependencies { get; set; } + [JsonPropertyName("dependencies")] public HashSet Dependencies { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyScope.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyScope.cs index bbb56ab97..88624de9a 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyScope.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyScope.cs @@ -1,9 +1,12 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; +using System.Text.Json.Serialization; + /// Used to communicate Dependency Scope of Component. /// Currently only populated for Maven component. /// The values are ordered in terms of priority, which is used to resolve the scope for duplicate component while merging them. /// +[JsonConverter(typeof(JsonStringEnumConverter))] public enum DependencyScope { /// default scope. dependencies are available in the project during all build tasks. propogated to dependent projects. diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/Detector.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/Detector.cs index b48be87cc..45642e157 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/Detector.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/Detector.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; using System.Collections.Generic; +using System.Text.Json.Serialization; using Microsoft.ComponentDetection.Contracts.TypedComponent; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -10,12 +11,16 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))] public class Detector { + [JsonPropertyName("detectorId")] public string DetectorId { get; set; } + [JsonPropertyName("isExperimental")] public bool IsExperimental { get; set; } + [JsonPropertyName("version")] public int Version { get; set; } [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] + [JsonPropertyName("supportedComponentTypes")] public IEnumerable SupportedComponentTypes { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DockerLayer.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DockerLayer.cs index 068d51b90..c38aef21f 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DockerLayer.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DockerLayer.cs @@ -1,22 +1,28 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.BcdeModels; +using System.Text.Json.Serialization; + public class DockerLayer { // Summary: // the command/script that was executed in order to create the layer. + [JsonPropertyName("createdBy")] public string CreatedBy { get; set; } // Summary: // The Layer hash (docker inspect) that represents the changes between this layer and the previous layer + [JsonPropertyName("diffId")] public string DiffId { get; set; } // Summary: // Whether or not this layer was found in the base image of the container + [JsonPropertyName("isBaseImage")] public bool IsBaseImage { get; set; } // Summary: // 0-indexed monotonically increasing ID for the order of the layer in the container. // Note: only includes non-empty layers + [JsonPropertyName("layerIndex")] public int LayerIndex { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/LayerMappedLinuxComponents.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/LayerMappedLinuxComponents.cs index 06bd56e7c..c94812ddc 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/LayerMappedLinuxComponents.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/LayerMappedLinuxComponents.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; using System.Collections.Generic; +using System.Text.Json.Serialization; using Microsoft.ComponentDetection.Contracts.TypedComponent; /// @@ -14,10 +15,12 @@ public class LayerMappedLinuxComponents /// Gets or sets the components detected in this layer. /// This can include system packages (LinuxComponent) as well as application-level packages (NpmComponent, PipComponent, etc.). /// + [JsonPropertyName("components")] public IEnumerable Components { get; set; } /// /// Gets or sets the Docker layer associated with these components. /// + [JsonPropertyName("dockerLayer")] public DockerLayer DockerLayer { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs index 2fb431ff8..2aec2d833 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; @@ -9,16 +10,22 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))] public class ScanResult { + [JsonPropertyName("componentsFound")] public IEnumerable ComponentsFound { get; set; } + [JsonPropertyName("detectorsInScan")] public IEnumerable DetectorsInScan { get; set; } + [JsonPropertyName("detectorsNotInScan")] public IEnumerable DetectorsNotInScan { get; set; } + [JsonPropertyName("containerDetailsMap")] public Dictionary ContainerDetailsMap { get; set; } - [JsonConverter(typeof(StringEnumConverter))] + [Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] + [JsonPropertyName("resultCode")] public ProcessingResultCode ResultCode { get; set; } + [JsonPropertyName("sourceDirectory")] public string SourceDirectory { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScannedComponent.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScannedComponent.cs index ff208383b..2534a6326 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScannedComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScannedComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; @@ -9,24 +10,34 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels; [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))] public class ScannedComponent { + [JsonPropertyName("locationsFoundAt")] public IEnumerable LocationsFoundAt { get; set; } + [JsonPropertyName("component")] public TypedComponent.TypedComponent Component { get; set; } + [JsonPropertyName("detectorId")] public string DetectorId { get; set; } + [JsonPropertyName("isDevelopmentDependency")] public bool? IsDevelopmentDependency { get; set; } - [JsonConverter(typeof(StringEnumConverter))] + [Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] + [JsonPropertyName("dependencyScope")] public DependencyScope? DependencyScope { get; set; } + [JsonPropertyName("topLevelReferrers")] public IEnumerable TopLevelReferrers { get; set; } + [JsonPropertyName("ancestralReferrers")] public IEnumerable AncestralReferrers { get; set; } + [JsonPropertyName("containerDetailIds")] public IEnumerable ContainerDetailIds { get; set; } + [JsonPropertyName("containerLayerIds")] public IDictionary> ContainerLayerIds { get; set; } + [JsonPropertyName("targetFrameworks")] public ISet TargetFrameworks { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/Internal/NpmAuthor.cs b/src/Microsoft.ComponentDetection.Contracts/Internal/NpmAuthor.cs index 4c4d578ff..d08b766ca 100644 --- a/src/Microsoft.ComponentDetection.Contracts/Internal/NpmAuthor.cs +++ b/src/Microsoft.ComponentDetection.Contracts/Internal/NpmAuthor.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.Internal; using System; +using System.Text.Json.Serialization; public class NpmAuthor { @@ -11,7 +12,9 @@ public NpmAuthor(string name, string email = null) this.Email = string.IsNullOrEmpty(email) ? null : email; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("email")] public string Email { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Contracts/ProcessingResultCode.cs b/src/Microsoft.ComponentDetection.Contracts/ProcessingResultCode.cs index 9836d635f..3c372ee1e 100644 --- a/src/Microsoft.ComponentDetection.Contracts/ProcessingResultCode.cs +++ b/src/Microsoft.ComponentDetection.Contracts/ProcessingResultCode.cs @@ -1,6 +1,9 @@ namespace Microsoft.ComponentDetection.Contracts; +using System.Text.Json.Serialization; + /// Code used to communicate the state of a scan after completion. +[JsonConverter(typeof(JsonStringEnumConverter))] public enum ProcessingResultCode { /// The scan was completely successful. diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CargoComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CargoComponent.cs index 3137601e4..d74edc9d1 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CargoComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CargoComponent.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; using Newtonsoft.Json; using PackageUrl; @@ -20,18 +21,26 @@ public CargoComponent(string name, string version, string author = null, string this.Source = source; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } #nullable enable - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // Newtonsoft.Json + [System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] // System.Text.Json + [JsonPropertyName("author")] public string? Author { get; set; } - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // Newtonsoft.Json + [System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] // System.Text.Json + [JsonPropertyName("license")] public string? License { get; set; } - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // Newtonsoft.Json + [System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] // System.Text.Json + [JsonPropertyName("source")] public string? Source { get; set; } #nullable disable diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ComponentType.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ComponentType.cs index 31b245d59..16b88292f 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ComponentType.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ComponentType.cs @@ -1,9 +1,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System.Runtime.Serialization; +using System.Text.Json.Serialization; // This is used in BcdeModels as well [DataContract] +[JsonConverter(typeof(JsonStringEnumConverter))] public enum ComponentType : byte { [EnumMember] diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ConanComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ConanComponent.cs index a480d3eda..b3e0ff64c 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ConanComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ConanComponent.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; using PackageUrl; public class ConanComponent : TypedComponent @@ -18,14 +19,19 @@ public ConanComponent(string name, string version, string previous, string packa this.Sha1Hash = this.ValidateRequiredInput(packageId, nameof(this.Sha1Hash), nameof(ComponentType.Conan)); } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("md5Hash")] public string Md5Hash { get; set; } + [JsonPropertyName("sha1Hash")] public string Sha1Hash { get; set; } + [JsonPropertyName("packageSourceURL")] public string PackageSourceURL => $"https://conan.io/center/recipes/{this.Name}?version={this.Version}"; public override ComponentType Type => ComponentType.Conan; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CondaComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CondaComponent.cs index ec4e0dc07..df6bcdc8e 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CondaComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/CondaComponent.cs @@ -1,6 +1,8 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; + public class CondaComponent : TypedComponent { public CondaComponent(string name, string version, string build, string channel, string subdir, string @namespace, string url, string md5) @@ -20,20 +22,28 @@ private CondaComponent() /* Reserved for deserialization */ } + [JsonPropertyName("build")] public string Build { get; set; } + [JsonPropertyName("channel")] public string Channel { get; set; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("namespace")] public string Namespace { get; set; } + [JsonPropertyName("subdir")] public string Subdir { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("url")] public string Url { get; set; } + [JsonPropertyName("mD5")] public string MD5 { get; set; } public override ComponentType Type => ComponentType.Conda; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerImageComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerImageComponent.cs index e89b45428..80df152cd 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerImageComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerImageComponent.cs @@ -1,6 +1,8 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; + public class DockerImageComponent : TypedComponent { private DockerImageComponent() @@ -15,10 +17,13 @@ public DockerImageComponent(string hash, string name = null, string tag = null) this.Tag = tag; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("digest")] public string Digest { get; set; } + [JsonPropertyName("tag")] public string Tag { get; set; } public override ComponentType Type => ComponentType.DockerImage; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerReferenceComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerReferenceComponent.cs index ea76ec893..4789a7abb 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerReferenceComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerReferenceComponent.cs @@ -1,6 +1,8 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; + public class DockerReferenceComponent : TypedComponent { public DockerReferenceComponent(string hash, string repository = null, string tag = null) @@ -19,12 +21,16 @@ private DockerReferenceComponent() /* Reserved for deserialization */ } + [JsonPropertyName("repository")] public string Repository { get; set; } + [JsonPropertyName("digest")] public string Digest { get; set; } + [JsonPropertyName("tag")] public string Tag { get; set; } + [JsonPropertyName("domain")] public string Domain { get; set; } public override ComponentType Type => ComponentType.DockerReference; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DotNetComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DotNetComponent.cs index 99b49f5af..26a12d431 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DotNetComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DotNetComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System; +using System.Text.Json.Serialization; public class DotNetComponent : TypedComponent { @@ -27,16 +28,19 @@ public DotNetComponent(string sdkVersion, string targetFramework = null, string /// /// SDK Version detected, could be null if no global.json exists and no dotnet is on the path. /// + [JsonPropertyName("sdkVersion")] public string SdkVersion { get; set; } /// /// Target framework for this instance. Null in the case of global.json. /// + [JsonPropertyName("targetFramework")] public string TargetFramework { get; set; } /// /// Project type: application, library. Null in the case of global.json or if no project output could be discovered. /// + [JsonPropertyName("projectType")] public string ProjectType { get; set; } public override ComponentType Type => ComponentType.DotNet; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GitComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GitComponent.cs index 3e9b10d61..7a31d6ab4 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GitComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GitComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System; +using System.Text.Json.Serialization; public class GitComponent : TypedComponent { @@ -19,10 +20,13 @@ private GitComponent() /* Reserved for deserialization */ } + [JsonPropertyName("repositoryUrl")] public Uri RepositoryUrl { get; set; } + [JsonPropertyName("commitHash")] public string CommitHash { get; set; } + [JsonPropertyName("tag")] public string Tag { get; set; } public override ComponentType Type => ComponentType.Git; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GoComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GoComponent.cs index 749396f87..fd0080523 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GoComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GoComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System; +using System.Text.Json.Serialization; using PackageUrl; public class GoComponent : TypedComponent, IEquatable @@ -25,10 +26,13 @@ private GoComponent() /* Reserved for deserialization */ } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("hash")] public string Hash { get; set; } // Commit should be used in place of version when available diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs index 7ec336364..5622fb90e 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System; +using System.Text.Json.Serialization; using PackageUrl; public class LinuxComponent : TypedComponent @@ -21,17 +22,23 @@ public LinuxComponent(string distribution, string release, string name, string v this.Author = author; } + [JsonPropertyName("distribution")] public string Distribution { get; set; } + [JsonPropertyName("release")] public string Release { get; set; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } #nullable enable + [JsonPropertyName("license")] public string? License { get; set; } + [JsonPropertyName("author")] public string? Author { get; set; } #nullable disable diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/MavenComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/MavenComponent.cs index 0d863f2e4..d9036f43f 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/MavenComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/MavenComponent.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; using PackageUrl; public class MavenComponent : TypedComponent @@ -17,10 +18,13 @@ private MavenComponent() /* Reserved for deserialization */ } + [JsonPropertyName("groupId")] public string GroupId { get; set; } + [JsonPropertyName("artifactId")] public string ArtifactId { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } public override ComponentType Type => ComponentType.Maven; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NpmComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NpmComponent.cs index 6715d6ce4..58ecb29e4 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NpmComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NpmComponent.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; using Microsoft.ComponentDetection.Contracts.Internal; using PackageUrl; @@ -19,12 +20,16 @@ public NpmComponent(string name, string version, string hash = null, NpmAuthor a this.Author = author; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("hash")] public string Hash { get; set; } + [JsonPropertyName("author")] public NpmAuthor Author { get; set; } public override ComponentType Type => ComponentType.Npm; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NugetComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NugetComponent.cs index 9e716d391..a7b8870ec 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NugetComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NugetComponent.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; using PackageUrl; public class NuGetComponent : TypedComponent @@ -17,10 +18,13 @@ public NuGetComponent(string name, string version, string[] authors = null) this.Authors = authors; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("authors")] public string[] Authors { get; set; } public override ComponentType Type => ComponentType.NuGet; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/OtherComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/OtherComponent.cs index 68f6483c5..4eb104801 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/OtherComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/OtherComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System; +using System.Text.Json.Serialization; public class OtherComponent : TypedComponent { @@ -18,12 +19,16 @@ public OtherComponent(string name, string version, Uri downloadUrl, string hash) this.Hash = hash; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("downloadUrl")] public Uri DownloadUrl { get; set; } + [JsonPropertyName("hash")] public string Hash { get; set; } public override ComponentType Type => ComponentType.Other; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PipComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PipComponent.cs index 5858fb7c2..b7d1a14d1 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PipComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PipComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; using Newtonsoft.Json; using PackageUrl; @@ -20,15 +21,21 @@ public PipComponent(string name, string version, string author = null, string li this.License = license; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } #nullable enable - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // Newtonsoft.Json + [System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] // System.Text.Json + [JsonPropertyName("author")] public string? Author { get; set; } - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // Newtonsoft.Json + [System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] // System.Text.Json + [JsonPropertyName("license")] public string? License { get; set; } #nullable disable diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PodComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PodComponent.cs index 64ae8681e..2e1558f12 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PodComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/PodComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System.Collections.Generic; +using System.Text.Json.Serialization; using PackageUrl; public class PodComponent : TypedComponent @@ -18,10 +19,13 @@ public PodComponent(string name, string version, string specRepo = "") this.SpecRepo = specRepo; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("specRepo")] public string SpecRepo { get; set; } public override ComponentType Type => ComponentType.Pod; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/RubyGemsComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/RubyGemsComponent.cs index 1c6ce94f9..aa434b203 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/RubyGemsComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/RubyGemsComponent.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; using PackageUrl; public class RubyGemsComponent : TypedComponent @@ -17,10 +18,13 @@ public RubyGemsComponent(string name, string version, string source = "") this.Source = source; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("source")] public string Source { get; set; } public override ComponentType Type => ComponentType.RubyGems; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SpdxComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SpdxComponent.cs index 79ab31ea1..e6cf2cd79 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SpdxComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SpdxComponent.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System; +using System.Text.Json.Serialization; public class SpdxComponent : TypedComponent { @@ -22,16 +23,22 @@ public SpdxComponent(string spdxVersion, Uri documentNamespace, string name, str public override ComponentType Type => ComponentType.Spdx; + [JsonPropertyName("rootElementId")] public string RootElementId { get; set; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("spdxVersion")] public string SpdxVersion { get; set; } + [JsonPropertyName("documentNamespace")] public Uri DocumentNamespace { get; set; } + [JsonPropertyName("checksum")] public string Checksum { get; set; } + [JsonPropertyName("path")] public string Path { get; set; } protected override string ComputeId() => $"{this.Name}-{this.SpdxVersion}-{this.Checksum}"; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SwiftComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SwiftComponent.cs index dc57554fc..884293b10 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SwiftComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/SwiftComponent.cs @@ -3,6 +3,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using PackageUrl; /// @@ -30,8 +31,10 @@ public SwiftComponent(string name, string version, string packageUrl, string has this.hash = this.ValidateRequiredInput(hash, nameof(hash), nameof(ComponentType.Swift)); } + [JsonPropertyName("name")] public string Name { get; } + [JsonPropertyName("version")] public string Version { get; } public override ComponentType Type => ComponentType.Swift; diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/TypedComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/TypedComponent.cs index 69a19ec68..8f1a36174 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/TypedComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/TypedComponent.cs @@ -50,6 +50,7 @@ internal TypedComponent() /// Gets the type of the component, must be well known. [JsonConverter(typeof(StringEnumConverter))] // Newtonsoft.Json [System.Text.Json.Serialization.JsonConverter(typeof(JsonStringEnumConverter))] // System.Text.Json + [System.Text.Json.Serialization.JsonPropertyName("type")] public abstract ComponentType Type { get; } /// Gets the id of the component. diff --git a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/VcpkgComponent.cs b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/VcpkgComponent.cs index 27c6c7f11..1b1af859e 100644 --- a/src/Microsoft.ComponentDetection.Contracts/TypedComponent/VcpkgComponent.cs +++ b/src/Microsoft.ComponentDetection.Contracts/TypedComponent/VcpkgComponent.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Contracts.TypedComponent; +using System.Text.Json.Serialization; using PackageUrl; public class VcpkgComponent : TypedComponent @@ -23,18 +24,25 @@ public VcpkgComponent(string spdxid, string name, string version, string triplet this.DownloadLocation = downloadLocation; } + [JsonPropertyName("spdxid")] public string SPDXID { get; set; } + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("downloadLocation")] public string DownloadLocation { get; set; } + [JsonPropertyName("triplet")] public string Triplet { get; set; } + [JsonPropertyName("version")] public string Version { get; set; } + [JsonPropertyName("description")] public string Description { get; set; } + [JsonPropertyName("portVersion")] public int PortVersion { get; set; } public override ComponentType Type => ComponentType.Vcpkg; diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationMetadata.cs b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationMetadata.cs index 2248f5083..0c0b9bddc 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationMetadata.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationMetadata.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Detectors.Pip; +using System.Text.Json.Serialization; using Newtonsoft.Json; /// @@ -14,18 +15,21 @@ public sealed record PipInstallationMetadata /// as of May 2024. /// [JsonProperty("metadata_version")] + [JsonPropertyName("metadata_version")] public string MetadataVersion { get; set; } /// /// The name of the distribution. /// [JsonProperty("name")] + [JsonPropertyName("name")] public string Name { get; set; } /// - /// A string containing the distribution’s version number. + /// A string containing the distribution's version number. /// [JsonProperty("version")] + [JsonPropertyName("version")] public string Version { get; set; } /// @@ -33,42 +37,49 @@ public sealed record PipInstallationMetadata /// See https://peps.python.org/pep-0508/ for the format of the strings. /// [JsonProperty("requires_dist")] + [JsonPropertyName("requires_dist")] public string[] RequiresDist { get; set; } /// - /// URL for the distribution’s home page. + /// URL for the distribution's home page. /// [JsonProperty("home_page")] + [JsonPropertyName("home_page")] public string HomePage { get; set; } /// - /// Maintainer’s name at a minimum; additional contact information may be provided. + /// Maintainer's name at a minimum; additional contact information may be provided. /// [JsonProperty("maintainer")] + [JsonPropertyName("maintainer")] public string Maintainer { get; set; } /// /// Maintainer’s e-mail address. It can contain a name and e-mail address in the legal forms for a RFC-822 From: header. /// [JsonProperty("maintainer_email")] + [JsonPropertyName("maintainer_email")] public string MaintainerEmail { get; set; } /// /// Author’s name at a minimum; additional contact information may be provided. /// [JsonProperty("author")] + [JsonPropertyName("author")] public string Author { get; set; } /// /// Author’s e-mail address. It can contain a name and e-mail address in the legal forms for a RFC-822 From: header. /// [JsonProperty("author_email")] + [JsonPropertyName("author_email")] public string AuthorEmail { get; set; } /// /// Text indicating the license covering the distribution. /// [JsonProperty("license")] + [JsonPropertyName("license")] public string License { get; set; } /// @@ -76,5 +87,6 @@ public sealed record PipInstallationMetadata /// Classifiers are described in PEP 301 https://peps.python.org/pep-0301/. /// [JsonProperty("classifier")] + [JsonPropertyName("classifier")] public string[] Classifier { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReport.cs b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReport.cs index 9a1a2cc64..17bb5a232 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReport.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReport.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Detectors.Pip; using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; /// @@ -13,23 +14,27 @@ public sealed record PipInstallationReport /// Version of the installation report specification. Currently 1, but will be incremented if the format changes. /// [JsonProperty("version")] + [JsonPropertyName("version")] public string Version { get; set; } /// /// Version of pip used to produce the report. /// [JsonProperty("pip_version")] + [JsonPropertyName("pip_version")] public string PipVersion { get; set; } /// /// Distribution packages (to be) installed. /// [JsonProperty("install")] + [JsonPropertyName("install")] public PipInstallationReportItem[] InstallItems { get; set; } /// /// Environment metadata for the report. See https://peps.python.org/pep-0508/#environment-markers. /// [JsonProperty("environment")] + [JsonPropertyName("environment")] public IDictionary Environment { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReportItem.cs b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReportItem.cs index a86a2350c..a1cc4440b 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReportItem.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReportItem.cs @@ -1,6 +1,7 @@ #nullable disable namespace Microsoft.ComponentDetection.Detectors.Pip; +using System.Text.Json.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -10,18 +11,21 @@ public sealed record PipInstallationReportItem /// The metadata of the distribution. /// [JsonProperty("metadata")] + [JsonPropertyName("metadata")] public PipInstallationMetadata Metadata { get; set; } /// /// true if the requirement was provided as, or constrained to, a direct URL reference. false if the requirements was provided as a name and version specifier. /// [JsonProperty("is_direct")] + [JsonPropertyName("is_direct")] public bool IsDirect { get; set; } /// /// true if the requirement was yanked from the index, but was still selected by pip conform. /// [JsonProperty("is_yanked")] + [JsonPropertyName("is_yanked")] public bool IsYanked { get; set; } /// @@ -30,17 +34,20 @@ public sealed record PipInstallationReportItem /// was installed as a dependency of another requirement. /// [JsonProperty("requested")] + [JsonPropertyName("requested")] public bool Requested { get; set; } /// /// See https://packaging.python.org/en/latest/specifications/direct-url-data-structure/. /// [JsonProperty("download_info")] + [JsonPropertyName("download_info")] public JObject DownloadInfo { get; set; } /// /// Extras requested by the user. /// [JsonProperty("requested_extras")] + [JsonPropertyName("requested_extras")] public JArray RequestedExtras { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectInfo.cs b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectInfo.cs index ea295c18c..38a8a16b5 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectInfo.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectInfo.cs @@ -2,22 +2,29 @@ namespace Microsoft.ComponentDetection.Detectors.Pip; using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; public class PythonProjectInfo { + [JsonPropertyName("author")] public string Author { get; set; } [JsonProperty("author_email")] + [JsonPropertyName("author_email")] public string AuthorEmail { get; set; } + [JsonPropertyName("classifiers")] public List Classifiers { get; set; } + [JsonPropertyName("license")] public string License { get; set; } + [JsonPropertyName("maintainer")] public string Maintainer { get; set; } [JsonProperty("maintainer_email")] + [JsonPropertyName("maintainer_email")] public string MaintainerEmail { get; set; } // Add other properties from the "info" object as needed diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs index 9fa21f05a..75ac79781 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Detectors.Pip; using System; +using System.Text.Json.Serialization; using Newtonsoft.Json; /// @@ -9,12 +10,16 @@ namespace Microsoft.ComponentDetection.Detectors.Pip; /// public class PythonProjectRelease { + [JsonPropertyName("packageType")] public string PackageType { get; set; } [JsonProperty("python_version")] + [JsonPropertyName("python_version")] public string PythonVersion { get; set; } + [JsonPropertyName("size")] public double Size { get; set; } + [JsonPropertyName("url")] public Uri Url { get; set; } } diff --git a/src/Microsoft.ComponentDetection.Detectors/swiftpm/Contracts/SwiftResolvedFile.cs b/src/Microsoft.ComponentDetection.Detectors/swiftpm/Contracts/SwiftResolvedFile.cs index 69c3e907b..af22c2d07 100644 --- a/src/Microsoft.ComponentDetection.Detectors/swiftpm/Contracts/SwiftResolvedFile.cs +++ b/src/Microsoft.ComponentDetection.Detectors/swiftpm/Contracts/SwiftResolvedFile.cs @@ -2,6 +2,7 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; /// @@ -10,42 +11,51 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent; public class SwiftResolvedFile { [JsonProperty("pins")] + [JsonPropertyName("pins")] public IList Pins { get; set; } [JsonProperty("version")] + [JsonPropertyName("version")] public int Version { get; set; } public class SwiftDependency { // The name of the package [JsonProperty("identity")] + [JsonPropertyName("identity")] public string Identity { get; set; } // How the package is imported. Example: "remoteSourceControl" // This is not an enum because the Swift contract does not specify the possible values. [JsonProperty("kind")] + [JsonPropertyName("kind")] public string Kind { get; set; } // The unique path to the repository where the package is located. Example: Git repo URL. [JsonProperty("location")] + [JsonPropertyName("location")] public string Location { get; set; } // Data about the package version and commit hash. [JsonProperty("state")] + [JsonPropertyName("state")] public SwiftState State { get; set; } public class SwiftState { // The commit hash of the package. [JsonProperty("revision")] + [JsonPropertyName("revision")] public string Revision { get; set; } // The version of the package. Might be missing. [JsonProperty("version")] + [JsonPropertyName("version")] public string Version { get; set; } // The branch of the package. Might be missing. [JsonProperty("branch")] + [JsonPropertyName("branch")] public string Branch { get; set; } } } diff --git a/src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/ManifestInfo.cs b/src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/ManifestInfo.cs index adc0798b0..1e2be2e9f 100644 --- a/src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/ManifestInfo.cs +++ b/src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/ManifestInfo.cs @@ -1,10 +1,12 @@ #nullable disable namespace Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts; +using System.Text.Json.Serialization; using Newtonsoft.Json; public class ManifestInfo { [JsonProperty("manifest-path")] + [JsonPropertyName("manifest-path")] public string ManifestPath { get; set; } } From 1a0f4586c3c4a108db588c62e26a0cf91dc351cc Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Fri, 21 Nov 2025 19:57:44 -0800 Subject: [PATCH 2/2] Fix `JsonPropertyName` of `PackageType` property in `PythonProjectRelease` model --- .../pip/Contracts/PythonProjectRelease.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs index 75ac79781..8580e4d2b 100644 --- a/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs +++ b/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs @@ -10,7 +10,7 @@ namespace Microsoft.ComponentDetection.Detectors.Pip; /// public class PythonProjectRelease { - [JsonPropertyName("packageType")] + [JsonPropertyName("packagetype")] public string PackageType { get; set; } [JsonProperty("python_version")]