diff --git a/Directory.Packages.props b/Directory.Packages.props
index 70e1363ccef..1431be1c0d6 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -40,8 +40,7 @@
-
-
+
@@ -62,7 +61,7 @@
-
+
diff --git a/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettings.cs b/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettings.cs
index 33832329c1e..1b2b18b22cc 100644
--- a/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettings.cs
+++ b/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettings.cs
@@ -1,12 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
+
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Installer;
using Microsoft.TemplateEngine.Edge.Settings;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Edge.BuiltInManagedProvider
{
@@ -82,20 +83,20 @@ public async Task> GetInstalledTemplatePackag
var jObject = _environmentSettings.Host.FileSystem.ReadObject(_globalSettingsFile);
var packages = new List();
- foreach (var package in jObject.Get(nameof(GlobalSettingsData.Packages)) ?? new JArray())
+ foreach (var package in jObject.Get(nameof(GlobalSettingsData.Packages)) ?? new JsonArray())
{
packages.Add(new TemplatePackageData(
- package.ToGuid(nameof(TemplatePackageData.InstallerId)),
- package.Value(nameof(TemplatePackageData.MountPointUri)) ?? string.Empty,
- ((DateTime?)package[nameof(TemplatePackageData.LastChangeTime)]) ?? default,
+ package!.ToGuid(nameof(TemplatePackageData.InstallerId)),
+ package.ToString(nameof(TemplatePackageData.MountPointUri)) ?? string.Empty,
+ package![nameof(TemplatePackageData.LastChangeTime)]?.GetValue() ?? default,
package.ToStringDictionary(propertyName: nameof(TemplatePackageData.Details))));
}
return packages;
}
- catch (JsonReaderException ex)
+ catch (JsonException ex)
{
- var wrappedEx = new JsonReaderException(string.Format(LocalizableStrings.GlobalSettings_Error_CorruptedSettings, _globalSettingsFile, ex.Message), ex);
+ var wrappedEx = new JsonException(string.Format(LocalizableStrings.GlobalSettings_Error_CorruptedSettings, _globalSettingsFile, ex.Message), ex.Path, ex.LineNumber, ex.BytePositionInLine, ex);
throw wrappedEx;
}
catch (Exception)
diff --git a/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettingsData.cs b/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettingsData.cs
index 6a380483ee0..4e55c4643c0 100644
--- a/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettingsData.cs
+++ b/src/Microsoft.TemplateEngine.Edge/BuiltInManagedProvider/GlobalSettingsData.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Serialization;
using Microsoft.TemplateEngine.Abstractions.Installer;
-using Newtonsoft.Json;
namespace Microsoft.TemplateEngine.Edge.BuiltInManagedProvider
{
@@ -16,7 +16,7 @@ internal GlobalSettingsData(IReadOnlyList packages)
Packages = packages;
}
- [JsonProperty]
+ [JsonInclude]
internal IReadOnlyList Packages { get; }
}
}
diff --git a/src/Microsoft.TemplateEngine.Edge/Constraints/ConstraintsExtensions.cs b/src/Microsoft.TemplateEngine.Edge/Constraints/ConstraintsExtensions.cs
index 5f18d34b7ed..308f4813f29 100644
--- a/src/Microsoft.TemplateEngine.Edge/Constraints/ConstraintsExtensions.cs
+++ b/src/Microsoft.TemplateEngine.Edge/Constraints/ConstraintsExtensions.cs
@@ -1,8 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Edge.Constraints
{
@@ -16,23 +17,29 @@ internal static class Extensions
/// Thrown on unexpected input - not a valid json string or array of string or an empty array.
public static IEnumerable ParseArrayOfConstraintStrings(this string? args)
{
- JToken token = ParseConstraintJToken(args);
+ JsonNode token = ParseConstraintJsonNode(args);
- if (token.Type == JTokenType.String)
+ if (token.GetValueKind() == JsonValueKind.String)
{
- return new[] { token.Value() ?? throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArgumentHasEmptyString, args)) };
+ return new[] { token.GetValue() ?? throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArgumentHasEmptyString, args)) };
}
- JArray array = token.ToConstraintsJArray(args, true);
+ JsonArray array = token.ToConstraintsJsonArray(args, true);
- return array.Values().Select(value =>
+ return array.Select(value =>
{
- if (string.IsNullOrEmpty(value))
+ if (value == null || value.GetValueKind() != JsonValueKind.String)
+ {
+ throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArgumentHasEmptyString, args));
+ }
+
+ string? strValue = value.GetValue();
+ if (string.IsNullOrEmpty(strValue))
{
throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArgumentHasEmptyString, args));
}
- return value!;
+ return strValue!;
});
}
@@ -42,14 +49,14 @@ public static IEnumerable ParseArrayOfConstraintStrings(this string? arg
/// Input configuration string.
/// Enumeration of parsed JObject tokens.
/// Thrown on unexpected input - not a valid json array or an empty array.
- public static IEnumerable ParseArrayOfConstraintJObjects(this string? args)
+ public static IEnumerable ParseArrayOfConstraintJObjects(this string? args)
{
- JToken token = ParseConstraintJToken(args);
- JArray array = token.ToConstraintsJArray(args, false);
+ JsonNode token = ParseConstraintJsonNode(args);
+ JsonArray array = token.ToConstraintsJsonArray(args, false);
return array.Select(value =>
{
- if (value is not JObject jObj)
+ if (value is not JsonObject jObj)
{
throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_InvalidJsonArray_Objects, args));
}
@@ -103,29 +110,29 @@ public static IVersionSpecification ParseVersionSpecification(this string versio
return versionInstance;
}
- private static JToken ParseConstraintJToken(this string? args)
+ private static JsonNode ParseConstraintJsonNode(this string? args)
{
if (string.IsNullOrWhiteSpace(args))
{
throw new ConfigurationException(LocalizableStrings.Constraint_Error_ArgumentsNotSpecified);
}
- JToken? token;
+ JsonNode? token;
try
{
- token = JToken.Parse(args!);
+ token = JsonNode.Parse(args!);
}
catch (Exception e)
{
throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_InvalidJson, args), e);
}
- return token;
+ return token ?? throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_InvalidJson, args));
}
- private static JArray ToConstraintsJArray(this JToken token, string? args, bool isStringTypeAllowed)
+ private static JsonArray ToConstraintsJsonArray(this JsonNode token, string? args, bool isStringTypeAllowed)
{
- if (token is not JArray array)
+ if (token is not JsonArray array)
{
throw new ConfigurationException(string.Format(
isStringTypeAllowed
diff --git a/src/Microsoft.TemplateEngine.Edge/Constraints/HostConstraint.cs b/src/Microsoft.TemplateEngine.Edge/Constraints/HostConstraint.cs
index 29741375b44..bdbfb6ea106 100644
--- a/src/Microsoft.TemplateEngine.Edge/Constraints/HostConstraint.cs
+++ b/src/Microsoft.TemplateEngine.Edge/Constraints/HostConstraint.cs
@@ -1,10 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Edge.Constraints
{
@@ -71,7 +71,7 @@ private static IEnumerable ParseArgs(string? args)
{
List hostInformation = new List();
- foreach (JObject jObj in args.ParseArrayOfConstraintJObjects())
+ foreach (JsonObject jObj in args.ParseArrayOfConstraintJObjects())
{
string? hostName = jObj.ToString("hostname");
string? version = jObj.ToString("version");
diff --git a/src/Microsoft.TemplateEngine.Edge/Microsoft.TemplateEngine.Edge.csproj b/src/Microsoft.TemplateEngine.Edge/Microsoft.TemplateEngine.Edge.csproj
index 81945e88fe2..07475cbce22 100644
--- a/src/Microsoft.TemplateEngine.Edge/Microsoft.TemplateEngine.Edge.csproj
+++ b/src/Microsoft.TemplateEngine.Edge/Microsoft.TemplateEngine.Edge.csproj
@@ -28,7 +28,7 @@
-
+
diff --git a/src/Microsoft.TemplateEngine.Edge/Settings/SettingsStore.cs b/src/Microsoft.TemplateEngine.Edge/Settings/SettingsStore.cs
index dd203f47cd8..688f8d3de9f 100644
--- a/src/Microsoft.TemplateEngine.Edge/Settings/SettingsStore.cs
+++ b/src/Microsoft.TemplateEngine.Edge/Settings/SettingsStore.cs
@@ -1,66 +1,67 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Edge.Settings
{
internal class SettingsStore
{
- internal SettingsStore(JObject? obj)
+ internal SettingsStore(JsonObject? obj)
{
if (obj == null)
{
return;
}
- if (obj.TryGetValue(nameof(ComponentGuidToAssemblyQualifiedName), StringComparison.OrdinalIgnoreCase, out JToken? componentGuidToAssemblyQualifiedNameToken))
+ if (obj.TryGetValueCaseInsensitive(nameof(ComponentGuidToAssemblyQualifiedName), out JsonNode? componentGuidToAssemblyQualifiedNameToken))
{
- if (componentGuidToAssemblyQualifiedNameToken is JObject componentGuidToAssemblyQualifiedNameObject)
+ if (componentGuidToAssemblyQualifiedNameToken is JsonObject componentGuidToAssemblyQualifiedNameObject)
{
- foreach (JProperty entry in componentGuidToAssemblyQualifiedNameObject.Properties())
+ foreach (var entry in componentGuidToAssemblyQualifiedNameObject)
{
- if (entry.Value is { Type: JTokenType.String })
+ if (entry.Value?.GetValueKind() == JsonValueKind.String)
{
- ComponentGuidToAssemblyQualifiedName[entry.Name] = entry.Value.ToString();
+ ComponentGuidToAssemblyQualifiedName[entry.Key] = entry.Value.GetValue();
}
}
}
}
- if (obj.TryGetValue(nameof(ProbingPaths), StringComparison.OrdinalIgnoreCase, out JToken? probingPathsToken))
+ if (obj.TryGetValueCaseInsensitive(nameof(ProbingPaths), out JsonNode? probingPathsToken))
{
- if (probingPathsToken is JArray probingPathsArray)
+ if (probingPathsToken is JsonArray probingPathsArray)
{
- foreach (JToken path in probingPathsArray)
+ foreach (JsonNode? path in probingPathsArray)
{
- if (path is { Type: JTokenType.String })
+ if (path?.GetValueKind() == JsonValueKind.String)
{
- ProbingPaths.Add(path.ToString());
+ ProbingPaths.Add(path.GetValue());
}
}
}
}
- if (obj.TryGetValue(nameof(ComponentTypeToGuidList), StringComparison.OrdinalIgnoreCase, out JToken? componentTypeToGuidListToken))
+ if (obj.TryGetValueCaseInsensitive(nameof(ComponentTypeToGuidList), out JsonNode? componentTypeToGuidListToken))
{
- if (componentTypeToGuidListToken is JObject componentTypeToGuidListObject)
+ if (componentTypeToGuidListToken is JsonObject componentTypeToGuidListObject)
{
- foreach (JProperty entry in componentTypeToGuidListObject.Properties())
+ foreach (var entry in componentTypeToGuidListObject)
{
- if (entry.Value is JArray values)
+ if (entry.Value is JsonArray values)
{
HashSet set = new HashSet();
- ComponentTypeToGuidList[entry.Name] = set;
+ ComponentTypeToGuidList[entry.Key] = set;
- foreach (JToken value in values)
+ foreach (JsonNode? value in values)
{
- if (value is { Type: JTokenType.String })
+ if (value?.GetValueKind() == JsonValueKind.String)
{
- if (Guid.TryParse(value.ToString(), out Guid id))
+ if (Guid.TryParse(value.GetValue(), out Guid id))
{
set.Add(id);
}
@@ -72,13 +73,13 @@ internal SettingsStore(JObject? obj)
}
}
- [JsonProperty]
+ [JsonInclude]
internal Dictionary ComponentGuidToAssemblyQualifiedName { get; } = new();
- [JsonProperty]
+ [JsonInclude]
internal HashSet ProbingPaths { get; } = new();
- [JsonProperty]
+ [JsonInclude]
internal Dictionary> ComponentTypeToGuidList { get; } = new();
internal static SettingsStore Load(IEngineEnvironmentSettings engineEnvironmentSettings, SettingsFilePaths paths)
@@ -88,7 +89,7 @@ internal static SettingsStore Load(IEngineEnvironmentSettings engineEnvironmentS
return new SettingsStore(null);
}
- JObject parsed;
+ JsonObject parsed;
using (Timing.Over(engineEnvironmentSettings.Host.Logger, "Parse settings"))
{
try
diff --git a/src/Microsoft.TemplateEngine.Edge/Settings/TemplateCache.cs b/src/Microsoft.TemplateEngine.Edge/Settings/TemplateCache.cs
index 92462ca29f8..39cde883ea5 100644
--- a/src/Microsoft.TemplateEngine.Edge/Settings/TemplateCache.cs
+++ b/src/Microsoft.TemplateEngine.Edge/Settings/TemplateCache.cs
@@ -3,13 +3,13 @@
using System.Globalization;
using System.Text;
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Abstractions.TemplatePackage;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Edge.Settings
{
@@ -58,7 +58,7 @@ public TemplateCache(IReadOnlyList allTemplatePackages, ScanRe
(IScanTemplateInfo Template, ITemplatePackage TemplatePackage, ILocalizationLocator? Localization, IMountPoint MountPoint) chosenTemplate = duplicatedIdentities.Value.Last();
ILocalizationLocator? loc = GetBestLocalizationLocatorMatch(chosenTemplate.Template);
- (string, JObject?)? hostFile = GetBestHostConfigMatch(chosenTemplate.Template, environmentSettings, chosenTemplate.MountPoint);
+ (string, JsonObject?)? hostFile = GetBestHostConfigMatch(chosenTemplate.Template, environmentSettings, chosenTemplate.MountPoint);
templates.Add(new TemplateInfo(chosenTemplate.Template, loc, hostFile));
}
@@ -71,11 +71,11 @@ public TemplateCache(IReadOnlyList allTemplatePackages, ScanRe
PrintOverlappingIdentityWarning(logger, templateDeduplicationDictionary);
}
- public TemplateCache(JObject? contentJObject)
+ public TemplateCache(JsonObject? contentJObject)
{
- if (contentJObject != null && contentJObject.TryGetValue(nameof(Version), StringComparison.OrdinalIgnoreCase, out JToken? versionToken))
+ if (contentJObject != null && contentJObject.TryGetValueCaseInsensitive(nameof(Version), out JsonNode? versionToken))
{
- Version = versionToken.ToString();
+ Version = versionToken!.ToJsonString().Trim('"');
}
else
{
@@ -86,17 +86,20 @@ public TemplateCache(JObject? contentJObject)
return;
}
- Locale = contentJObject.TryGetValue(nameof(Locale), StringComparison.OrdinalIgnoreCase, out JToken? localeToken)
- ? localeToken.ToString()
+ Locale = contentJObject.TryGetValueCaseInsensitive(nameof(Locale), out JsonNode? localeToken)
+ ? localeToken!.GetValue()
: string.Empty;
var mountPointInfo = new Dictionary();
- if (contentJObject.TryGetValue(nameof(MountPointsInfo), StringComparison.OrdinalIgnoreCase, out JToken? mountPointInfoToken) && mountPointInfoToken is IDictionary dict)
+ if (contentJObject.TryGetValueCaseInsensitive(nameof(MountPointsInfo), out JsonNode? mountPointInfoToken) && mountPointInfoToken is JsonObject mountPointInfoObj)
{
- foreach (var entry in dict)
+ foreach (var entry in mountPointInfoObj)
{
- mountPointInfo.Add(entry.Key, entry.Value.Value());
+ if (entry.Value != null)
+ {
+ mountPointInfo.Add(entry.Key, entry.Value.GetValue());
+ }
}
}
@@ -104,13 +107,13 @@ public TemplateCache(JObject? contentJObject)
List templateList = new List();
- if (contentJObject.TryGetValue(nameof(TemplateInfo), StringComparison.OrdinalIgnoreCase, out JToken? templateInfoToken) && templateInfoToken is JArray arr)
+ if (contentJObject.TryGetValueCaseInsensitive(nameof(TemplateInfo), out JsonNode? templateInfoToken) && templateInfoToken is JsonArray arr)
{
- foreach (JToken entry in arr)
+ foreach (JsonNode? entry in arr)
{
- if (entry != null && entry.Type == JTokenType.Object)
+ if (entry is JsonObject entryObj)
{
- templateList.Add(Settings.TemplateInfo.FromJObject((JObject)entry));
+ templateList.Add(Settings.TemplateInfo.FromJObject(entryObj));
}
}
}
@@ -118,16 +121,16 @@ public TemplateCache(JObject? contentJObject)
TemplateInfo = templateList;
}
- [JsonProperty]
+ [JsonPropertyName("Version")]
public string? Version { get; }
- [JsonProperty]
+ [JsonPropertyName("Locale")]
public string Locale { get; }
- [JsonProperty]
+ [JsonPropertyName("TemplateInfo")]
public IReadOnlyList TemplateInfo { get; }
- [JsonProperty]
+ [JsonPropertyName("MountPointsInfo")]
public Dictionary MountPointsInfo { get; }
private ILocalizationLocator? GetBestLocalizationLocatorMatch(IScanTemplateInfo template)
@@ -195,7 +198,7 @@ private void PrintOverlappingIdentityWarning(ILogger logger, IDictionary shortNam
/// unlocalized template.
/// localization information.
/// host config information.
- internal TemplateInfo(IScanTemplateInfo template, ILocalizationLocator? localizationInfo, (string Path, JObject? Content)? hostConfig)
+ internal TemplateInfo(IScanTemplateInfo template, ILocalizationLocator? localizationInfo, (string Path, JsonObject? Content)? hostConfig)
{
if (template is null)
{
@@ -97,11 +97,11 @@ internal TemplateInfo(IScanTemplateInfo template, ILocalizationLocator? localiza
Name = localizationInfo?.Name ?? template.Name;
ParameterDefinitions = LocalizeParameters(template, localizationInfo);
- HostData = hostConfig?.Content?.ToString(Formatting.None);
+ HostData = hostConfig?.Content?.ToJsonString();
}
#pragma warning disable CS0618 // Type or member is obsolete
- [JsonProperty(nameof(Parameters))]
+ [JsonPropertyName("Parameters")]
#pragma warning restore CS0618 // Type or member is obsolete
public IParameterDefinitionSet ParameterDefinitions { get; private set; } = ParameterDefinitionSet.Empty;
@@ -109,34 +109,34 @@ internal TemplateInfo(IScanTemplateInfo template, ILocalizationLocator? localiza
[Obsolete("Use ParameterDefinitionSet instead.")]
public IReadOnlyList Parameters => ParameterDefinitions;
- [JsonProperty]
+ [JsonPropertyName("MountPointUri")]
public string MountPointUri { get; }
- [JsonProperty]
+ [JsonPropertyName("Author")]
public string? Author { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("Classifications")]
public IReadOnlyList Classifications { get; private set; } = new List();
- [JsonProperty]
+ [JsonPropertyName("DefaultName")]
public string? DefaultName { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("Description")]
public string? Description { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("Identity")]
public string Identity { get; }
- [JsonProperty]
+ [JsonPropertyName("GeneratorId")]
public Guid GeneratorId { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("GroupIdentity")]
public string? GroupIdentity { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("Precedence")]
public int Precedence { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("Name")]
public string Name { get; }
[JsonIgnore]
@@ -156,7 +156,7 @@ string ITemplateInfo.ShortName
public IReadOnlyList ShortNameList { get; } = new List();
- [JsonProperty]
+ [JsonPropertyName("PreferDefaultName")]
public bool PreferDefaultName { get; private set; }
[JsonIgnore]
@@ -210,22 +210,22 @@ IReadOnlyDictionary ITemplateInfo.CacheParameters
}
}
- [JsonProperty]
+ [JsonPropertyName("ConfigPlace")]
public string ConfigPlace { get; }
- [JsonProperty]
+ [JsonPropertyName("LocaleConfigPlace")]
public string? LocaleConfigPlace { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("HostConfigPlace")]
public string? HostConfigPlace { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("ThirdPartyNotices")]
public string? ThirdPartyNotices { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("BaselineInfo")]
public IReadOnlyDictionary BaselineInfo { get; private set; } = new Dictionary();
- [JsonProperty]
+ [JsonPropertyName("TagsCollection")]
public IReadOnlyDictionary TagsCollection { get; private set; } = new Dictionary();
[JsonIgnore]
@@ -233,13 +233,13 @@ IReadOnlyDictionary ITemplateInfo.CacheParameters
public string? HostData { get; private set; }
- [JsonProperty]
+ [JsonPropertyName("PostActions")]
public IReadOnlyList PostActions { get; private set; } = [];
- [JsonProperty]
+ [JsonPropertyName("Constraints")]
public IReadOnlyList Constraints { get; private set; } = [];
- public static TemplateInfo FromJObject(JObject entry)
+ public static TemplateInfo FromJObject(JsonObject entry)
{
return TemplateInfoReader.FromJObject(entry);
}
diff --git a/src/Microsoft.TemplateEngine.Edge/Settings/TemplateInfoReader.cs b/src/Microsoft.TemplateEngine.Edge/Settings/TemplateInfoReader.cs
index 264fde02f44..60a2e2b1436 100644
--- a/src/Microsoft.TemplateEngine.Edge/Settings/TemplateInfoReader.cs
+++ b/src/Microsoft.TemplateEngine.Edge/Settings/TemplateInfoReader.cs
@@ -1,12 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Abstractions.Parameters;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Edge.Settings
{
@@ -14,26 +14,29 @@ internal partial class TemplateInfo
{
internal class TemplateInfoReader
{
- internal static TemplateInfo FromJObject(JObject entry)
+ internal static TemplateInfo FromJObject(JsonObject entry)
{
string identity = entry.ToString(nameof(Identity)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(Identity)} property.", nameof(entry));
string name = entry.ToString(nameof(Name)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(Name)} property.", nameof(entry));
string mountPointUri = entry.ToString(nameof(MountPointUri)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(MountPointUri)} property.", nameof(entry));
string configPlace = entry.ToString(nameof(ConfigPlace)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(ConfigPlace)} property.", nameof(entry));
- JToken? shortNameToken = entry.Get(nameof(ShortNameList));
+ JsonNode? shortNameToken = entry.Get(nameof(ShortNameList));
IEnumerable shortNames = shortNameToken.JTokenStringOrArrayToCollection([]);
TemplateInfo info = new TemplateInfo(identity, name, shortNames, mountPointUri, configPlace)
{
Author = entry.ToString(nameof(Author))
};
- JArray? classificationsArray = entry.Get(nameof(Classifications));
+ JsonArray? classificationsArray = entry.Get(nameof(Classifications));
if (classificationsArray != null)
{
List classifications = new List();
- foreach (JToken item in classificationsArray)
+ foreach (JsonNode? item in classificationsArray)
{
- classifications.Add(item.ToString());
+ if (item != null)
+ {
+ classifications.Add(item.GetValue());
+ }
}
info.Classifications = classifications;
}
@@ -49,34 +52,34 @@ internal static TemplateInfo FromJObject(JObject entry)
info.HostConfigPlace = entry.ToString(nameof(HostConfigPlace));
info.ThirdPartyNotices = entry.ToString(nameof(ThirdPartyNotices));
- JObject? baselineJObject = entry.Get(nameof(ITemplateInfo.BaselineInfo));
+ JsonObject? baselineJObject = entry.Get(nameof(ITemplateInfo.BaselineInfo));
Dictionary baselineInfo = new Dictionary();
if (baselineJObject != null)
{
- foreach (JProperty item in baselineJObject.Properties())
+ foreach (var item in baselineJObject)
{
- var defaultOverrides = item.Value.ToStringDictionary(propertyName: nameof(IBaselineInfo.DefaultOverrides));
+ var defaultOverrides = item.Value?.ToStringDictionary(propertyName: nameof(IBaselineInfo.DefaultOverrides));
if (defaultOverrides is null)
{
continue;
}
IBaselineInfo baseline = new BaselineInfo(defaultOverrides, item.Value.ToString(nameof(IBaselineInfo.Description)));
- baselineInfo.Add(item.Name, baseline);
+ baselineInfo.Add(item.Key, baseline);
}
info.BaselineInfo = baselineInfo;
}
//read parameters
#pragma warning disable CS0618 // Type or member is obsolete
- JArray? parametersArray = entry.Get(nameof(Parameters));
+ JsonArray? parametersArray = entry.Get(nameof(Parameters));
#pragma warning restore CS0618 // Type or member is obsolete
if (parametersArray != null)
{
List templateParameters = new List();
- foreach (JToken item in parametersArray)
+ foreach (JsonNode? item in parametersArray)
{
- if (item is JObject jObj)
+ if (item is JsonObject jObj)
{
templateParameters.Add(ParameterFromJObject(jObj));
}
@@ -87,25 +90,25 @@ internal static TemplateInfo FromJObject(JObject entry)
//read tags
// tags are just "name": "description"
// e.g.: "language": "C#"
- JObject? tagsObject = entry.Get(nameof(TagsCollection));
+ JsonObject? tagsObject = entry.Get(nameof(TagsCollection));
if (tagsObject != null)
{
Dictionary tags = new Dictionary();
- foreach (JProperty item in tagsObject.Properties())
+ foreach (var item in tagsObject)
{
- tags.Add(item.Name.ToString(), item.Value.ToString());
+ tags.Add(item.Key, item.Value?.GetValue() ?? string.Empty);
}
info.TagsCollection = tags;
}
info.HostData = entry.ToString(nameof(info.HostData));
- JArray? postActionsArray = entry.Get(nameof(info.PostActions));
+ JsonArray? postActionsArray = entry.Get(nameof(info.PostActions));
if (postActionsArray != null)
{
List postActions = new List();
- foreach (JToken item in postActionsArray)
+ foreach (JsonNode? item in postActionsArray)
{
- if (Guid.TryParse(item.ToString(), out Guid id))
+ if (item != null && Guid.TryParse(item.GetValue(), out Guid id))
{
postActions.Add(id);
}
@@ -114,11 +117,11 @@ internal static TemplateInfo FromJObject(JObject entry)
}
//read parameters
- JArray? constraintsArray = entry.Get(nameof(info.Constraints));
+ JsonArray? constraintsArray = entry.Get(nameof(info.Constraints));
if (constraintsArray != null)
{
List constraints = new List();
- foreach (JToken item in constraintsArray)
+ foreach (JsonNode? item in constraintsArray)
{
string? type = item.ToString(nameof(TemplateConstraintInfo.Type));
if (string.IsNullOrWhiteSpace(type))
@@ -134,10 +137,10 @@ internal static TemplateInfo FromJObject(JObject entry)
}
///
- /// Parses from .
+ /// Parses from .
///
///
- private static ITemplateParameter ParameterFromJObject(JObject jObject)
+ private static ITemplateParameter ParameterFromJObject(JsonObject jObject)
{
string? name = jObject.ToString(nameof(ITemplateParameter.Name));
if (string.IsNullOrWhiteSpace(name))
@@ -160,13 +163,13 @@ private static ITemplateParameter ParameterFromJObject(JObject jObject)
if (dataType.Equals("choice", StringComparison.OrdinalIgnoreCase))
{
choices = new Dictionary(StringComparer.OrdinalIgnoreCase);
- JObject? cdToken = jObject.Get(nameof(ITemplateParameter.Choices));
+ JsonObject? cdToken = jObject.Get(nameof(ITemplateParameter.Choices));
if (cdToken != null)
{
- foreach (JProperty cdPair in cdToken.Properties())
+ foreach (var cdPair in cdToken)
{
choices.Add(
- cdPair.Name.ToString(),
+ cdPair.Key,
new ParameterChoice(
cdPair.Value.ToString(nameof(ParameterChoice.DisplayName)),
cdPair.Value.ToString(nameof(ParameterChoice.Description))));
@@ -205,34 +208,34 @@ internal CacheTemplateParameter(ITemplateParameter parameter)
public string? Description => _parameter.Description;
- [JsonProperty]
+ [JsonPropertyName("Name")]
public string Name => _parameter.Name;
- [JsonProperty]
+ [JsonPropertyName("Precedence")]
public TemplateParameterPrecedence Precedence => _parameter.Precedence;
- [JsonProperty]
+ [JsonPropertyName("Type")]
public string Type => _parameter.Type;
- [JsonProperty]
+ [JsonPropertyName("IsName")]
public bool IsName => _parameter.IsName;
- [JsonProperty]
+ [JsonPropertyName("DefaultValue")]
public string? DefaultValue => _parameter.DefaultValue;
- [JsonProperty]
+ [JsonPropertyName("DefaultIfOptionWithoutValue")]
public string? DefaultIfOptionWithoutValue => _parameter.DefaultIfOptionWithoutValue;
- [JsonProperty]
+ [JsonPropertyName("DataType")]
public string DataType => _parameter.DataType;
- [JsonProperty]
+ [JsonPropertyName("Choices")]
public IReadOnlyDictionary? Choices => _parameter.Choices;
- [JsonProperty]
+ [JsonPropertyName("DisplayName")]
public string? DisplayName => _parameter.DisplayName;
- [JsonProperty]
+ [JsonPropertyName("AllowMultipleValues")]
public bool AllowMultipleValues => _parameter.AllowMultipleValues;
[Obsolete]
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseReplaceSymbol.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseReplaceSymbol.cs
index 7f45f022b56..3556d35f850 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseReplaceSymbol.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseReplaceSymbol.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -20,7 +20,7 @@ private protected BaseReplaceSymbol(BaseReplaceSymbol clone) : base(clone)
ReplacementContexts = clone.ReplacementContexts;
}
- private protected BaseReplaceSymbol(JObject jObject, string name) : base(name)
+ private protected BaseReplaceSymbol(JsonObject jObject, string name) : base(name)
{
FileRename = jObject.ToString(nameof(FileRename));
Replaces = jObject.ToString(nameof(Replaces));
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseValueSymbol.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseValueSymbol.cs
index 666889bd586..a3a2b0cc7b5 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseValueSymbol.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BaseValueSymbol.cs
@@ -1,7 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -14,12 +15,12 @@ public abstract class BaseValueSymbol : BaseReplaceSymbol
///
///
///
- private protected BaseValueSymbol(string name, JObject jObject, string? defaultOverride, bool symbolConditionsSupported = false) : base(jObject, name)
+ private protected BaseValueSymbol(string name, JsonObject jObject, string? defaultOverride, bool symbolConditionsSupported = false) : base(jObject, name)
{
DefaultValue = defaultOverride ?? jObject.ToString(nameof(DefaultValue));
IsRequired = ParseIsRequiredField(jObject, !symbolConditionsSupported);
DataType = jObject.ToString(nameof(DataType));
- if (!jObject.TryGetValue(nameof(Forms), StringComparison.OrdinalIgnoreCase, out JToken? formsToken) || formsToken is not JObject formsObject)
+ if (!jObject.TryGetValue(nameof(Forms), out JsonNode? formsToken) || formsToken is not JsonObject formsObject)
{
// no value forms explicitly defined, use the default ("identity")
Forms = SymbolValueFormsModel.Default;
@@ -68,17 +69,18 @@ private protected BaseValueSymbol(string name, string? replaces) : base(name, re
///
public string? DataType { get; internal init; }
- private protected bool TryGetIsRequiredField(JToken token, out bool result)
+ private protected bool TryGetIsRequiredField(JsonNode token, out bool result)
{
result = false;
- return (token.Type == JTokenType.Boolean || token.Type == JTokenType.String)
+ var kind = token.GetValueKind();
+ return (kind is JsonValueKind.True or JsonValueKind.False || kind == JsonValueKind.String)
&&
bool.TryParse(token.ToString(), out result);
}
- private bool ParseIsRequiredField(JToken token, bool throwOnError)
+ private bool ParseIsRequiredField(JsonNode token, bool throwOnError)
{
- if (!token.TryGetValue(nameof(IsRequired), out JToken? isRequiredToken))
+ if (!token.TryGetValue(nameof(IsRequired), out JsonNode? isRequiredToken))
{
return false;
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BindSymbol.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BindSymbol.cs
index 880a43d702d..49f8ba92270 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BindSymbol.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/BindSymbol.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -23,7 +23,7 @@ internal BindSymbol(string name, string binding) : base(name, null)
Binding = binding;
}
- internal BindSymbol(string name, JObject jObject) : base(jObject, name)
+ internal BindSymbol(string name, JsonObject jObject) : base(jObject, name)
{
string? binding = jObject.ToString(nameof(Binding));
if (string.IsNullOrWhiteSpace(binding))
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ComputedSymbol.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ComputedSymbol.cs
index a05df4586f9..59b326f0f6f 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ComputedSymbol.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ComputedSymbol.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -23,7 +23,7 @@ internal ComputedSymbol(string name, string value) : base(name)
Value = value;
}
- internal ComputedSymbol(string name, JObject jObject) : base(name)
+ internal ComputedSymbol(string name, JsonObject jObject) : base(name)
{
string? value = jObject.ToString(nameof(Value));
if (string.IsNullOrWhiteSpace(value))
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomFileGlobModel.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomFileGlobModel.cs
index 91afdfb31bf..002cf601284 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomFileGlobModel.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomFileGlobModel.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Core.Contracts;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -37,15 +37,15 @@ internal CustomFileGlobModel(string glob, IReadOnlyList op
///
internal IVariableConfig VariableFormat { get; } = VariableConfig.Default;
- internal static CustomFileGlobModel FromJObject(JObject globData, string globName)
+ internal static CustomFileGlobModel FromJObject(JsonObject globData, string globName)
{
// setup the custom operations
List customOpsForGlob = new List();
- if (globData.TryGetValue(nameof(Operations), StringComparison.OrdinalIgnoreCase, out JToken? operationData))
+ if (globData.TryGetValue(nameof(Operations), out JsonNode? operationData))
{
- foreach (JToken operationConfig in (JArray)operationData)
+ foreach (JsonNode? operationConfig in (JsonArray)operationData!)
{
- if (operationConfig is JObject obj)
+ if (operationConfig is JsonObject obj)
{
customOpsForGlob.Add(CustomOperationModel.FromJObject(obj));
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomOperationModel.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomOperationModel.cs
index 3ed1547ef8c..6fe8f87c4b9 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomOperationModel.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/CustomOperationModel.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -22,13 +22,13 @@ internal CustomOperationModel() { }
///
public string? Configuration { get; internal init; }
- internal static CustomOperationModel FromJObject(JObject jObject)
+ internal static CustomOperationModel FromJObject(JsonObject jObject)
{
CustomOperationModel model = new CustomOperationModel
{
Type = jObject.ToString(nameof(Type)),
Condition = jObject.ToString(nameof(Condition)),
- Configuration = jObject.Get(nameof(Configuration))?.ToString(),
+ Configuration = jObject.Get(nameof(Configuration))?.ToJsonString(),
};
return model;
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/DerivedSymbol.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/DerivedSymbol.cs
index 09d9e7d4381..31c3bcd4683 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/DerivedSymbol.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/DerivedSymbol.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -29,7 +29,7 @@ internal DerivedSymbol(string name, string valueTransform, string valueSource, s
ValueSource = valueSource;
}
- internal DerivedSymbol(string name, JObject jObject, string? defaultOverride)
+ internal DerivedSymbol(string name, JsonObject jObject, string? defaultOverride)
: base(name, jObject, defaultOverride)
{
string? valueTransform = jObject.ToString(nameof(ValueTransform));
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ExtendedFileSource.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ExtendedFileSource.cs
index b48dd82470b..7c80e482031 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ExtendedFileSource.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ExtendedFileSource.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -54,7 +54,7 @@ internal ExtendedFileSource() { }
///
public IReadOnlyList Modifiers { get; internal init; } = [];
- internal static ExtendedFileSource FromJObject(JObject jObject)
+ internal static ExtendedFileSource FromJObject(JsonObject jObject)
{
List modifiers = new List();
ExtendedFileSource src = new ExtendedFileSource()
@@ -63,13 +63,13 @@ internal static ExtendedFileSource FromJObject(JObject jObject)
Exclude = jObject.ToStringReadOnlyList(nameof(Exclude)),
Include = jObject.ToStringReadOnlyList(nameof(Include)),
Condition = jObject.ToString(nameof(Condition)),
- Rename = jObject.Get(nameof(Rename))?.ToStringDictionary().ToDictionary(x => x.Key, x => x.Value) ?? RenameDefaults,
+ Rename = jObject.Get(nameof(Rename))?.ToStringDictionary().ToDictionary(x => x.Key, x => x.Value) ?? RenameDefaults,
Modifiers = modifiers,
Source = jObject.ToString(nameof(Source)) ?? "./",
Target = jObject.ToString(nameof(Target)) ?? "./"
};
- foreach (JObject entry in jObject.Items(nameof(src.Modifiers)))
+ foreach (JsonObject entry in jObject.Items(nameof(src.Modifiers)))
{
SourceModifier modifier = new SourceModifier
{
@@ -77,7 +77,7 @@ internal static ExtendedFileSource FromJObject(JObject jObject)
CopyOnly = entry.ToStringReadOnlyList(nameof(CopyOnly)),
Exclude = entry.ToStringReadOnlyList(nameof(Exclude)),
Include = entry.ToStringReadOnlyList(nameof(Include)),
- Rename = entry.Get(nameof(Rename))?.ToStringDictionary().ToDictionary(x => x.Key, x => x.Value) ?? RenameDefaults,
+ Rename = entry.Get(nameof(Rename))?.ToStringDictionary().ToDictionary(x => x.Key, x => x.Value) ?? RenameDefaults,
};
modifiers.Add(modifier);
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/GeneratedSymbol.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/GeneratedSymbol.cs
index 291621f5638..d6ab5bd2e59 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/GeneratedSymbol.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/GeneratedSymbol.cs
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -29,7 +29,7 @@ internal GeneratedSymbol(string name, string generator, IReadOnlyDictionary
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ParameterSymbol.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ParameterSymbol.cs
index 4127cec846a..153ebdd936c 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ParameterSymbol.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ParameterSymbol.cs
@@ -1,9 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -25,7 +26,7 @@ public sealed class ParameterSymbol : BaseValueSymbol
///
/// JSON to initialize the symbol with.
///
- internal ParameterSymbol(string name, JObject jObject, string? defaultOverride)
+ internal ParameterSymbol(string name, JsonObject jObject, string? defaultOverride)
: base(name, jObject, defaultOverride, true)
{
DefaultIfOptionWithoutValue = jObject.ToString(nameof(DefaultIfOptionWithoutValue));
@@ -38,7 +39,7 @@ internal ParameterSymbol(string name, JObject jObject, string? defaultOverride)
{
TagName = jObject.ToString(nameof(TagName));
- foreach (JObject choiceObject in jObject.Items(nameof(Choices)))
+ foreach (JsonObject choiceObject in jObject.Items(nameof(Choices)))
{
string? choiceName = choiceObject.ToString("choice");
@@ -187,20 +188,20 @@ internal void Localize(IParameterSymbolLocalizationModel locModel)
}
- private static TemplateParameterPrecedence GetPrecedence(bool isRequired, JObject jObject)
+ private static TemplateParameterPrecedence GetPrecedence(bool isRequired, JsonObject jObject)
{
string? isRequiredCondition = ParseIsRequiredConditionField(jObject);
// Initialize IsEnabled - as a condition or a constant
string? isEnabledCondition = null;
bool isEnabled = true;
- if (jObject != null && jObject.TryGetValue("IsEnabled", StringComparison.OrdinalIgnoreCase, out JToken? isEnabledToken))
+ if (jObject != null && jObject.TryGetValue("IsEnabled", out JsonNode? isEnabledToken))
{
if (isEnabledToken!.TryParseBool(out bool enabledConst))
{
isEnabled = enabledConst;
}
- else if (isEnabledToken.Type == JTokenType.String)
+ else if (isEnabledToken!.GetValueKind() == JsonValueKind.String)
{
isEnabledCondition = isEnabledToken.ToString();
}
@@ -242,9 +243,9 @@ private static TemplateParameterPrecedence GetPrecedence(bool isRequired, bool i
return TemplateParameterPrecedence.Default;
}
- private static string? ParseIsRequiredConditionField(JToken token)
+ private static string? ParseIsRequiredConditionField(JsonNode token)
{
- if (!token.TryGetValue(nameof(IsRequired), out JToken? isRequiredToken))
+ if (!token.TryGetValue(nameof(IsRequired), out JsonNode? isRequiredToken))
{
return null;
}
@@ -255,7 +256,7 @@ private static TemplateParameterPrecedence GetPrecedence(bool isRequired, bool i
return null;
}
- if (isRequiredToken!.Type != JTokenType.String)
+ if (isRequiredToken!.GetValueKind() != JsonValueKind.String)
{
throw new ArgumentException(string.Format(LocalizableStrings.Symbol_Error_IsRequiredNotABoolOrString, isRequiredToken));
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PostActionModel.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PostActionModel.cs
index 958dc603a76..a5842f41f9d 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PostActionModel.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PostActionModel.cs
@@ -1,10 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Localization;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Validation;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -76,7 +76,7 @@ public string? Description
///
public IReadOnlyList ManualInstructionInfo { get; internal init; } = new List();
- internal static IReadOnlyList LoadListFromJArray(JArray? jArray, List validationEntries)
+ internal static IReadOnlyList LoadListFromJArray(JsonArray? jArray, List validationEntries)
{
List localizedPostActions = new();
if (jArray == null)
@@ -87,10 +87,10 @@ internal static IReadOnlyList LoadListFromJArray(JArray? jArray
HashSet postActionIds = new();
for (int postActionIndex = 0; postActionIndex < jArray.Count; postActionIndex++)
{
- JToken action = jArray[postActionIndex];
+ JsonNode? action = jArray[postActionIndex];
string? postActionId = action.ToString(nameof(Id));
string? description = action.ToString(nameof(Description));
- Guid actionId = action.ToGuid(nameof(ActionId));
+ Guid actionId = action!.ToGuid(nameof(ActionId));
bool continueOnError = action.ToBool(nameof(ContinueOnError));
string? postActionCondition = action.ToString(nameof(Condition));
bool applyFileRenamesToManualInstructions = action.ToBool(nameof(ApplyFileRenamesToManualInstructions));
@@ -118,9 +118,9 @@ internal static IReadOnlyList LoadListFromJArray(JArray? jArray
}
Dictionary args = new Dictionary(StringComparer.OrdinalIgnoreCase);
- foreach (JProperty argInfo in action.PropertiesOf("Args"))
+ foreach (var argInfo in action.PropertiesOf("Args"))
{
- args.Add(argInfo.Name, argInfo.Value.ToString());
+ args.Add(argInfo.Key, argInfo.Value?.ToString() ?? string.Empty);
}
List verifiedApplyFileRenamesToArgs = new();
@@ -141,7 +141,7 @@ internal static IReadOnlyList LoadListFromJArray(JArray? jArray
}
}
- IReadOnlyList manualInstructions = LoadManualInstructionsFromJArray(action.Get("ManualInstructions"), validationEntries);
+ IReadOnlyList manualInstructions = LoadManualInstructionsFromJArray(action.Get("ManualInstructions"), validationEntries);
PostActionModel model = new(args, manualInstructions)
{
@@ -177,7 +177,7 @@ internal void Localize(PostActionLocalizationModel locModel)
}
}
- private static IReadOnlyList LoadManualInstructionsFromJArray(JArray? jArray, List validationEntries)
+ private static IReadOnlyList LoadManualInstructionsFromJArray(JsonArray? jArray, List validationEntries)
{
var results = new List();
if (jArray == null)
@@ -188,7 +188,7 @@ private static IReadOnlyList LoadManualInstructionsFromJ
HashSet manualInstructionIds = new HashSet();
for (int i = 0; i < jArray.Count; i++)
{
- JToken jToken = jArray[i];
+ JsonNode? jToken = jArray[i];
string? id = jToken.ToString("id");
string text = jToken.ToString("text") ?? string.Empty;
string? condition = jToken.ToString("condition");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PrimaryOutputModel.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PrimaryOutputModel.cs
index 3a791151afe..bd2129338e7 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PrimaryOutputModel.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/PrimaryOutputModel.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -27,7 +27,7 @@ internal PrimaryOutputModel(string path)
///
public string Path { get; }
- internal static IReadOnlyList ListFromJArray(JArray? jsonData)
+ internal static IReadOnlyList ListFromJArray(JsonArray? jsonData)
{
List modelList = new List();
@@ -36,7 +36,7 @@ internal static IReadOnlyList ListFromJArray(JArray? jsonDat
return modelList;
}
- foreach (JToken pathInfo in jsonData)
+ foreach (JsonNode? pathInfo in jsonData)
{
string? path = pathInfo.ToString(nameof(Path));
if (string.IsNullOrWhiteSpace(path))
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ReplacementContext.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ReplacementContext.cs
index be69f3f74a5..e6d430fe6c7 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ReplacementContext.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/ReplacementContext.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -28,16 +28,16 @@ internal ReplacementContext(string? before, string? after)
///
public string? OnlyIfAfter { get; }
- internal static IReadOnlyList FromJObject(JObject jObject)
+ internal static IReadOnlyList FromJObject(JsonObject jObject)
{
- JArray? onlyIf = jObject.Get("onlyIf");
+ JsonArray? onlyIf = jObject.Get("onlyIf");
if (onlyIf != null)
{
List contexts = new List();
- foreach (JToken entry in onlyIf.Children())
+ foreach (JsonNode? entry in onlyIf)
{
- if (entry is not JObject)
+ if (entry is not JsonObject)
{
continue;
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolModelConverter.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolModelConverter.cs
index 5f519aaea9e..45f905dd222 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolModelConverter.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolModelConverter.cs
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -11,7 +11,7 @@ internal sealed class SymbolModelConverter
{
// Note: Only ParameterSymbol has a Description property, this it's the only one that gets localization
// TODO: change how localization gets merged in, don't do it here.
- internal static BaseSymbol? GetModelForObject(string name, JObject jObject, ILogger? logger, string? defaultOverride)
+ internal static BaseSymbol? GetModelForObject(string name, JsonObject jObject, ILogger? logger, string? defaultOverride)
{
try
{
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolValueFormsModel.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolValueFormsModel.cs
index 7f8ec6fea4d..a26fa440d64 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolValueFormsModel.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/SymbolValueFormsModel.cs
@@ -1,8 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -29,42 +30,19 @@ internal SymbolValueFormsModel(IReadOnlyList globalForms)
DefaultLowerSafeNamespaceValueFormFactory.FormIdentifier
});
- // Sets up the value forms for a symbol, based on configuration from template.json
- // There are two acceptable configuration formats for each forms specification.
- //
- // Note: in the examples below, "global" is used. But we'll be extending this to allow
- // conditional forms, which will have other names.
- // The same format will be used for other named form definitions.
- //
- // Simple:
- // "forms": {
- // "global": [ ]
- // }
- //
- // Detailed:
- // "forms" {
- // "global": {
- // "forms": [ ],
- // "addIdentity": ,
- // // other future extensions, e.g. conditionals
- // },
- //
- // If the symbol doesn't include an "identity" form and the addIdentity flag isn't false,
- // an identity specification is added to the beginning of the symbol's value form list.
- // If there is an identity form listed, its position remains intact irrespective of the addIdentity flag.
- internal static SymbolValueFormsModel FromJObject(JObject configJson)
+ internal static SymbolValueFormsModel FromJObject(JsonObject configJson)
{
- JToken? globalConfig = configJson.Property("global")?.Value;
+ JsonNode? globalConfig = JExtensions.GetPropertyCaseInsensitive(configJson, "global");
List globalForms;
bool addIdentity;
- if (globalConfig?.Type == JTokenType.Array)
+ if (globalConfig?.GetValueKind() == JsonValueKind.Array)
{
// config is just an array of form names.
globalForms = globalConfig.ArrayAsStrings().ToList();
addIdentity = true; // default value
}
- else if (globalConfig?.Type == JTokenType.Object)
+ else if (globalConfig?.GetValueKind() == JsonValueKind.Object)
{
// config is an object.
globalForms = globalConfig.ArrayAsStrings("forms").ToList();
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/TemplateConfigModel.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/TemplateConfigModel.cs
index 06a35b816f4..e85bd75a287 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/TemplateConfigModel.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ConfigModel/TemplateConfigModel.cs
@@ -2,14 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.InteropServices;
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Localization;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel
{
@@ -45,7 +44,7 @@ internal TemplateConfigModel(string identity)
Symbols = [];
}
- private TemplateConfigModel(JObject source, ILogger? logger, string? baselineName = null)
+ private TemplateConfigModel(JsonObject source, ILogger? logger, string? baselineName = null)
{
ILogger? logger1 = logger;
@@ -78,7 +77,7 @@ private TemplateConfigModel(JObject source, ILogger? logger, string? baselineNam
var sources = new List();
Sources = sources;
- foreach (JObject item in source.Items(nameof(Sources)))
+ foreach (JsonObject item in source.Items(nameof(Sources)))
{
ExtendedFileSource src = ExtendedFileSource.FromJObject(item);
sources.Add(src);
@@ -107,13 +106,13 @@ private TemplateConfigModel(JObject source, ILogger? logger, string? baselineNam
symbols[tagInfo.Key] = ParameterSymbol.FromDeprecatedConfigTag(tagInfo.Key, tagInfo.Value);
}
}
- foreach (JProperty prop in source.PropertiesOf(nameof(Symbols)))
+ foreach (var prop in source.PropertiesOf(nameof(Symbols)))
{
- if (prop.Value is not JObject obj)
+ if (prop.Value is not JsonObject obj)
{
continue;
}
- if (string.IsNullOrWhiteSpace(prop.Name))
+ if (string.IsNullOrWhiteSpace(prop.Key))
{
continue;
}
@@ -121,26 +120,26 @@ private TemplateConfigModel(JObject source, ILogger? logger, string? baselineNam
string? defaultOverride = null;
if (baseline?.DefaultOverrides != null)
{
- baseline.DefaultOverrides.TryGetValue(prop.Name, out defaultOverride);
+ baseline.DefaultOverrides.TryGetValue(prop.Key, out defaultOverride);
}
- BaseSymbol? modelForSymbol = SymbolModelConverter.GetModelForObject(prop.Name, obj, logger, defaultOverride);
+ BaseSymbol? modelForSymbol = SymbolModelConverter.GetModelForObject(prop.Key, obj, logger, defaultOverride);
if (modelForSymbol != null)
{
// The symbols dictionary comparer is Ordinal, making symbol names case-sensitive.
- if (string.Equals(prop.Name, NameSymbolName, StringComparison.Ordinal)
- && symbols.TryGetValue(prop.Name, out BaseSymbol existingSymbol)
+ if (string.Equals(prop.Key, NameSymbolName, StringComparison.Ordinal)
+ && symbols.TryGetValue(prop.Key, out BaseSymbol existingSymbol)
&& existingSymbol is ParameterSymbol existingParameterSymbol
&& modelForSymbol is ParameterSymbol modelForParameterSymbol)
{
// "name" symbol is explicitly defined above. If it's also defined in the template.json, it gets special handling here.
- symbols[prop.Name] = new ParameterSymbol(modelForParameterSymbol, existingParameterSymbol.Forms);
+ symbols[prop.Key] = new ParameterSymbol(modelForParameterSymbol, existingParameterSymbol.Forms);
}
else
{
// last in wins (in the odd case where a template.json defined a symbol multiple times)
- symbols[prop.Name] = modelForSymbol;
+ symbols[prop.Key] = modelForSymbol;
}
}
}
@@ -152,35 +151,35 @@ private TemplateConfigModel(JObject source, ILogger? logger, string? baselineNam
}
}
_symbols = symbols;
- _postActions = PostActionModel.LoadListFromJArray(source.Get("PostActions"), _validationEntries);
- PrimaryOutputs = PrimaryOutputModel.ListFromJArray(source.Get(nameof(PrimaryOutputs)));
+ _postActions = PostActionModel.LoadListFromJArray(source.Get("PostActions"), _validationEntries);
+ PrimaryOutputs = PrimaryOutputModel.ListFromJArray(source.Get(nameof(PrimaryOutputs)));
// Custom operations at the global level
- JToken? globalCustomConfigData = source[nameof(GlobalCustomOperations)];
+ JsonNode? globalCustomConfigData = JExtensions.GetPropertyCaseInsensitive(source, nameof(GlobalCustomOperations));
if (globalCustomConfigData != null)
{
- GlobalCustomOperations = CustomFileGlobModel.FromJObject((JObject)globalCustomConfigData, string.Empty);
+ GlobalCustomOperations = CustomFileGlobModel.FromJObject((JsonObject)globalCustomConfigData, string.Empty);
}
// Custom operations for specials
- IReadOnlyDictionary allSpecialOpsConfig = source.ToJTokenDictionary(StringComparer.OrdinalIgnoreCase, nameof(SpecialCustomOperations));
+ IReadOnlyDictionary allSpecialOpsConfig = source.ToJsonNodeDictionary(StringComparer.OrdinalIgnoreCase, nameof(SpecialCustomOperations));
List specialCustomSetup = new();
- foreach (KeyValuePair globConfigKeyValue in allSpecialOpsConfig)
+ foreach (KeyValuePair globConfigKeyValue in allSpecialOpsConfig)
{
string globName = globConfigKeyValue.Key;
- JToken globData = globConfigKeyValue.Value;
+ JsonNode globData = globConfigKeyValue.Value;
- CustomFileGlobModel globModel = CustomFileGlobModel.FromJObject((JObject)globData, globName);
+ CustomFileGlobModel globModel = CustomFileGlobModel.FromJObject((JsonObject)globData, globName);
specialCustomSetup.Add(globModel);
}
SpecialCustomOperations = specialCustomSetup;
List constraints = new();
- foreach (JProperty prop in source.PropertiesOf(nameof(Constraints)))
+ foreach (var prop in source.PropertiesOf(nameof(Constraints)))
{
- if (prop.Value is not JObject obj)
+ if (prop.Value is not JsonObject obj)
{
logger1?.LogWarning(LocalizableStrings.SimpleConfigModel_Error_Constraints_InvalidSyntax, nameof(Constraints).ToLowerInvariant());
continue;
@@ -189,11 +188,11 @@ private TemplateConfigModel(JObject source, ILogger? logger, string? baselineNam
string? type = obj.ToString(nameof(TemplateConstraintInfo.Type));
if (string.IsNullOrWhiteSpace(type))
{
- logger1?.LogWarning(LocalizableStrings.SimpleConfigModel_Error_Constraints_MissingType, obj.ToString(), nameof(TemplateConstraintInfo.Type).ToLowerInvariant());
+ logger1?.LogWarning(LocalizableStrings.SimpleConfigModel_Error_Constraints_MissingType, obj.ToJsonString(), nameof(TemplateConstraintInfo.Type).ToLowerInvariant());
continue;
}
- obj.TryGetValue(nameof(TemplateConstraintInfo.Args), StringComparison.OrdinalIgnoreCase, out JToken? args);
- constraints.Add(new TemplateConstraintInfo(type!, args?.ToString(Formatting.None)));
+ obj.TryGetValue(nameof(TemplateConstraintInfo.Args), out JsonNode? args);
+ constraints.Add(new TemplateConstraintInfo(type!, args?.ToJsonString()));
}
Constraints = constraints;
}
@@ -431,11 +430,12 @@ public static TemplateConfigModel FromString(string content, ILogger? logger = n
internal static TemplateConfigModel FromTextReader(TextReader content, ILogger? logger = null)
{
- using JsonReader r = new JsonTextReader(content);
- return new TemplateConfigModel(JObject.Load(r), logger, null);
+ string json = content.ReadToEnd();
+ JsonObject source = JExtensions.ParseJsonObject(json);
+ return new TemplateConfigModel(source, logger, null);
}
- internal static TemplateConfigModel FromJObject(JObject source, ILogger? logger = null, string? baselineName = null)
+ internal static TemplateConfigModel FromJObject(JsonObject source, ILogger? logger = null, string? baselineName = null)
{
return new TemplateConfigModel(source, logger, baselineName);
}
@@ -520,7 +520,7 @@ private static BaseSymbol SetupDefaultNameSymbol(string? sourceName)
};
}
- private static Dictionary SetupValueFormMapForTemplate(JObject? source = null)
+ private static Dictionary SetupValueFormMapForTemplate(JsonObject? source = null)
{
Dictionary formMap = new(StringComparer.Ordinal);
@@ -539,11 +539,11 @@ private static Dictionary SetupValueFormMapForTemplate(JObje
// setup the forms defined by the template configuration.
// if any have the same name as a default, the default is overridden.
- IReadOnlyDictionary templateDefinedForms = source.ToJTokenDictionary(StringComparer.OrdinalIgnoreCase, nameof(Forms));
+ IReadOnlyDictionary templateDefinedForms = source.ToJsonNodeDictionary(StringComparer.OrdinalIgnoreCase, nameof(Forms));
- foreach (KeyValuePair form in templateDefinedForms)
+ foreach (KeyValuePair form in templateDefinedForms)
{
- if (form.Value is JObject o)
+ if (form.Value is JsonObject o)
{
formMap[form.Key] = ValueFormRegistry.GetForm(form.Key, o);
}
@@ -551,20 +551,20 @@ private static Dictionary SetupValueFormMapForTemplate(JObje
return formMap;
}
- private static IReadOnlyDictionary BaselineInfoFromJObject(IEnumerable baselineJProperties)
+ private static IReadOnlyDictionary BaselineInfoFromJObject(IEnumerable> baselineProperties)
{
Dictionary allBaselines = new();
- foreach (JProperty property in baselineJProperties)
+ foreach (var property in baselineProperties)
{
- if (property.Value is not JObject obj)
+ if (property.Value is not JsonObject obj)
{
continue;
}
- IReadOnlyDictionary? defaultOverrides = obj.Get(nameof(Utils.BaselineInfo.DefaultOverrides))?.ToStringDictionary() ?? new Dictionary();
+ IReadOnlyDictionary? defaultOverrides = obj.Get(nameof(Utils.BaselineInfo.DefaultOverrides))?.ToStringDictionary() ?? new Dictionary();
BaselineInfo baseline = new(defaultOverrides, obj.ToString(nameof(baseline.Description)));
- allBaselines[property.Name] = baseline;
+ allBaselines[property.Key] = baseline;
}
return allBaselines;
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/DirectoryBasedTemplate.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/DirectoryBasedTemplate.cs
index 438575cfe56..e547621644f 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/DirectoryBasedTemplate.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/DirectoryBasedTemplate.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Mount;
@@ -9,7 +10,6 @@
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Validation;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects
{
@@ -157,7 +157,7 @@ internal Task ValidateAsync(ValidationScope scope, CancellationToken cancellatio
/// Additional files must be in the same folder as the template file.
///
/// when additional files configuration is invalid.
- private static JObject MergeAdditionalConfiguration(JObject primarySource, IFileSystemInfo primarySourceConfig)
+ private static JsonObject MergeAdditionalConfiguration(JsonObject primarySource, IFileSystemInfo primarySourceConfig)
{
IReadOnlyList otherFiles = primarySource.ArrayAsStrings(AdditionalConfigFilesIndicator);
@@ -166,7 +166,7 @@ private static JObject MergeAdditionalConfiguration(JObject primarySource, IFile
return primarySource;
}
- JObject combinedSource = (JObject)primarySource.DeepClone();
+ JsonObject combinedSource = primarySource.DeepCloneObject();
foreach (string partialConfigFileName in otherFiles)
{
@@ -181,7 +181,7 @@ private static JObject MergeAdditionalConfiguration(JObject primarySource, IFile
LocalizableStrings.SimpleConfigModel_AuthoringException_MergeConfiguration_FileNotFound,
partialConfigFileName),
partialConfigFileName);
- JObject partialConfigJson = partialConfigFile.ReadJObjectFromIFile();
+ JsonObject partialConfigJson = partialConfigFile.ReadJObjectFromIFile();
combinedSource.Merge(partialConfigJson);
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/LocalizationModelDeserializer.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/LocalizationModelDeserializer.cs
index d9b45444d8c..abaf9937275 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/LocalizationModelDeserializer.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/LocalizationModelDeserializer.cs
@@ -1,10 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Localization;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects
{
@@ -26,10 +26,10 @@ public static LocalizationModel Deserialize(IFile file)
{
_ = file ?? throw new ArgumentNullException(nameof(file));
- JObject srcObject = file.ReadJObjectFromIFile();
+ System.Text.Json.Nodes.JsonObject srcObject = file.ReadJObjectFromIFile();
- List<(string Key, string Value)> localizedStrings = srcObject.Properties()
- .Select(p => p.Value.Type == JTokenType.String ? (p.Name, p.Value.ToString()) : throw new Exception(LocalizableStrings.Authoring_InvalidJsonElementInLocalizationFile))
+ List<(string Key, string Value)> localizedStrings = srcObject
+ .Select(p => p.Value?.GetValueKind() == JsonValueKind.String ? (p.Key, p.Value.GetValue()) : throw new Exception(LocalizableStrings.Authoring_InvalidJsonElementInLocalizationFile))
.ToList();
var symbols = LoadSymbolModels(localizedStrings);
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/BaseMacroConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/BaseMacroConfig.cs
index 7dfda10fd30..71ce191c146 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/BaseMacroConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/BaseMacroConfig.cs
@@ -1,13 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Expressions.Cpp2;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Macros
{
@@ -84,8 +85,8 @@ protected static bool ConvertJTokenToBool(string token, IGeneratedSymbolConfig c
{
try
{
- var jToken = JToken.Parse(token);
- if (jToken.TryParseBool(out bool result))
+ var jToken = JExtensions.ParseJsonNode(token);
+ if (jToken != null && jToken.TryParseBool(out bool result))
{
return result;
}
@@ -101,8 +102,8 @@ protected static int ConvertJTokenToInt(string token, IGeneratedSymbolConfig con
{
try
{
- var jToken = JToken.Parse(token);
- if (jToken.TryParseInt(out int result))
+ var jToken = JExtensions.ParseJsonNode(token);
+ if (jToken != null && jToken.TryParseInt(out int result))
{
return result;
}
@@ -118,12 +119,12 @@ protected static string ConvertJTokenToString(string token, IGeneratedSymbolConf
{
try
{
- var jToken = JToken.Parse(token);
- if (jToken is not JValue val)
+ var jToken = JExtensions.ParseJsonNode(token);
+ if (jToken is not JsonValue val)
{
throw new TemplateAuthoringException(string.Format(LocalizableStrings.MacroConfig_Exception_ValueShouldBeString, config.VariableName, parameterName), config.VariableName);
}
- return val.ToString();
+ return val.GetValueKind() == JsonValueKind.String ? val.GetValue() : val.ToJsonString();
}
catch (Exception ex) when (ex is not TemplateAuthoringException)
{
@@ -131,16 +132,16 @@ protected static string ConvertJTokenToString(string token, IGeneratedSymbolConf
}
}
- protected static JArray ConvertJTokenToJArray(string token, IGeneratedSymbolConfig config, string parameterName)
+ protected static JsonArray ConvertJTokenToJArray(string token, IGeneratedSymbolConfig config, string parameterName)
{
try
{
- var jToken = JToken.Parse(token);
- if (jToken.Type != JTokenType.Array)
+ var jToken = JExtensions.ParseJsonNode(token);
+ if (jToken == null || jToken.GetValueKind() != JsonValueKind.Array)
{
throw new TemplateAuthoringException(string.Format(LocalizableStrings.MacroConfig_Exception_ValueShouldBeArray, config.VariableName, parameterName), config.VariableName);
}
- return (JArray)jToken;
+ return (JsonArray)jToken;
}
catch (Exception ex) when (ex is not TemplateAuthoringException)
{
@@ -185,7 +186,7 @@ protected TVal GetMandatoryParameterValue(IGeneratedSymbolConfig config, s
return converter(token, config, parameterName);
}
- protected JArray GetMandatoryParameterArray(IGeneratedSymbolConfig config, string parameterName)
+ protected JsonArray GetMandatoryParameterArray(IGeneratedSymbolConfig config, string parameterName)
{
if (!config.Parameters.TryGetValue(parameterName, out string token))
{
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/JoinMacroConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/JoinMacroConfig.cs
index baa2b89d7e0..485b2749c6e 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/JoinMacroConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/JoinMacroConfig.cs
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Macros
{
@@ -29,11 +29,11 @@ internal JoinMacroConfig(JoinMacro macro, IGeneratedSymbolConfig generatedSymbol
List<(JoinType Type, string Value)> symbolsList = new();
- JArray jArray = GetMandatoryParameterArray(generatedSymbolConfig, SymbolsPropertyName);
+ JsonArray jArray = GetMandatoryParameterArray(generatedSymbolConfig, SymbolsPropertyName);
- foreach (JToken entry in jArray)
+ foreach (JsonNode? entry in jArray)
{
- if (entry is not JObject jObj)
+ if (entry is not JsonObject jObj)
{
throw new TemplateAuthoringException(string.Format(LocalizableStrings.MacroConfig_Exception_ArrayShouldContainObjects, generatedSymbolConfig.VariableName, SymbolsPropertyName), generatedSymbolConfig.VariableName);
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/RegexMacroConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/RegexMacroConfig.cs
index fc8792bacac..5f8d27b14ec 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/RegexMacroConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/RegexMacroConfig.cs
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Macros
{
@@ -31,11 +31,11 @@ internal RegexMacroConfig(RegexMacro macro, IGeneratedSymbolConfig generatedSymb
Source = GetMandatoryParameterValue(generatedSymbolConfig, "source");
List<(string Type, string Value)> steps = new();
- JArray jArray = GetMandatoryParameterArray(generatedSymbolConfig, StepsPropertyName);
+ JsonArray jArray = GetMandatoryParameterArray(generatedSymbolConfig, StepsPropertyName);
- foreach (JToken entry in jArray)
+ foreach (JsonNode? entry in jArray)
{
- if (entry is not JObject jObj)
+ if (entry is not JsonObject jObj)
{
throw new TemplateAuthoringException(string.Format(LocalizableStrings.MacroConfig_Exception_ArrayShouldContainObjects, generatedSymbolConfig.VariableName, StepsPropertyName), generatedSymbolConfig.VariableName);
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/SwitchMacroConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/SwitchMacroConfig.cs
index df256725ef1..8e82ffe796b 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/SwitchMacroConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/SwitchMacroConfig.cs
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Macros
{
@@ -30,11 +30,11 @@ internal SwitchMacroConfig(SwitchMacro macro, IGeneratedSymbolConfig generatedSy
Evaluator = EvaluatorSelector.SelectStringEvaluator(EvaluatorSelector.ParseEvaluatorName(evaluator, DefaultEvaluator));
}
List<(string? Condition, string Value)> cases = new();
- JArray jArray = GetMandatoryParameterArray(generatedSymbolConfig, CasesPropertyName);
+ JsonArray jArray = GetMandatoryParameterArray(generatedSymbolConfig, CasesPropertyName);
- foreach (JToken entry in jArray)
+ foreach (JsonNode? entry in jArray)
{
- if (entry is not JObject jObj)
+ if (entry is not JsonObject jObj)
{
throw new TemplateAuthoringException(string.Format(LocalizableStrings.MacroConfig_Exception_ArrayShouldContainObjects, generatedSymbolConfig.VariableName, CasesPropertyName), generatedSymbolConfig.VariableName);
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.csproj b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.csproj
index c85ab5ebc04..79dab3bba05 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.csproj
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/BalancedNestingConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/BalancedNestingConfig.cs
index 6aa866e2b6a..d64a25a83d2 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/BalancedNestingConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/BalancedNestingConfig.cs
@@ -1,12 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -18,7 +18,7 @@ internal class BalancedNestingConfig : IOperationConfig
public IEnumerable ConfigureFromJson(string configuration, IDirectory templateRoot)
{
- JObject rawConfiguration = JObject.Parse(configuration);
+ JsonObject rawConfiguration = JExtensions.ParseJsonObject(configuration);
string? startToken = rawConfiguration.ToString("startToken");
string? realEndToken = rawConfiguration.ToString("realEndToken");
string? pseudoEndToken = rawConfiguration.ToString("pseudoEndToken");
@@ -29,9 +29,9 @@ public IEnumerable ConfigureFromJson(string configuration, I
yield return new BalancedNesting(startToken.TokenConfig(), realEndToken.TokenConfig(), pseudoEndToken.TokenConfig(), id, resetFlag, onByDefault);
}
- internal static JObject CreateConfiguration(string startToken, string realEndToken, string pseudoEndToken, string id, string resetFlag)
+ internal static JsonObject CreateConfiguration(string startToken, string realEndToken, string pseudoEndToken, string id, string resetFlag)
{
- JObject config = new JObject
+ JsonObject config = new JsonObject
{
["startToken"] = startToken,
["realEndToken"] = realEndToken,
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalBlockCommentConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalBlockCommentConfig.cs
index e7690085e06..31e4f3d2dda 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalBlockCommentConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalBlockCommentConfig.cs
@@ -1,17 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
internal static class ConditionalBlockCommentConfig
{
- internal static List ConfigureFromJObject(JObject rawConfiguration)
+ internal static List ConfigureFromJObject(JsonObject rawConfiguration)
{
string? startToken = rawConfiguration.ToString("startToken");
string? endToken = rawConfiguration.ToString("endToken");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalConfig.cs
index cdd90807f15..193519a829a 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalConfig.cs
@@ -1,13 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -19,7 +19,7 @@ internal class ConditionalConfig : IOperationConfig
public IEnumerable ConfigureFromJson(string configuration, IDirectory templateRoot)
{
- JObject rawConfiguration = JObject.Parse(configuration);
+ JsonObject rawConfiguration = JExtensions.ParseJsonObject(configuration);
string? commentStyle = rawConfiguration.ToString("style");
IEnumerable operations = string.IsNullOrEmpty(commentStyle) || string.Equals(commentStyle, "custom", StringComparison.OrdinalIgnoreCase)
? ConditionalCustomConfig.ConfigureFromJObject(rawConfiguration)
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalCustomConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalCustomConfig.cs
index e3bc5cbedf5..9926aa08477 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalCustomConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalCustomConfig.cs
@@ -1,16 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
internal static class ConditionalCustomConfig
{
- internal static List ConfigureFromJObject(JObject rawConfiguration)
+ internal static List ConfigureFromJObject(JsonObject rawConfiguration)
{
IReadOnlyList ifToken = rawConfiguration.ArrayAsStrings("if");
IReadOnlyList elseToken = rawConfiguration.ArrayAsStrings("else");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalKeywords.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalKeywords.cs
index 9989aa22014..cb0ba067129 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalKeywords.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalKeywords.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -34,7 +34,7 @@ internal ConditionalKeywords()
// TODO: Allow the rawConfiguration elements to be either strings (as-is) or arrays of strings.
// The code that consumes instances of this class is already setup to deal with multiple forms of each keyword type.
- internal static ConditionalKeywords FromJObject(JObject rawConfiguration)
+ internal static ConditionalKeywords FromJObject(JsonObject rawConfiguration)
{
ConditionalKeywords keywords = new ConditionalKeywords();
string? ifKeyword = rawConfiguration.ToString("ifKeyword");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalLineCommentConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalLineCommentConfig.cs
index 932874e4f84..88ba8aedd88 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalLineCommentConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalLineCommentConfig.cs
@@ -1,17 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
internal static class ConditionalLineCommentConfig
{
- internal static List ConfigureFromJObject(JObject rawConfiguration)
+ internal static List ConfigureFromJObject(JsonObject rawConfiguration)
{
string? token = rawConfiguration.ToString("token");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalOperationOptions.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalOperationOptions.cs
index 3c2886a693c..0033424d020 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalOperationOptions.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ConditionalOperationOptions.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -28,7 +28,7 @@ internal ConditionalOperationOptions()
internal bool OnByDefault { get; set; }
- internal static ConditionalOperationOptions FromJObject(JObject rawConfiguration)
+ internal static ConditionalOperationOptions FromJObject(JsonObject rawConfiguration)
{
ConditionalOperationOptions options = new ConditionalOperationOptions();
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/FlagsConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/FlagsConfig.cs
index 413acce85d9..f741de589d7 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/FlagsConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/FlagsConfig.cs
@@ -1,12 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -25,7 +25,7 @@ internal class FlagsConfig : IOperationConfig
public IEnumerable ConfigureFromJson(string configuration, IDirectory templateRoot)
{
- JObject rawConfiguration = JObject.Parse(configuration);
+ JsonObject rawConfiguration = JExtensions.ParseJsonObject(configuration);
string? flag = rawConfiguration.ToString("name");
string on = rawConfiguration.ToString("on") ?? string.Empty;
string off = rawConfiguration.ToString("off") ?? string.Empty;
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/IncludeConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/IncludeConfig.cs
index 09bfbec4e83..1a120f9bea4 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/IncludeConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/IncludeConfig.cs
@@ -1,13 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -19,7 +19,7 @@ internal class IncludeConfig : IOperationConfig
public IEnumerable ConfigureFromJson(string configuration, IDirectory templateRoot)
{
- JObject rawConfiguration = JObject.Parse(configuration);
+ JsonObject rawConfiguration = JExtensions.ParseJsonObject(configuration);
string? startToken = rawConfiguration.ToString("start");
string? endToken = rawConfiguration.ToString("end");
string? id = rawConfiguration.ToString("id");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/RegionConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/RegionConfig.cs
index 23ab8774482..18ed46bf2be 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/RegionConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/RegionConfig.cs
@@ -1,12 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Core;
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -18,7 +18,7 @@ internal class RegionConfig : IOperationConfig
public IEnumerable ConfigureFromJson(string configuration, IDirectory templateRoot)
{
- JObject rawConfiguration = JObject.Parse(configuration);
+ JsonObject rawConfiguration = JExtensions.ParseJsonObject(configuration);
string? id = rawConfiguration.ToString("id");
string? start = rawConfiguration.ToString("start");
string? end = rawConfiguration.ToString("end");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ReplacementConfig.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ReplacementConfig.cs
index 1682d2211ec..0aac579badd 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ReplacementConfig.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/OperationConfig/ReplacementConfig.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Mount;
@@ -8,7 +9,6 @@
using Microsoft.TemplateEngine.Core.Contracts;
using Microsoft.TemplateEngine.Core.Operations;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Abstractions;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.OperationConfig
{
@@ -20,20 +20,20 @@ internal class ReplacementConfig : IOperationConfig
public IEnumerable ConfigureFromJson(string configuration, IDirectory templateRoot)
{
- JObject rawConfiguration = JObject.Parse(configuration);
+ JsonObject rawConfiguration = JExtensions.ParseJsonObject(configuration);
string? original = rawConfiguration.ToString("original");
string? replacement = rawConfiguration.ToString("replacement");
string? id = rawConfiguration.ToString("id");
bool onByDefault = rawConfiguration.ToBool("onByDefault");
- JArray? onlyIf = rawConfiguration.Get("onlyIf");
+ JsonArray? onlyIf = rawConfiguration.Get("onlyIf");
TokenConfig coreConfig = original.TokenConfigBuilder();
if (onlyIf != null)
{
- foreach (JToken entry in onlyIf.Children())
+ foreach (JsonNode? entry in onlyIf)
{
- if (entry is not JObject)
+ if (entry is not JsonObject)
{
continue;
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueFormRegistry.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueFormRegistry.cs
index 95b9c2e7251..13356b71ff5 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueFormRegistry.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueFormRegistry.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects
{
@@ -36,7 +36,7 @@ internal static class ValueFormRegistry
internal static IReadOnlyDictionary FormLookup => AllForms.ToDictionary(ff => ff.Identifier, ff => ff, StringComparer.OrdinalIgnoreCase);
- internal static IValueForm GetForm(string name, JObject? obj)
+ internal static IValueForm GetForm(string name, JsonObject? obj)
{
string? identifier = obj.ToString("identifier");
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ActionableValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ActionableValueFormFactory.cs
index d88dd60575f..c63f5d440dd 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ActionableValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ActionableValueFormFactory.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -12,7 +12,7 @@ internal abstract class ActionableValueFormFactory : BaseValueFormFactory
{
protected ActionableValueFormFactory(string identifier) : base(identifier) { }
- public override IValueForm FromJObject(string name, JObject? configuration = null)
+ public override IValueForm FromJObject(string name, JsonObject? configuration = null)
{
return new ActionableValueForm(name, this);
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/BaseValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/BaseValueFormFactory.cs
index ccd721b547a..a0e236ad97b 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/BaseValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/BaseValueFormFactory.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -24,7 +24,7 @@ protected BaseValueFormFactory(string identifier)
public abstract IValueForm Create(string? name = null);
- public abstract IValueForm FromJObject(string name, JObject? configuration = null);
+ public abstract IValueForm FromJObject(string name, JsonObject? configuration = null);
protected abstract class BaseValueForm : IValueForm
{
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ChainValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ChainValueFormFactory.cs
index 0a6eed43825..eabe5794d6d 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ChainValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ChainValueFormFactory.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -27,7 +27,7 @@ protected override string Process(string value, IReadOnlyList? steps, IR
return result;
}
- protected override IReadOnlyList ReadConfiguration(JObject jObject)
+ protected override IReadOnlyList ReadConfiguration(JsonObject jObject)
{
return jObject.ArrayAsStrings("steps");
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ConfigurableValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ConfigurableValueFormFactory.cs
index f01570a0256..74a1575a7b4 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ConfigurableValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ConfigurableValueFormFactory.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -12,7 +12,7 @@ internal abstract class ConfigurableValueFormFactory : BaseValueFormFactory w
{
protected ConfigurableValueFormFactory(string identifier) : base(identifier) { }
- public override IValueForm FromJObject(string name, JObject? configuration)
+ public override IValueForm FromJObject(string name, JsonObject? configuration)
{
if (configuration != null)
{
@@ -34,7 +34,7 @@ public override IValueForm Create(string? name = null)
};
}
- protected abstract T ReadConfiguration(JObject jObject);
+ protected abstract T ReadConfiguration(JsonObject jObject);
protected abstract string Process(string value, T? configuration);
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/DependentValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/DependentValueFormFactory.cs
index 1ac8da24845..44004dd6f9b 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/DependentValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/DependentValueFormFactory.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -12,7 +12,7 @@ internal abstract class DependentValueFormFactory : BaseValueFormFactory wher
{
protected DependentValueFormFactory(string identifier) : base(identifier) { }
- public override IValueForm FromJObject(string name, JObject? configuration)
+ public override IValueForm FromJObject(string name, JsonObject? configuration)
{
if (configuration != null)
{
@@ -34,7 +34,7 @@ public override IValueForm Create(string? name = null)
};
}
- protected abstract T ReadConfiguration(JObject jObject);
+ protected abstract T ReadConfiguration(JsonObject jObject);
protected abstract string Process(string value, T? configuration, IReadOnlyDictionary otherForms);
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueForm.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueForm.cs
index 9366ec4bcdd..7da1e20a63a 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueForm.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueForm.cs
@@ -23,7 +23,7 @@ public interface IValueForm
///
/// True is the form is a default implicit form.
- /// See for more details.
+ /// See for more details.
///
internal bool IsDefault { get; }
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueFormFactory.cs
index 68895ccf1e2..1b48d798fac 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/IValueFormFactory.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -20,6 +20,6 @@ internal interface IValueFormFactory
///
/// Creates the form from JSON configuration.
///
- IValueForm FromJObject(string name, JObject? configuration = null);
+ IValueForm FromJObject(string name, JsonObject? configuration = null);
}
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/JsonEncodeValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/JsonEncodeValueFormFactory.cs
index 31661101fd7..95de03692b9 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/JsonEncodeValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/JsonEncodeValueFormFactory.cs
@@ -1,7 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json;
+using System.Text.Encodings.Web;
+using System.Text.Json;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -9,11 +10,16 @@ internal class JsonEncodeValueFormFactory : ActionableValueFormFactory
{
internal const string FormIdentifier = "jsonEncode";
+ private static readonly JsonSerializerOptions JsonEncodeOptions = new()
+ {
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+ };
+
internal JsonEncodeValueFormFactory() : base(FormIdentifier) { }
protected override string Process(string value)
{
- return JsonConvert.SerializeObject(value);
+ return JsonSerializer.Serialize(value, JsonEncodeOptions);
}
}
}
diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ReplacementValueFormFactory.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ReplacementValueFormFactory.cs
index 611a7ffe9b3..9c93ab683ba 100644
--- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ReplacementValueFormFactory.cs
+++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ValueForms/ReplacementValueFormFactory.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms
{
@@ -34,7 +34,7 @@ protected override string Process(string value, ReplacementValueFormSettings? co
return configuration.Match.Replace(value, configuration.Replacement);
}
- protected override ReplacementValueFormSettings ReadConfiguration(JObject jObject)
+ protected override ReplacementValueFormSettings ReadConfiguration(JsonObject jObject)
{
return new ReplacementValueFormSettings(new Regex(jObject.ToString("pattern")), jObject.ToString("replacement"));
}
diff --git a/src/Microsoft.TemplateEngine.Utils/Microsoft.TemplateEngine.Utils.csproj b/src/Microsoft.TemplateEngine.Utils/Microsoft.TemplateEngine.Utils.csproj
index b87aa437d62..7bfb6cc9f07 100644
--- a/src/Microsoft.TemplateEngine.Utils/Microsoft.TemplateEngine.Utils.csproj
+++ b/src/Microsoft.TemplateEngine.Utils/Microsoft.TemplateEngine.Utils.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/src/Microsoft.TemplateSearch.Common/Microsoft.TemplateSearch.Common.csproj b/src/Microsoft.TemplateSearch.Common/Microsoft.TemplateSearch.Common.csproj
index c140fc324a6..80d70443282 100644
--- a/src/Microsoft.TemplateSearch.Common/Microsoft.TemplateSearch.Common.csproj
+++ b/src/Microsoft.TemplateSearch.Common/Microsoft.TemplateSearch.Common.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/BlobStorageTemplateInfo.cs b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/BlobStorageTemplateInfo.cs
index bcd57461605..bdecfd54df4 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/BlobStorageTemplateInfo.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/BlobStorageTemplateInfo.cs
@@ -1,16 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
using Microsoft.TemplateEngine;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Abstractions.Parameters;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateSearch.Common
{
- [JsonObject(Id = "TemplateInfo")]
[Obsolete("The class is deprecated. Use TemplateSearchCache instead to create search cache data. Deserialization code to be moved to TemplateSearchData.Json.")]
internal class BlobStorageTemplateInfo : ITemplateInfo
{
@@ -50,7 +50,7 @@ public BlobStorageTemplateInfo(ITemplateInfo templateInfo)
PostActions = templateInfo.PostActions;
}
- [JsonConstructor]
+ [System.Text.Json.Serialization.JsonConstructor]
private BlobStorageTemplateInfo(string identity, string name, IEnumerable shortNameList)
{
if (string.IsNullOrWhiteSpace(identity))
@@ -73,7 +73,7 @@ private BlobStorageTemplateInfo(string identity, string name, IEnumerable Parameters => ParameterDefinitions;
[JsonIgnore]
- string ITemplateLocator.MountPointUri => throw new NotImplementedException();
+ string ITemplateLocator.MountPointUri => string.Empty;
- [JsonProperty]
public string? Author { get; private set; }
- [JsonProperty]
public IReadOnlyList Classifications { get; private set; } = new List();
[JsonIgnore]
- public string DefaultName => throw new NotImplementedException();
+ public string DefaultName => string.Empty;
- [JsonProperty]
public string? Description { get; private set; }
- [JsonProperty]
public string Identity { get; private set; }
[JsonIgnore]
- Guid ITemplateLocator.GeneratorId => throw new NotImplementedException();
+ Guid ITemplateLocator.GeneratorId => Guid.Empty;
- [JsonProperty]
public string? GroupIdentity { get; private set; }
- [JsonProperty]
public int Precedence { get; private set; }
- [JsonProperty]
public string Name { get; private set; }
[JsonIgnore]
[Obsolete("Use ShortNameList instead.")]
- string ITemplateInfo.ShortName => throw new NotImplementedException();
+ string ITemplateInfo.ShortName => ShortNameList.Count > 0 ? ShortNameList[0] : string.Empty;
- [JsonProperty]
public IReadOnlyList ShortNameList { get; private set; }
[JsonIgnore]
@@ -130,41 +122,37 @@ private BlobStorageTemplateInfo(string identity, string name, IEnumerable CacheParameters { get; private set; } = new Dictionary();
[JsonIgnore]
- string ITemplateLocator.ConfigPlace => throw new NotImplementedException();
+ string ITemplateLocator.ConfigPlace => string.Empty;
[JsonIgnore]
- string IExtendedTemplateLocator.LocaleConfigPlace => throw new NotImplementedException();
+ string IExtendedTemplateLocator.LocaleConfigPlace => string.Empty;
[JsonIgnore]
- string IExtendedTemplateLocator.HostConfigPlace => throw new NotImplementedException();
+ string IExtendedTemplateLocator.HostConfigPlace => string.Empty;
- [JsonProperty]
public string? ThirdPartyNotices { get; private set; }
- [JsonProperty]
public IReadOnlyDictionary BaselineInfo { get; private set; } = new Dictionary();
[JsonIgnore]
[Obsolete("This property is deprecated")]
bool ITemplateInfo.HasScriptRunningPostActions { get; set; }
- [JsonProperty]
public IReadOnlyDictionary TagsCollection { get; private set; } = new Dictionary();
- [JsonProperty]
public IReadOnlyList PostActions { get; private set; } = [];
[JsonIgnore]
- IReadOnlyList ITemplateMetadata.Constraints => throw new NotImplementedException();
+ IReadOnlyList ITemplateMetadata.Constraints => [];
- public static BlobStorageTemplateInfo FromJObject(JObject entry)
+ public static BlobStorageTemplateInfo FromJObject(JsonObject entry)
{
string identity = entry.ToString(nameof(Identity))
?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(Identity)} property.", nameof(entry));
string name = entry.ToString(nameof(Name))
?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(Name)} property.", nameof(entry));
- JToken? shortNameToken = entry.Get(nameof(ShortNameList));
+ JsonNode? shortNameToken = entry.Get(nameof(ShortNameList));
IEnumerable shortNames = shortNameToken?.JTokenStringOrArrayToCollection([])
?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(ShortNameList)} property.", nameof(entry));
@@ -172,13 +160,13 @@ public static BlobStorageTemplateInfo FromJObject(JObject entry)
{
Author = entry.ToString(nameof(Author))
};
- JArray? classificationsArray = entry.Get(nameof(Classifications));
+ JsonArray? classificationsArray = entry.Get(nameof(Classifications));
if (classificationsArray != null)
{
List classifications = new List();
- foreach (JToken item in classificationsArray)
+ foreach (JsonNode? item in classificationsArray)
{
- classifications.Add(item.ToString());
+ classifications.Add(item?.ToString() ?? string.Empty);
}
info.Classifications = classifications;
}
@@ -187,29 +175,29 @@ public static BlobStorageTemplateInfo FromJObject(JObject entry)
info.Precedence = entry.ToInt32(nameof(Precedence));
info.ThirdPartyNotices = entry.ToString(nameof(ThirdPartyNotices));
- JObject? baselineJObject = entry.Get(nameof(ITemplateInfo.BaselineInfo));
+ JsonObject? baselineJObject = entry.Get(nameof(ITemplateInfo.BaselineInfo));
Dictionary baselineInfo = new Dictionary();
if (baselineJObject != null)
{
- foreach (JProperty item in baselineJObject.Properties())
+ foreach (var item in baselineJObject)
{
IBaselineInfo baseline = new BaselineCacheInfo()
{
Description = item.Value.ToString(nameof(IBaselineInfo.Description)),
- DefaultOverrides = item.Value.ToStringDictionary(propertyName: nameof(IBaselineInfo.DefaultOverrides))
+ DefaultOverrides = item.Value?.ToStringDictionary(propertyName: nameof(IBaselineInfo.DefaultOverrides)) ?? new Dictionary()
};
- baselineInfo.Add(item.Name, baseline);
+ baselineInfo.Add(item.Key, baseline);
}
info.BaselineInfo = baselineInfo;
}
- JArray? postActionsArray = entry.Get(nameof(info.PostActions));
+ JsonArray? postActionsArray = entry.Get(nameof(info.PostActions));
if (postActionsArray != null)
{
List postActions = new List();
- foreach (JToken item in postActionsArray)
+ foreach (JsonNode? item in postActionsArray)
{
- if (Guid.TryParse(item.ToString(), out Guid id))
+ if (Guid.TryParse(item?.ToString(), out Guid id))
{
postActions.Add(id);
}
@@ -220,12 +208,12 @@ public static BlobStorageTemplateInfo FromJObject(JObject entry)
//read parameters
bool readParameters = false;
List templateParameters = new List();
- JArray? parametersArray = entry.Get(nameof(Parameters));
+ JsonArray? parametersArray = entry.Get(nameof(Parameters));
if (parametersArray != null)
{
- foreach (JToken item in parametersArray)
+ foreach (JsonNode? item in parametersArray)
{
- if (item is JObject jObj)
+ if (item is JsonObject jObj)
{
templateParameters.Add(new BlobTemplateParameter(jObj));
}
@@ -233,27 +221,27 @@ public static BlobStorageTemplateInfo FromJObject(JObject entry)
readParameters = true;
}
- JObject? tagsObject = entry.Get(nameof(TagsCollection));
+ JsonObject? tagsObject = entry.Get(nameof(TagsCollection));
Dictionary tags = new Dictionary();
if (tagsObject != null)
{
- foreach (JProperty item in tagsObject.Properties())
+ foreach (var item in tagsObject)
{
- tags.Add(item.Name.ToString(), item.Value.ToString());
+ tags.Add(item.Key, item.Value?.ToString() ?? string.Empty);
}
}
//try read tags and parameters - for compatibility reason
- tagsObject = entry.Get("tags");
+ tagsObject = entry.Get("tags");
if (tagsObject != null)
{
Dictionary legacyTags = new Dictionary();
- foreach (JProperty item in tagsObject.Properties())
+ foreach (var item in tagsObject)
{
- if (item.Value.Type == JTokenType.String)
+ if (item.Value is JsonValue jv && jv.GetValueKind() == JsonValueKind.String)
{
- tags[item.Name.ToString()] = item.Value.ToString();
- legacyTags[item.Name.ToString()] = new BlobLegacyCacheTag(
+ tags[item.Key] = item.Value.ToString();
+ legacyTags[item.Key] = new BlobLegacyCacheTag(
description: null,
choicesAndDescriptions: new Dictionary()
{
@@ -262,48 +250,47 @@ public static BlobStorageTemplateInfo FromJObject(JObject entry)
defaultValue: item.Value.ToString(),
defaultIfOptionWithoutValue: null);
}
- else if (item.Value is JObject tagObj)
+ else if (item.Value is JsonObject tagObj)
{
- JObject? choicesObject = tagObj.Get("ChoicesAndDescriptions");
+ JsonObject? choicesObject = tagObj.Get("ChoicesAndDescriptions");
if (choicesObject != null && !readParameters)
{
Dictionary choicesAndDescriptions = new Dictionary(StringComparer.OrdinalIgnoreCase);
Dictionary legacyChoices = new Dictionary(StringComparer.OrdinalIgnoreCase);
- foreach (JProperty cdPair in choicesObject.Properties())
+ foreach (var cdPair in choicesObject)
{
- choicesAndDescriptions[cdPair.Name.ToString()] = new ParameterChoice(null, cdPair.Value.ToString());
- legacyChoices[cdPair.Name.ToString()] = cdPair.Value.ToString();
+ choicesAndDescriptions[cdPair.Key] = new ParameterChoice(null, cdPair.Value?.ToString() ?? string.Empty);
+ legacyChoices[cdPair.Key] = cdPair.Value?.ToString() ?? string.Empty;
}
templateParameters.Add(
- new BlobTemplateParameter(item.Name.ToString(), "choice")
+ new BlobTemplateParameter(item.Key, "choice")
{
Choices = choicesAndDescriptions
});
- legacyTags[item.Name.ToString()] = new BlobLegacyCacheTag(
+ legacyTags[item.Key] = new BlobLegacyCacheTag(
description: tagObj.ToString("description"),
choicesAndDescriptions: legacyChoices,
defaultValue: tagObj.ToString("defaultValue"),
defaultIfOptionWithoutValue: tagObj.ToString("defaultIfOptionWithoutValue"));
}
- tags[item.Name.ToString()] = tagObj.ToString("defaultValue") ?? string.Empty;
+ tags[item.Key] = tagObj.ToString("defaultValue") ?? string.Empty;
}
}
info.Tags = legacyTags;
}
- JObject? cacheParametersObject = entry.Get("cacheParameters");
+ JsonObject? cacheParametersObject = entry.Get("cacheParameters");
if (!readParameters && cacheParametersObject != null)
{
Dictionary legacyParams = new Dictionary();
- foreach (JProperty item in cacheParametersObject.Properties())
+ foreach (var item in cacheParametersObject)
{
- JObject paramObj = (JObject)item.Value;
- if (paramObj == null)
+ if (item.Value is not JsonObject paramObj)
{
continue;
}
string dataType = paramObj.ToString(nameof(BlobTemplateParameter.DataType)) ?? "string";
- templateParameters.Add(new BlobTemplateParameter(item.Name.ToString(), dataType));
- legacyParams[item.Name.ToString()] = new BlobLegacyCacheParameter(
+ templateParameters.Add(new BlobTemplateParameter(item.Key, dataType));
+ legacyParams[item.Key] = new BlobLegacyCacheParameter(
description: paramObj.ToString("description"),
dataType: paramObj.ToString(nameof(BlobTemplateParameter.DataType)) ?? "string",
defaultValue: paramObj.ToString("defaultValue"),
@@ -320,10 +307,8 @@ public static BlobStorageTemplateInfo FromJObject(JObject entry)
private class BaselineCacheInfo : IBaselineInfo
{
- [JsonProperty]
public string? Description { get; set; }
- [JsonProperty]
public IReadOnlyDictionary DefaultOverrides { get; set; } = new Dictionary();
}
@@ -362,7 +347,7 @@ internal BlobTemplateParameter(string name, string dataType)
Precedence = TemplateParameterPrecedence.Default;
}
- internal BlobTemplateParameter(JObject jObject)
+ internal BlobTemplateParameter(JsonObject jObject)
{
string? name = jObject.ToString(nameof(Name));
if (string.IsNullOrWhiteSpace(name))
@@ -376,13 +361,13 @@ internal BlobTemplateParameter(JObject jObject)
if (DataType.Equals("choice", StringComparison.OrdinalIgnoreCase))
{
Dictionary choices = new Dictionary(StringComparer.OrdinalIgnoreCase);
- JObject? cdToken = jObject.Get(nameof(Choices));
+ JsonObject? cdToken = jObject.Get(nameof(Choices));
if (cdToken != null)
{
- foreach (JProperty cdPair in cdToken.Properties())
+ foreach (var cdPair in cdToken)
{
choices.Add(
- cdPair.Name.ToString(),
+ cdPair.Key,
new ParameterChoice(
cdPair.Value.ToString(nameof(ParameterChoice.DisplayName)),
cdPair.Value.ToString(nameof(ParameterChoice.Description))));
@@ -399,13 +384,10 @@ internal BlobTemplateParameter(JObject jObject)
Precedence = jObject.ToTemplateParameterPrecedence(nameof(Precedence));
}
- [JsonProperty]
public string Name { get; internal set; }
- [JsonProperty]
public string DataType { get; internal set; }
- [JsonProperty]
public IReadOnlyDictionary? Choices { get; internal set; }
[JsonIgnore]
@@ -422,23 +404,19 @@ internal BlobTemplateParameter(JObject jObject)
[JsonIgnore]
bool ITemplateParameter.IsName => false;
- [JsonProperty]
public string? DefaultValue { get; internal set; }
[JsonIgnore]
- string ITemplateParameter.DisplayName => throw new NotImplementedException();
+ string ITemplateParameter.DisplayName => string.Empty;
- [JsonProperty]
public string? DefaultIfOptionWithoutValue { get; internal set; }
- [JsonProperty]
public string? Description { get; internal set; }
[Obsolete]
[JsonIgnore]
- string ITemplateParameter.Documentation => throw new NotImplementedException();
+ string ITemplateParameter.Documentation => string.Empty;
- [JsonProperty]
public bool AllowMultipleValues { get; internal set; }
public override bool Equals(object obj)
@@ -471,23 +449,19 @@ public BlobLegacyCacheTag(string? description, IReadOnlyDictionary ChoicesAndDescriptions { get; }
- [JsonProperty]
public string? DefaultValue { get; }
- [JsonProperty]
public string? DefaultIfOptionWithoutValue { get; }
[JsonIgnore]
- public string DisplayName => throw new NotImplementedException();
+ public string DisplayName => string.Empty;
[JsonIgnore]
- public IReadOnlyDictionary Choices => throw new NotImplementedException();
+ public IReadOnlyDictionary Choices => new Dictionary();
}
@@ -501,20 +475,16 @@ public BlobLegacyCacheParameter(string? description, string? dataType, string? d
DefaultIfOptionWithoutValue = defaultIfOptionWithoutValue;
}
- [JsonProperty]
public string? DataType { get; }
- [JsonProperty]
public string? DefaultValue { get; }
- [JsonProperty]
public string? Description { get; }
- [JsonProperty]
public string? DefaultIfOptionWithoutValue { get; }
[JsonIgnore]
- public string DisplayName => throw new NotImplementedException();
+ public string DisplayName => string.Empty;
}
}
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/LegacySearchCacheReader.cs b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/LegacySearchCacheReader.cs
index ee6c1acd6c8..78b7f574cfd 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/LegacySearchCacheReader.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/LegacySearchCacheReader.cs
@@ -2,9 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections;
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
+using Microsoft.TemplateEngine;
using Microsoft.TemplateEngine.Abstractions;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateSearch.Common
{
@@ -56,12 +58,12 @@ internal static bool TryReadDiscoveryMetadata(IEngineEnvironmentSettings environ
environmentSettings.Host.Logger.LogDebug($"Reading cache file {pathToConfig}");
string cacheText = environmentSettings.Host.FileSystem.ReadAllText(pathToConfig);
- JObject cacheObject = JObject.Parse(cacheText);
+ JsonObject cacheObject = JExtensions.ParseJsonObject(cacheText);
return TryReadDiscoveryMetadata(cacheObject, environmentSettings.Host.Logger, additionalDataReaders, out discoveryMetadata);
}
- internal static bool TryReadDiscoveryMetadata(JObject cacheObject, ILogger logger, IReadOnlyDictionary>? additionalDataReaders, out TemplateDiscoveryMetadata? discoveryMetadata)
+ internal static bool TryReadDiscoveryMetadata(JsonObject cacheObject, ILogger logger, IReadOnlyDictionary>? additionalDataReaders, out TemplateDiscoveryMetadata? discoveryMetadata)
{
// add the reader calls, build the model objects
if (TryReadVersion(logger, cacheObject, out string? version)
@@ -76,12 +78,12 @@ internal static bool TryReadDiscoveryMetadata(JObject cacheObject, ILogger logge
return false;
}
- private static bool TryReadVersion(ILogger logger, JObject cacheObject, out string? version)
+ private static bool TryReadVersion(ILogger logger, JsonObject cacheObject, out string? version)
{
logger.LogDebug($"Reading template metadata version");
- if (cacheObject.TryGetValue(nameof(TemplateDiscoveryMetadata.Version), out JToken? value))
+ if (cacheObject.TryGetValueCaseInsensitive(nameof(TemplateDiscoveryMetadata.Version), out JsonNode? value))
{
- version = value.Value();
+ version = value?.ToString();
logger.LogDebug($"Version: {version}.");
return true;
}
@@ -92,26 +94,26 @@ private static bool TryReadVersion(ILogger logger, JObject cacheObject, out stri
private static bool TryReadTemplateList(
ILogger logger,
- JObject cacheObject,
+ JsonObject cacheObject,
out IReadOnlyList? templateList)
{
logger.LogDebug($"Reading template list");
try
{
// This is lifted from TemplateCache.ParseCacheContent - almost identical
- if (cacheObject.TryGetValue(nameof(TemplateDiscoveryMetadata.TemplateCache), StringComparison.OrdinalIgnoreCase, out JToken? templateInfoToken))
+ if (cacheObject.TryGetValueCaseInsensitive(nameof(TemplateDiscoveryMetadata.TemplateCache), out JsonNode? templateInfoToken))
{
List buildingTemplateList = new List();
- if (templateInfoToken is JArray arr)
+ if (templateInfoToken is JsonArray arr)
{
- foreach (JToken entry in arr)
+ foreach (JsonNode? entry in arr)
{
- if (entry != null && entry.Type == JTokenType.Object)
+ if (entry is JsonObject entryObj)
{
try
{
- buildingTemplateList.Add(BlobStorageTemplateInfo.FromJObject((JObject)entry));
+ buildingTemplateList.Add(BlobStorageTemplateInfo.FromJObject(entryObj));
}
catch (ArgumentException ex)
{
@@ -138,13 +140,13 @@ private static bool TryReadTemplateList(
}
}
- private static bool TryReadPackToTemplateMap(ILogger logger, JObject cacheObject, out IReadOnlyDictionary? packToTemplateMap)
+ private static bool TryReadPackToTemplateMap(ILogger logger, JsonObject cacheObject, out IReadOnlyDictionary? packToTemplateMap)
{
logger.LogDebug($"Reading package information.");
try
{
- if (!cacheObject.TryGetValue(nameof(TemplateDiscoveryMetadata.PackToTemplateMap), out JToken? packToTemplateMapToken)
- || packToTemplateMapToken is not JObject packToTemplateMapObject)
+ JsonNode? packToTemplateMapToken = JExtensions.GetPropertyCaseInsensitive(cacheObject, nameof(TemplateDiscoveryMetadata.PackToTemplateMap));
+ if (packToTemplateMapToken is not JsonObject packToTemplateMapObject)
{
logger.LogDebug($"Failed to read package info entries. Details: no PackToTemplateMap property found.");
packToTemplateMap = null;
@@ -153,25 +155,25 @@ private static bool TryReadPackToTemplateMap(ILogger logger, JObject cacheObject
Dictionary workingPackToTemplateMap = new();
- foreach (JProperty packEntry in packToTemplateMapObject.Properties())
+ foreach (var packEntry in packToTemplateMapObject)
{
- if (packEntry != null)
+ if (packEntry.Value != null)
{
- string packName = packEntry.Name.ToString();
- JObject entryValue = (JObject)packEntry.Value;
+ string packName = packEntry.Key;
+ JsonObject entryValue = (JsonObject)packEntry.Value;
- if (entryValue.TryGetValue(nameof(PackToTemplateEntry.Version), StringComparison.OrdinalIgnoreCase, out JToken? versionToken)
- && versionToken.Type == JTokenType.String
- && entryValue.TryGetValue(nameof(PackToTemplateEntry.TemplateIdentificationEntry), StringComparison.OrdinalIgnoreCase, out JToken? identificationToken)
- && identificationToken is JArray identificationArray)
+ JsonNode? versionNode = JExtensions.GetPropertyCaseInsensitive(entryValue, nameof(PackToTemplateEntry.Version));
+ JsonNode? identificationNode = JExtensions.GetPropertyCaseInsensitive(entryValue, nameof(PackToTemplateEntry.TemplateIdentificationEntry));
+ if (versionNode is JsonValue versionVal && versionVal.GetValueKind() == JsonValueKind.String
+ && identificationNode is JsonArray identificationArray)
{
- string? version = versionToken.Value() ?? throw new Exception("Version value is null.");
+ string? version = versionNode.ToString() ?? throw new Exception("Version value is null.");
List templatesInPack = new List();
- foreach (JToken templateIdentityInfo in identificationArray)
+ foreach (JsonNode? templateIdentityInfo in identificationArray)
{
- string? identity = templateIdentityInfo.Value(nameof(TemplateIdentificationEntry.Identity));
- string? groupIdentity = templateIdentityInfo.Value(nameof(TemplateIdentificationEntry.GroupIdentity));
+ string? identity = templateIdentityInfo?.ToString(nameof(TemplateIdentificationEntry.Identity));
+ string? groupIdentity = templateIdentityInfo?.ToString(nameof(TemplateIdentificationEntry.GroupIdentity));
if (identity == null)
{
@@ -182,8 +184,8 @@ private static bool TryReadPackToTemplateMap(ILogger logger, JObject cacheObject
}
workingPackToTemplateMap[packName] = new PackToTemplateEntry(version, templatesInPack);
- if (entryValue.TryGetValue(nameof(PackToTemplateEntry.TotalDownloads), out JToken? totalDownloadsToken)
- && long.TryParse(totalDownloadsToken.Value(), out long totalDownloads))
+ if (entryValue.TryGetValueCaseInsensitive(nameof(PackToTemplateEntry.TotalDownloads), out JsonNode? totalDownloadsNode)
+ && long.TryParse(totalDownloadsNode?.ToString(), out long totalDownloads))
{
workingPackToTemplateMap[packName].TotalDownloads = totalDownloads;
}
@@ -203,7 +205,7 @@ private static bool TryReadPackToTemplateMap(ILogger logger, JObject cacheObject
}
}
- private static bool TryReadAdditionalData(ILogger logger, JObject cacheObject, IReadOnlyDictionary>? additionalDataReaders, out IReadOnlyDictionary? additionalData)
+ private static bool TryReadAdditionalData(ILogger logger, JsonObject cacheObject, IReadOnlyDictionary>? additionalDataReaders, out IReadOnlyDictionary? additionalData)
{
if (additionalDataReaders == null)
{
@@ -212,8 +214,8 @@ private static bool TryReadAdditionalData(ILogger logger, JObject cacheObject, I
}
logger.LogDebug($"Reading additional information.");
// get the additional data section
- if (!cacheObject.TryGetValue(nameof(TemplateDiscoveryMetadata.AdditionalData), out JToken? additionalDataToken)
- || additionalDataToken is not JObject additionalDataObject)
+ JsonNode? additionalDataToken = JExtensions.GetPropertyCaseInsensitive(cacheObject, nameof(TemplateDiscoveryMetadata.AdditionalData));
+ if (additionalDataToken is not JsonObject additionalDataObject)
{
logger.LogDebug($"Failed to read package info entries. Details: no AdditionalData property found.");
additionalData = null;
@@ -227,8 +229,8 @@ private static bool TryReadAdditionalData(ILogger logger, JObject cacheObject, I
try
{
// get the entry for this piece of additional data
- if (!additionalDataObject.TryGetValue(dataReadInfo.Key, StringComparison.OrdinalIgnoreCase, out JToken? dataToken)
- || dataToken is not JObject dataObject)
+ JsonNode? dataNode = JExtensions.GetPropertyCaseInsensitive(additionalDataObject, dataReadInfo.Key);
+ if (dataNode is not JsonObject dataObject)
{
// this piece of data wasn't found, or wasn't valid. Ignore it.
continue;
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackInfo.cs b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackInfo.cs
index 9d0c1f4d1a5..deb6d88d979 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackInfo.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackInfo.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.TemplateSearch.Common.Abstractions;
-using Newtonsoft.Json;
namespace Microsoft.TemplateSearch.Common
{
@@ -24,19 +23,14 @@ internal PackInfo(string name, string version, long totalDownloads, IEnumerable<
Reserved = reserved;
}
- [JsonProperty]
public string Name { get; }
- [JsonProperty]
public string Version { get; }
- [JsonProperty]
public long TotalDownloads { get; }
- [JsonProperty]
public IReadOnlyList Owners { get; } = [];
- [JsonProperty]
public bool Reserved { get; }
//not supported for v1
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackToTemplateEntry.cs b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackToTemplateEntry.cs
index 269095a0a45..1bc240a8957 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackToTemplateEntry.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/PackToTemplateEntry.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json;
+using System.Text.Json.Serialization;
namespace Microsoft.TemplateSearch.Common
{
@@ -14,19 +14,19 @@ internal PackToTemplateEntry(string version, List t
TemplateIdentificationEntry = templateIdentificationEntry;
}
- [JsonProperty]
+ [JsonInclude]
internal string Version { get; }
- [JsonProperty]
+ [JsonInclude]
internal long TotalDownloads { get; set; }
- [JsonProperty]
+ [JsonInclude]
internal IReadOnlyList Owners { get; set; } = [];
- [JsonProperty]
+ [JsonInclude]
internal bool Reserved { get; set; }
- [JsonProperty]
+ [JsonInclude]
internal IReadOnlyList TemplateIdentificationEntry { get; }
}
}
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateDiscoveryMetadata.cs b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateDiscoveryMetadata.cs
index 0fe64655b97..b5e92825580 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateDiscoveryMetadata.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateDiscoveryMetadata.cs
@@ -1,9 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
+using Microsoft.TemplateEngine;
using Microsoft.TemplateEngine.Abstractions;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateSearch.Common
{
@@ -18,21 +19,21 @@ internal TemplateDiscoveryMetadata(string version, IReadOnlyList
AdditionalData = additionalData;
}
- [JsonProperty]
+ [JsonInclude]
internal string Version { get; }
- [JsonProperty]
+ [JsonInclude]
internal IReadOnlyList TemplateCache { get; }
- [JsonProperty]
+ [JsonInclude]
internal IReadOnlyDictionary PackToTemplateMap { get; }
- [JsonProperty]
+ [JsonInclude]
internal IReadOnlyDictionary AdditionalData { get; }
- internal JObject ToJObject()
+ internal JsonObject ToJObject()
{
- return JObject.FromObject(this);
+ return JExtensions.FromObject(this);
}
}
}
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateIdentificationEntry.cs b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateIdentificationEntry.cs
index c8e54773e18..8a8ccdb4661 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateIdentificationEntry.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateDiscoveryMetadata/TemplateIdentificationEntry.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json;
+using System.Text.Json.Serialization;
namespace Microsoft.TemplateSearch.Common
{
@@ -14,10 +14,10 @@ internal TemplateIdentificationEntry(string identity, string? groupIdentity)
GroupIdentity = groupIdentity;
}
- [JsonProperty]
+ [JsonInclude]
internal string Identity { get; }
- [JsonProperty]
+ [JsonInclude]
internal string? GroupIdentity { get; }
}
}
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplatePackageSearchData.Json.cs b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplatePackageSearchData.Json.cs
index fb1a956737b..c2f1e14101e 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplatePackageSearchData.Json.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplatePackageSearchData.Json.cs
@@ -1,17 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateSearch.Common
{
- [JsonConverter(typeof(TemplatePackageSearchDataJsonConverter))]
+ [System.Text.Json.Serialization.JsonConverter(typeof(TemplatePackageSearchDataJsonConverter))]
public partial class TemplatePackageSearchData
{
- internal TemplatePackageSearchData(JObject jObject, ILogger logger, IReadOnlyDictionary>? additionalDataReaders = null)
+ internal TemplatePackageSearchData(JsonObject jObject, ILogger logger, IReadOnlyDictionary>? additionalDataReaders = null)
{
if (jObject is null)
{
@@ -27,20 +27,20 @@ internal TemplatePackageSearchData(JObject jObject, ILogger logger, IReadOnlyDic
: throw new ArgumentException($"{nameof(jObject)} doesn't have {nameof(Name)} property or it is not a string.", nameof(jObject));
Version = jObject.ToString(nameof(Version));
TotalDownloads = jObject.ToInt32(nameof(TotalDownloads));
- Owners = jObject.Get(nameof(Owners)).JTokenStringOrArrayToCollection([]);
+ Owners = jObject.Get(nameof(Owners)).JTokenStringOrArrayToCollection([]);
Reserved = jObject.ToBool(nameof(Reserved));
Description = jObject.ToString(nameof(Description));
IconUrl = jObject.ToString(nameof(IconUrl));
- JArray? templatesData = jObject.Get(nameof(Templates))
+ JsonArray? templatesData = jObject.Get(nameof(Templates))
?? throw new ArgumentException($"{nameof(jObject)} doesn't have {nameof(Templates)} property or it is not an array.", nameof(jObject));
List templates = new List();
- foreach (JToken template in templatesData)
+ foreach (JsonNode? template in templatesData)
{
try
{
- if (template is JObject templateObj)
+ if (template is JsonObject templateObj)
{
templates.Add(new TemplateSearchData(templateObj, logger, additionalDataReaders));
}
@@ -62,12 +62,12 @@ internal TemplatePackageSearchData(JObject jObject, ILogger logger, IReadOnlyDic
}
#region JsonConverter
- private class TemplatePackageSearchDataJsonConverter : JsonConverter
+ private class TemplatePackageSearchDataJsonConverter : System.Text.Json.Serialization.JsonConverter
{
- public override TemplatePackageSearchData ReadJson(JsonReader reader, Type objectType, TemplatePackageSearchData? existingValue, bool hasExistingValue, JsonSerializer serializer)
+ public override TemplatePackageSearchData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> throw new NotImplementedException();
- public override void WriteJson(JsonWriter writer, TemplatePackageSearchData? value, JsonSerializer serializer)
+ public override void Write(Utf8JsonWriter writer, TemplatePackageSearchData value, JsonSerializerOptions options)
{
if (value == null)
{
@@ -75,30 +75,30 @@ public override void WriteJson(JsonWriter writer, TemplatePackageSearchData? val
}
writer.WriteStartObject();
writer.WritePropertyName(nameof(Name));
- writer.WriteValue(value.Name);
+ writer.WriteStringValue(value.Name);
if (!string.IsNullOrWhiteSpace(value.Version))
{
writer.WritePropertyName(nameof(Version));
- writer.WriteValue(value.Version);
+ writer.WriteStringValue(value.Version);
}
if (value.TotalDownloads != 0)
{
writer.WritePropertyName(nameof(TotalDownloads));
- writer.WriteValue(value.TotalDownloads);
+ writer.WriteNumberValue(value.TotalDownloads);
}
if (value.Owners.Any())
{
writer.WritePropertyName(nameof(Owners));
if (value.Owners.Count == 1)
{
- writer.WriteValue(value.Owners[0]);
+ writer.WriteStringValue(value.Owners[0]);
}
else
{
writer.WriteStartArray();
foreach (string owner in value.Owners)
{
- writer.WriteValue(owner);
+ writer.WriteStringValue(owner);
}
writer.WriteEndArray();
}
@@ -107,28 +107,28 @@ public override void WriteJson(JsonWriter writer, TemplatePackageSearchData? val
if (value.Reserved)
{
writer.WritePropertyName(nameof(Reserved));
- writer.WriteValue(value.Reserved);
+ writer.WriteBooleanValue(value.Reserved);
}
if (!string.IsNullOrWhiteSpace(value.Description))
{
writer.WritePropertyName(nameof(Description));
- writer.WriteValue(value.Description);
+ writer.WriteStringValue(value.Description);
}
if (!string.IsNullOrWhiteSpace(value.IconUrl))
{
writer.WritePropertyName(nameof(IconUrl));
- writer.WriteValue(value.IconUrl);
+ writer.WriteStringValue(value.IconUrl);
}
writer.WritePropertyName(nameof(Templates));
- serializer.Serialize(writer, value.Templates);
+ JsonSerializer.Serialize(writer, value.Templates, options);
if (value.AdditionalData.Any())
{
foreach (var item in value.AdditionalData)
{
writer.WritePropertyName(item.Key);
- serializer.Serialize(writer, item.Value);
+ JsonSerializer.Serialize(writer, item.Value, options);
}
}
writer.WriteEndObject();
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.Json.cs b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.Json.cs
index ffea8ea8fbe..1bb26f57551 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.Json.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.Json.cs
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateSearch.Common
{
@@ -12,7 +12,7 @@ internal partial class TemplateSearchCache
private static readonly string[] SupportedVersions = new[] { "1.0.0.0", "1.0.0.3", "2.0" };
internal static TemplateSearchCache FromJObject(
- JObject cacheObject,
+ JsonObject cacheObject,
ILogger logger,
IReadOnlyDictionary>? additionalDataReaders = null)
{
@@ -46,14 +46,14 @@ internal static TemplateSearchCache FromJObject(
}
- JArray? data = cacheObject.Get(nameof(TemplatePackages))
+ JsonArray? data = cacheObject.Get(nameof(TemplatePackages))
?? throw new Exception(LocalizableStrings.TemplateSearchCache_Exception_NotValid);
List templatePackages = new();
- foreach (JToken templatePackage in data)
+ foreach (JsonNode? templatePackage in data)
{
try
{
- if (templatePackage is not JObject templatePackageObj)
+ if (templatePackage is not JsonObject templatePackageObj)
{
throw new Exception($"Unexpected data in template search cache data, property: {nameof(TemplatePackages)}, value: {templatePackage}");
}
@@ -68,15 +68,15 @@ internal static TemplateSearchCache FromJObject(
}
internal static IDictionary ReadAdditionalData(
- JObject cacheObject,
+ JsonObject cacheObject,
IReadOnlyDictionary> additionalDataReaders,
ILogger logger)
{
Dictionary additionalData = new(StringComparer.OrdinalIgnoreCase);
foreach (KeyValuePair> dataReadInfo in additionalDataReaders)
{
- if (!cacheObject.TryGetValue(dataReadInfo.Key, StringComparison.OrdinalIgnoreCase, out JToken? dataToken)
- || dataToken is not JObject dataObject)
+ JsonNode? dataNode = JExtensions.GetPropertyCaseInsensitive(cacheObject, dataReadInfo.Key);
+ if (dataNode is not JsonObject dataObject)
{
// this piece of data wasn't found, or wasn't valid. Ignore it.
continue;
@@ -96,12 +96,12 @@ internal static IDictionary ReadAdditionalData(
return additionalData;
}
- internal JObject ToJObject()
+ internal JsonObject ToJObject()
{
- return JObject.FromObject(this);
+ return JExtensions.FromObject(this);
}
- private static bool TryReadVersion(ILogger logger, JObject cacheObject, out string? version)
+ private static bool TryReadVersion(ILogger logger, JsonObject cacheObject, out string? version)
{
logger.LogDebug($"Reading template search cache version");
version = cacheObject.ToString(nameof(Version));
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.cs b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.cs
index 52de55a828c..1c71edb54c3 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchCache.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Newtonsoft.Json;
+using System.Text.Json.Serialization;
namespace Microsoft.TemplateSearch.Common
{
@@ -23,10 +23,10 @@ private TemplateSearchCache(IReadOnlyList data, strin
Version = version;
}
- [JsonProperty]
+ [JsonInclude]
internal IReadOnlyList TemplatePackages { get; }
- [JsonProperty]
+ [JsonInclude]
internal string Version { get; private set; }
}
}
diff --git a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchData.Json.cs b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchData.Json.cs
index 1aa8a403e8d..1c9d0a82bea 100644
--- a/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchData.Json.cs
+++ b/src/Microsoft.TemplateSearch.Common/TemplateSearchCache/TemplateSearchData.Json.cs
@@ -1,17 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Abstractions;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateSearch.Common
{
- [JsonConverter(typeof(TemplateSearchData.TemplateSearchDataJsonConverter))]
+ [System.Text.Json.Serialization.JsonConverter(typeof(TemplateSearchData.TemplateSearchDataJsonConverter))]
public partial class TemplateSearchData : ITemplateInfo
{
- internal TemplateSearchData(JObject jObject, ILogger logger, IReadOnlyDictionary>? additionalDataReaders = null)
+ internal TemplateSearchData(JsonObject jObject, ILogger logger, IReadOnlyDictionary>? additionalDataReaders = null)
{
if (jObject is null)
{
@@ -34,13 +34,13 @@ internal TemplateSearchData(JObject jObject, ILogger logger, IReadOnlyDictionary
}
#region JsonConverter
- private class TemplateSearchDataJsonConverter : JsonConverter
+ private class TemplateSearchDataJsonConverter : System.Text.Json.Serialization.JsonConverter
{
//falls back to default de-serializer if not implemented
- public override TemplateSearchData ReadJson(JsonReader reader, Type objectType, TemplateSearchData? existingValue, bool hasExistingValue, JsonSerializer serializer)
+ public override TemplateSearchData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> throw new NotImplementedException();
- public override void WriteJson(JsonWriter writer, TemplateSearchData? value, JsonSerializer serializer)
+ public override void Write(Utf8JsonWriter writer, TemplateSearchData value, JsonSerializerOptions options)
{
if (value == null)
{
@@ -48,43 +48,43 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
}
writer.WriteStartObject();
writer.WritePropertyName(nameof(ITemplateInfo.Identity));
- writer.WriteValue(value.TemplateInfo.Identity);
+ writer.WriteStringValue(value.TemplateInfo.Identity);
if (!string.IsNullOrWhiteSpace(value.TemplateInfo.GroupIdentity))
{
writer.WritePropertyName(nameof(ITemplateInfo.GroupIdentity));
- writer.WriteValue(value.TemplateInfo.GroupIdentity);
+ writer.WriteStringValue(value.TemplateInfo.GroupIdentity);
}
if (value.TemplateInfo.Precedence != 0)
{
writer.WritePropertyName(nameof(ITemplateInfo.Precedence));
- writer.WriteValue(value.TemplateInfo.Precedence);
+ writer.WriteNumberValue(value.TemplateInfo.Precedence);
}
writer.WritePropertyName(nameof(ITemplateInfo.Name));
- writer.WriteValue(value.TemplateInfo.Name);
+ writer.WriteStringValue(value.TemplateInfo.Name);
writer.WritePropertyName(nameof(ITemplateInfo.ShortNameList));
writer.WriteStartArray();
foreach (string shortName in value.TemplateInfo.ShortNameList)
{
if (!string.IsNullOrWhiteSpace(shortName))
{
- writer.WriteValue(shortName);
+ writer.WriteStringValue(shortName);
}
}
writer.WriteEndArray();
if (!string.IsNullOrWhiteSpace(value.TemplateInfo.Author))
{
writer.WritePropertyName(nameof(ITemplateInfo.Author));
- writer.WriteValue(value.TemplateInfo.Author);
+ writer.WriteStringValue(value.TemplateInfo.Author);
}
if (!string.IsNullOrWhiteSpace(value.TemplateInfo.Description))
{
writer.WritePropertyName(nameof(ITemplateInfo.Description));
- writer.WriteValue(value.TemplateInfo.Description);
+ writer.WriteStringValue(value.TemplateInfo.Description);
}
if (!string.IsNullOrWhiteSpace(value.TemplateInfo.ThirdPartyNotices))
{
writer.WritePropertyName(nameof(ITemplateInfo.ThirdPartyNotices));
- writer.WriteValue(value.TemplateInfo.ThirdPartyNotices);
+ writer.WriteStringValue(value.TemplateInfo.ThirdPartyNotices);
}
if (value.TemplateInfo.Classifications.Any())
@@ -95,7 +95,7 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
{
if (!string.IsNullOrWhiteSpace(classification))
{
- writer.WriteValue(classification);
+ writer.WriteStringValue(classification);
}
}
writer.WriteEndArray();
@@ -108,7 +108,7 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
foreach (var tag in value.TemplateInfo.TagsCollection)
{
writer.WritePropertyName(tag.Key);
- writer.WriteValue(tag.Value);
+ writer.WriteStringValue(tag.Value);
}
writer.WriteEndObject();
}
@@ -123,21 +123,21 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
{
writer.WriteStartObject();
writer.WritePropertyName(nameof(ITemplateParameter.Name));
- writer.WriteValue(param.Name);
+ writer.WriteStringValue(param.Name);
if (!string.IsNullOrWhiteSpace(param.DataType))
{
writer.WritePropertyName(nameof(ITemplateParameter.DataType));
- writer.WriteValue(param.DataType);
+ writer.WriteStringValue(param.DataType);
}
if (!string.IsNullOrWhiteSpace(param.Description))
{
writer.WritePropertyName(nameof(ITemplateParameter.Description));
- writer.WriteValue(param.Description);
+ writer.WriteStringValue(param.Description);
}
if (!string.IsNullOrWhiteSpace(param.DefaultIfOptionWithoutValue))
{
writer.WritePropertyName(nameof(ITemplateParameter.DefaultIfOptionWithoutValue));
- writer.WriteValue(param.DefaultIfOptionWithoutValue);
+ writer.WriteStringValue(param.DefaultIfOptionWithoutValue);
}
if (param.Choices != null && param.Choices.Any())
@@ -151,12 +151,12 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
if (!string.IsNullOrWhiteSpace(choice.Value.Description))
{
writer.WritePropertyName(nameof(ParameterChoice.Description));
- writer.WriteValue(choice.Value.Description);
+ writer.WriteStringValue(choice.Value.Description);
}
if (!string.IsNullOrWhiteSpace(choice.Value.DisplayName))
{
writer.WritePropertyName(nameof(ParameterChoice.DisplayName));
- writer.WriteValue(choice.Value.DisplayName);
+ writer.WriteStringValue(choice.Value.DisplayName);
}
writer.WriteEndObject();
}
@@ -170,7 +170,7 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
if (value.TemplateInfo.BaselineInfo.Any())
{
writer.WritePropertyName(nameof(ITemplateInfo.BaselineInfo));
- serializer.Serialize(writer, value.TemplateInfo.BaselineInfo);
+ JsonSerializer.Serialize(writer, value.TemplateInfo.BaselineInfo, options);
}
if (value.TemplateInfo.PostActions.Any())
@@ -179,7 +179,7 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
writer.WriteStartArray();
foreach (Guid guid in value.TemplateInfo.PostActions)
{
- writer.WriteValue(guid.ToString());
+ writer.WriteStringValue(guid.ToString());
}
writer.WriteEndArray();
}
@@ -189,7 +189,7 @@ public override void WriteJson(JsonWriter writer, TemplateSearchData? value, Jso
foreach (var item in value.AdditionalData)
{
writer.WritePropertyName(item.Key);
- serializer.Serialize(writer, item.Value);
+ JsonSerializer.Serialize(writer, item.Value, options);
}
}
diff --git a/src/Shared/JExtensions.cs b/src/Shared/JExtensions.cs
index 4d5eff8db3f..4ecbd81a7bc 100644
--- a/src/Shared/JExtensions.cs
+++ b/src/Shared/JExtensions.cs
@@ -1,42 +1,63 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Mount;
using Microsoft.TemplateEngine.Abstractions.PhysicalFileSystem;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine
{
internal static class JExtensions
{
- internal static string? ToString(this JToken? token, string? key)
+ private static readonly JsonDocumentOptions DocOptions = new() { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true };
+ private static readonly JsonNodeOptions NodeOptions = new() { PropertyNameCaseInsensitive = true };
+ private static readonly JsonSerializerOptions SerializerOptions = new()
+ {
+ PropertyNameCaseInsensitive = true,
+ WriteIndented = false,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ };
+
+ internal static string? ToString(this JsonNode? token, string? key)
{
if (key == null)
{
- if (token == null || token.Type != JTokenType.String)
+ if (token == null)
{
return null;
}
- return token.ToString();
+ if (token is JsonValue val && val.GetValueKind() == JsonValueKind.String)
+ {
+ return val.GetValue();
+ }
+
+ return null;
}
- if (token is not JObject obj)
+ if (token is not JsonObject obj)
{
return null;
}
- if (!obj.TryGetValue(key, StringComparison.OrdinalIgnoreCase, out JToken? element) || element.Type == JTokenType.Null)
+ JsonNode? element = GetPropertyCaseInsensitive(obj, key);
+ if (element == null || element.GetValueKind() == JsonValueKind.Null)
{
return null;
}
- return element.ToString();
+ if (element is JsonValue strVal && strVal.GetValueKind() == JsonValueKind.String)
+ {
+ return strVal.GetValue();
+ }
+
+ return element.ToJsonString();
}
- internal static bool TryGetValue(this JToken? token, string? key, out JToken? result)
+ internal static bool TryGetValue(this JsonNode? token, string? key, out JsonNode? result)
{
result = null;
@@ -49,25 +70,42 @@ internal static bool TryGetValue(this JToken? token, string? key, out JToken? re
{
result = token;
}
- else if (!((JObject)token).TryGetValue(key, StringComparison.OrdinalIgnoreCase, out result))
+ else
{
- return false;
+ result = GetPropertyCaseInsensitive(token.AsObject(), key);
+ if (result == null)
+ {
+ return false;
+ }
}
return true;
}
- internal static bool TryParseBool(this JToken token, out bool result)
+ internal static bool TryParseBool(this JsonNode token, out bool result)
{
result = false;
- return (token.Type == JTokenType.Boolean || token.Type == JTokenType.String)
- &&
- bool.TryParse(token.ToString(), out result);
+ var kind = token.GetValueKind();
+ if (kind == JsonValueKind.True)
+ {
+ result = true;
+ return true;
+ }
+ if (kind == JsonValueKind.False)
+ {
+ result = false;
+ return true;
+ }
+ if (kind == JsonValueKind.String)
+ {
+ return bool.TryParse(token.GetValue(), out result);
+ }
+ return false;
}
- internal static bool ToBool(this JToken? token, string? key = null, bool defaultValue = false)
+ internal static bool ToBool(this JsonNode? token, string? key = null, bool defaultValue = false)
{
- if (!token.TryGetValue(key, out JToken? checkToken))
+ if (!token.TryGetValue(key, out JsonNode? checkToken))
{
return defaultValue;
}
@@ -80,20 +118,31 @@ internal static bool ToBool(this JToken? token, string? key = null, bool default
return result;
}
- internal static bool TryParseInt(this JToken token, out int result)
+ internal static bool TryParseInt(this JsonNode token, out int result)
{
result = default;
- return (token.Type == JTokenType.Integer || token.Type == JTokenType.String)
- &&
- int.TryParse(token.ToString(), out result);
+ var kind = token.GetValueKind();
+ if (kind == JsonValueKind.Number)
+ {
+ if (token is JsonValue jv && jv.TryGetValue(out int intVal))
+ {
+ result = intVal;
+ return true;
+ }
+ return int.TryParse(token.ToJsonString(), out result);
+ }
+ if (kind == JsonValueKind.String)
+ {
+ return int.TryParse(token.GetValue(), out result);
+ }
+ return false;
}
- internal static int ToInt32(this JToken? token, string? key = null, int defaultValue = 0)
+ internal static int ToInt32(this JsonNode? token, string? key = null, int defaultValue = 0)
{
- int value;
if (key == null)
{
- if (token == null || token.Type != JTokenType.Integer || !int.TryParse(token.ToString(), out value))
+ if (token == null || !token.TryParseInt(out int value))
{
return defaultValue;
}
@@ -101,28 +150,21 @@ internal static int ToInt32(this JToken? token, string? key = null, int defaultV
return value;
}
- if (token is not JObject obj)
+ if (token is not JsonObject obj)
{
return defaultValue;
}
- if (!obj.TryGetValue(key, StringComparison.OrdinalIgnoreCase, out JToken? element))
+ JsonNode? element = GetPropertyCaseInsensitive(obj, key);
+ if (element == null || !element.TryParseInt(out int result))
{
return defaultValue;
}
- else if (element.Type == JTokenType.Integer)
- {
- return element.ToInt32();
- }
- else if (int.TryParse(element.ToString(), out value))
- {
- return value;
- }
- return defaultValue;
+ return result;
}
- internal static T ToEnum(this JToken token, string? key = null, T defaultValue = default, bool ignoreCase = false)
+ internal static T ToEnum(this JsonNode token, string? key = null, T defaultValue = default, bool ignoreCase = false)
where T : struct
{
string? val = token.ToString(key);
@@ -134,7 +176,7 @@ internal static T ToEnum(this JToken token, string? key = null, T defaultValu
return result;
}
- internal static Guid ToGuid(this JToken token, string? key = null, Guid defaultValue = default)
+ internal static Guid ToGuid(this JsonNode token, string? key = null, Guid defaultValue = default)
{
string? val = token.ToString(key);
if (val == null || !Guid.TryParse(val, out Guid result))
@@ -149,10 +191,10 @@ internal static Guid ToGuid(this JToken token, string? key = null, Guid defaultV
/// Reads as read only string list/>.
/// Property value may be string or array.
///
- internal static IReadOnlyList ToStringReadOnlyList(this JObject jObject, string propertyName, IReadOnlyList? defaultValue = null)
+ internal static IReadOnlyList ToStringReadOnlyList(this JsonObject jObject, string propertyName, IReadOnlyList? defaultValue = null)
{
defaultValue ??= [];
- JToken? token = jObject.Get(propertyName);
+ JsonNode? token = jObject.Get(propertyName);
if (token == null)
{
return defaultValue;
@@ -160,52 +202,49 @@ internal static IReadOnlyList ToStringReadOnlyList(this JObject jObject,
return token.JTokenStringOrArrayToCollection(defaultValue) ?? defaultValue;
}
- internal static IEnumerable PropertiesOf(this JToken? token, string? key = null)
+ internal static IEnumerable> PropertiesOf(this JsonNode? token, string? key = null)
{
- if (token is not JObject obj)
+ if (token is not JsonObject obj)
{
return [];
}
if (key != null)
{
- if (!obj.TryGetValue(key, StringComparison.OrdinalIgnoreCase, out JToken? element))
+ JsonNode? element = GetPropertyCaseInsensitive(obj, key);
+ if (element == null)
{
return [];
}
- return element is not JObject jObj ? [] : jObj.Properties();
+ return element is not JsonObject jObj ? [] : jObj.ToList();
}
- return obj.Properties();
+ return obj.ToList();
}
- internal static T? Get(this JToken? token, string? key)
- where T : JToken
+ internal static T? Get(this JsonNode? token, string? key)
+ where T : JsonNode
{
- if (token is not JObject obj || key == null)
- {
- return default;
- }
-
- if (!obj.TryGetValue(key, StringComparison.OrdinalIgnoreCase, out JToken? res))
+ if (token is not JsonObject obj || key == null)
{
return default;
}
+ JsonNode? res = GetPropertyCaseInsensitive(obj, key);
return res as T;
}
- internal static IReadOnlyDictionary ToStringDictionary(this JToken token, StringComparer? comparer = null, string? propertyName = null)
+ internal static IReadOnlyDictionary ToStringDictionary(this JsonNode token, StringComparer? comparer = null, string? propertyName = null)
{
Dictionary result = new(comparer ?? StringComparer.Ordinal);
- foreach (JProperty property in token.PropertiesOf(propertyName))
+ foreach (var property in token.PropertiesOf(propertyName))
{
- if (property.Value == null || property.Value.Type != JTokenType.String)
+ if (property.Value == null || property.Value.GetValueKind() != JsonValueKind.String)
{
continue;
}
- result[property.Name] = property.Value.ToString();
+ result[property.Key] = property.Value.GetValue();
}
return result;
@@ -213,15 +252,18 @@ internal static IReadOnlyDictionary ToStringDictionary(this JTok
///
/// Converts properties of to dictionary.
- /// Leaves the values as JToken.
+ /// Leaves the values as JsonNode.
///
- internal static IReadOnlyDictionary ToJTokenDictionary(this JToken token, StringComparer? comparer = null, string? propertyName = null)
+ internal static IReadOnlyDictionary ToJsonNodeDictionary(this JsonNode token, StringComparer? comparer = null, string? propertyName = null)
{
- Dictionary result = new(comparer ?? StringComparer.Ordinal);
+ Dictionary result = new(comparer ?? StringComparer.Ordinal);
- foreach (JProperty property in token.PropertiesOf(propertyName))
+ foreach (var property in token.PropertiesOf(propertyName))
{
- result[property.Name] = property.Value;
+ if (property.Value != null)
+ {
+ result[property.Key] = property.Value;
+ }
}
return result;
@@ -229,23 +271,26 @@ internal static IReadOnlyDictionary ToJTokenDictionary(this JTok
///
/// Converts properties of to dictionary.
- /// Values are serialized to string (as JToken). Strings are serialized as , i.e. needs to be parsed prior to be used.
+ /// Values are serialized to string (as JsonNode). Strings are serialized as JSON, i.e. needs to be parsed prior to be used.
///
- internal static IReadOnlyDictionary ToJTokenStringDictionary(this JToken token, StringComparer? comparer = null, string? propertyName = null)
+ internal static IReadOnlyDictionary ToJsonNodeStringDictionary(this JsonNode token, StringComparer? comparer = null, string? propertyName = null)
{
Dictionary result = new(comparer ?? StringComparer.Ordinal);
- foreach (JProperty property in token.PropertiesOf(propertyName))
+ foreach (var property in token.PropertiesOf(propertyName))
{
- result[property.Name] = property.Value.ToString(Formatting.None);
+ if (property.Value != null)
+ {
+ result[property.Key] = property.Value.ToJsonString();
+ }
}
return result;
}
- internal static TemplateParameterPrecedence ToTemplateParameterPrecedence(this JToken jObject, string? key)
+ internal static TemplateParameterPrecedence ToTemplateParameterPrecedence(this JsonNode jObject, string? key)
{
- if (!jObject.TryGetValue(key, out JToken? checkToken))
+ if (!jObject.TryGetValue(key, out JsonNode? checkToken))
{
return TemplateParameterPrecedence.Default;
}
@@ -258,50 +303,50 @@ internal static TemplateParameterPrecedence ToTemplateParameterPrecedence(this J
return new TemplateParameterPrecedence(precedenceDefinition, isRequiredCondition, isEnabledCondition, isRequired);
}
- internal static IReadOnlyList ArrayAsStrings(this JToken? token, string? propertyName = null)
+ internal static IReadOnlyList ArrayAsStrings(this JsonNode? token, string? propertyName = null)
{
if (propertyName != null)
{
- token = token.Get(propertyName);
+ token = token.Get(propertyName);
}
- if (token is not JArray arr)
+ if (token is not JsonArray arr)
{
return [];
}
List values = new();
- foreach (JToken item in arr)
+ foreach (JsonNode? item in arr)
{
- if (item != null && item.Type == JTokenType.String)
+ if (item != null && item.GetValueKind() == JsonValueKind.String)
{
- values.Add(item.ToString());
+ values.Add(item.GetValue());
}
}
return values;
}
- internal static IReadOnlyList ArrayAsGuids(this JToken? token, string? propertyName = null)
+ internal static IReadOnlyList ArrayAsGuids(this JsonNode? token, string? propertyName = null)
{
if (propertyName != null)
{
- token = token.Get(propertyName);
+ token = token.Get(propertyName);
}
- if (token is not JArray arr)
+ if (token is not JsonArray arr)
{
return [];
}
List values = new();
- foreach (JToken item in arr)
+ foreach (JsonNode? item in arr)
{
- if (item != null && item.Type == JTokenType.String)
+ if (item != null && item.GetValueKind() == JsonValueKind.String)
{
- if (Guid.TryParse(item.ToString(), out Guid val))
+ if (Guid.TryParse(item.GetValue(), out Guid val))
{
values.Add(val);
}
@@ -311,20 +356,20 @@ internal static IReadOnlyList ArrayAsGuids(this JToken? token, string? pro
return values;
}
- internal static IEnumerable Items(this JToken? token, string? propertyName = null)
- where T : JToken
+ internal static IEnumerable Items(this JsonNode? token, string? propertyName = null)
+ where T : JsonNode
{
if (propertyName != null)
{
- token = token.Get(propertyName);
+ token = token.Get(propertyName);
}
- if (token is not JArray arr)
+ if (token is not JsonArray arr)
{
yield break;
}
- foreach (JToken item in arr)
+ foreach (JsonNode? item in arr)
{
if (item is T res)
{
@@ -333,47 +378,40 @@ internal static IEnumerable Items(this JToken? token, string? propertyName
}
}
- internal static JObject ReadJObjectFromIFile(this IFile file)
+ internal static JsonObject ReadJObjectFromIFile(this IFile file)
{
using Stream s = file.OpenRead();
using TextReader tr = new StreamReader(s, System.Text.Encoding.UTF8, true);
- using JsonReader r = new JsonTextReader(tr);
- {
- return JObject.Load(r);
- }
+ string json = tr.ReadToEnd();
+ return (JsonObject?)JsonNode.Parse(json, NodeOptions, DocOptions)
+ ?? throw new InvalidOperationException("Failed to parse JSON from file.");
}
- internal static JObject ReadObject(this IPhysicalFileSystem fileSystem, string path)
+ internal static JsonObject ReadObject(this IPhysicalFileSystem fileSystem, string path)
{
using Stream fileStream = fileSystem.OpenRead(path);
using var textReader = new StreamReader(fileStream, System.Text.Encoding.UTF8, true);
- using var jsonReader = new JsonTextReader(textReader);
- {
- return JObject.Load(jsonReader);
- }
+ string json = textReader.ReadToEnd();
+ return (JsonObject?)JsonNode.Parse(json, NodeOptions, DocOptions)
+ ?? throw new InvalidOperationException($"Failed to parse JSON from '{path}'.");
}
internal static void WriteObject(this IPhysicalFileSystem fileSystem, string path, object obj)
{
using Stream fileStream = fileSystem.CreateFile(path);
- using var textWriter = new StreamWriter(fileStream, System.Text.Encoding.UTF8);
- using var jsonWriter = new JsonTextWriter(textWriter);
- {
- var serializer = new JsonSerializer();
- serializer.Serialize(jsonWriter, obj);
- }
+ JsonSerializer.Serialize(fileStream, obj, SerializerOptions);
}
- internal static IReadOnlyList JTokenStringOrArrayToCollection(this JToken? token, IReadOnlyList defaultSet)
+ internal static IReadOnlyList JTokenStringOrArrayToCollection(this JsonNode? token, IReadOnlyList defaultSet)
{
if (token == null)
{
return defaultSet;
}
- if (token.Type == JTokenType.String)
+ if (token.GetValueKind() == JsonValueKind.String)
{
- string tokenValue = token.ToString();
+ string tokenValue = token.GetValue();
return new List() { tokenValue };
}
@@ -382,11 +420,10 @@ internal static IReadOnlyList JTokenStringOrArrayToCollection(this JToke
///
/// Converts to valid JSON string.
- /// JToken.ToString() doesn't provide a valid JSON string for JTokenType == String.
///
internal static string ToJsonString(object obj)
{
- return JToken.FromObject(obj).ToString(Formatting.None);
+ return JsonSerializer.Serialize(obj, SerializerOptions);
}
internal static string ToCamelCase(this string str)
@@ -398,5 +435,111 @@ internal static string ToCamelCase(this string str)
};
}
+ ///
+ /// Tries to get a property value from a using case-insensitive key matching.
+ ///
+ internal static bool TryGetValueCaseInsensitive(this JsonObject obj, string key, out JsonNode? result)
+ {
+ result = GetPropertyCaseInsensitive(obj, key);
+ return result != null;
+ }
+
+ ///
+ /// Gets a property from a JsonObject with case-insensitive key matching.
+ ///
+ internal static JsonNode? GetPropertyCaseInsensitive(JsonObject obj, string key)
+ {
+ // Try exact match first (fast path).
+ if (obj.TryGetPropertyValue(key, out JsonNode? result))
+ {
+ return result;
+ }
+
+ // Fall back to case-insensitive search.
+ foreach (var kvp in obj)
+ {
+ if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase))
+ {
+ return kvp.Value;
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Parses a JSON string into a JsonObject (with comment/trailing comma support).
+ ///
+ internal static JsonObject ParseJsonObject(string json)
+ {
+ return (JsonObject?)JsonNode.Parse(json, NodeOptions, DocOptions)
+ ?? throw new InvalidOperationException("Failed to parse JSON string as JsonObject.");
+ }
+
+ ///
+ /// Parses a JSON string into a JsonNode (with comment/trailing comma support).
+ ///
+ internal static JsonNode? ParseJsonNode(string json)
+ {
+ return JsonNode.Parse(json, NodeOptions, DocOptions);
+ }
+
+ ///
+ /// Serializes an object to a JsonObject via JSON round-trip.
+ /// Equivalent to Newtonsoft's JObject.FromObject().
+ ///
+ internal static JsonObject FromObject(object obj)
+ {
+ string json = JsonSerializer.Serialize(obj, SerializerOptions);
+ return (JsonObject?)JsonNode.Parse(json, NodeOptions, DocOptions)
+ ?? throw new InvalidOperationException("Failed to round-trip object to JsonObject.");
+ }
+
+ ///
+ /// Creates a deep clone of a by round-tripping through JSON text.
+ ///
+ internal static JsonObject DeepCloneObject(this JsonObject source)
+ {
+ return (JsonObject?)JsonNode.Parse(source.ToJsonString(), NodeOptions, DocOptions)
+ ?? throw new InvalidOperationException("Failed to deep clone JsonObject.");
+ }
+
+ ///
+ /// Merges properties from into .
+ /// Equivalent to Newtonsoft's JObject.Merge() with default settings:
+ /// - Objects are recursively merged
+ /// - Arrays are concatenated
+ /// - Other values (including null) from source overwrite target.
+ ///
+ internal static void Merge(this JsonObject target, JsonObject source)
+ {
+ foreach (var property in source)
+ {
+ if (property.Value is JsonObject sourceObj
+ && target.TryGetPropertyValue(property.Key, out JsonNode? targetNode)
+ && targetNode is JsonObject targetObj)
+ {
+ // Recursively merge nested objects
+ targetObj.Merge(sourceObj);
+ }
+ else if (property.Value is JsonArray sourceArr
+ && target.TryGetPropertyValue(property.Key, out targetNode)
+ && targetNode is JsonArray targetArr)
+ {
+ // Concatenate arrays
+ foreach (var item in sourceArr)
+ {
+ targetArr.Add(item != null ? JsonNode.Parse(item.ToJsonString()) : null);
+ }
+ }
+ else
+ {
+ // Overwrite (or add) the property; clone value to detach from source tree
+ target[property.Key] = property.Value != null
+ ? JsonNode.Parse(property.Value.ToJsonString())
+ : null;
+ }
+ }
+ }
}
}
diff --git a/test/Microsoft.TemplateEngine.Authoring.CLI.IntegrationTests/ExportCommandTests.cs b/test/Microsoft.TemplateEngine.Authoring.CLI.IntegrationTests/ExportCommandTests.cs
index 01039bf238e..4e945be749c 100644
--- a/test/Microsoft.TemplateEngine.Authoring.CLI.IntegrationTests/ExportCommandTests.cs
+++ b/test/Microsoft.TemplateEngine.Authoring.CLI.IntegrationTests/ExportCommandTests.cs
@@ -1,14 +1,16 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.TestHelper;
using Microsoft.TemplateEngine.Tests;
-using Newtonsoft.Json.Linq;
namespace Microsoft.TemplateEngine.Authoring.CLI.IntegrationTests
{
public class ExportCommandTests : TestBase, IDisposable
{
+ private static readonly JsonDocumentOptions DocOptions = new() { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip };
private readonly string _workingDirectory;
public ExportCommandTests()
@@ -74,26 +76,26 @@ public async Task EnglishLocFilesAreOverwritten()
string deLocFile = Path.Combine(expectedExportDirectory, "templatestrings.de.json");
Assert.True(File.Exists(enLocFile));
Assert.True(File.Exists(deLocFile));
- var engJsonContent = JObject.Parse(File.ReadAllText(enLocFile));
- var deJsonContent = JObject.Parse(File.ReadAllText(deLocFile));
- Assert.Equal("Test Asset", engJsonContent.Property("author")?.Value.ToString());
- Assert.Equal("Test Asset", deJsonContent.Property("author")?.Value.ToString());
+ var engJsonContent = JsonNode.Parse(File.ReadAllText(enLocFile), documentOptions: DocOptions)!.AsObject();
+ var deJsonContent = JsonNode.Parse(File.ReadAllText(deLocFile), documentOptions: DocOptions)!.AsObject();
+ Assert.Equal("Test Asset", engJsonContent["author"]?.ToString());
+ Assert.Equal("Test Asset", deJsonContent["author"]?.ToString());
//modify author property
string baseConfig = Path.Combine(testTemplate, ".template.config", "template.json");
- var templateJsonContent = JObject.Parse(File.ReadAllText(baseConfig));
- Assert.NotNull(templateJsonContent.Property("author"));
- templateJsonContent.Property("author")!.Value = "New Author";
- File.WriteAllText(baseConfig, templateJsonContent.ToString());
+ var templateJsonContent = JsonNode.Parse(File.ReadAllText(baseConfig), documentOptions: DocOptions)!.AsObject();
+ Assert.NotNull(templateJsonContent["author"]);
+ templateJsonContent["author"] = "New Author";
+ File.WriteAllText(baseConfig, templateJsonContent.ToJsonString());
runResult = await Program.Main(new[] { "localize", "export", testTemplate });
Assert.Equal(0, runResult);
Assert.True(File.Exists(enLocFile));
Assert.True(File.Exists(deLocFile));
- engJsonContent = JObject.Parse(File.ReadAllText(enLocFile));
- deJsonContent = JObject.Parse(File.ReadAllText(deLocFile));
- Assert.Equal("New Author", engJsonContent.Property("author")?.Value.ToString());
- Assert.Equal("Test Asset", deJsonContent.Property("author")?.Value.ToString());
+ engJsonContent = JsonNode.Parse(File.ReadAllText(enLocFile), documentOptions: DocOptions)!.AsObject();
+ deJsonContent = JsonNode.Parse(File.ReadAllText(deLocFile), documentOptions: DocOptions)!.AsObject();
+ Assert.Equal("New Author", engJsonContent["author"]?.ToString());
+ Assert.Equal("Test Asset", deJsonContent["author"]?.ToString());
}
[Fact]
@@ -101,9 +103,9 @@ public async Task TemplateLanguageLocFilesAreOverwritten()
{
string testTemplate = GetTestTemplateInTempDir("TemplateWithSourceName");
string baseConfig = Path.Combine(testTemplate, ".template.config", "template.json");
- var templateJsonContent = JObject.Parse(File.ReadAllText(baseConfig));
- templateJsonContent.AddFirst(new JProperty("authoringLanguage", "de"));
- File.WriteAllText(baseConfig, templateJsonContent.ToString());
+ var templateJsonContent = JsonNode.Parse(File.ReadAllText(baseConfig), documentOptions: DocOptions)!.AsObject();
+ templateJsonContent.Insert(0, "authoringLanguage", "de");
+ File.WriteAllText(baseConfig, templateJsonContent.ToJsonString());
int runResult = await Program.Main(new[] { "localize", "export", testTemplate });
Assert.Equal(0, runResult);
@@ -112,25 +114,25 @@ public async Task TemplateLanguageLocFilesAreOverwritten()
string deLocFile = Path.Combine(expectedExportDirectory, "templatestrings.de.json");
Assert.True(File.Exists(enLocFile));
Assert.True(File.Exists(deLocFile));
- var engJsonContent = JObject.Parse(File.ReadAllText(enLocFile));
- var deJsonContent = JObject.Parse(File.ReadAllText(deLocFile));
- Assert.Equal("Test Asset", engJsonContent.Property("author")?.Value.ToString());
- Assert.Equal("Test Asset", deJsonContent.Property("author")?.Value.ToString());
+ var engJsonContent = JsonNode.Parse(File.ReadAllText(enLocFile), documentOptions: DocOptions)!.AsObject();
+ var deJsonContent = JsonNode.Parse(File.ReadAllText(deLocFile), documentOptions: DocOptions)!.AsObject();
+ Assert.Equal("Test Asset", engJsonContent["author"]?.ToString());
+ Assert.Equal("Test Asset", deJsonContent["author"]?.ToString());
//modify author property
- templateJsonContent = JObject.Parse(File.ReadAllText(baseConfig));
- Assert.NotNull(templateJsonContent.Property("author"));
- templateJsonContent.Property("author")!.Value = "New Author";
- File.WriteAllText(baseConfig, templateJsonContent.ToString());
+ templateJsonContent = JsonNode.Parse(File.ReadAllText(baseConfig), documentOptions: DocOptions)!.AsObject();
+ Assert.NotNull(templateJsonContent["author"]);
+ templateJsonContent["author"] = "New Author";
+ File.WriteAllText(baseConfig, templateJsonContent.ToJsonString());
runResult = await Program.Main(new[] { "localize", "export", testTemplate });
Assert.Equal(0, runResult);
Assert.True(File.Exists(enLocFile));
Assert.True(File.Exists(deLocFile));
- engJsonContent = JObject.Parse(File.ReadAllText(enLocFile));
- deJsonContent = JObject.Parse(File.ReadAllText(deLocFile));
- Assert.Equal("New Author", deJsonContent.Property("author")?.Value.ToString());
- Assert.Equal("Test Asset", engJsonContent.Property("author")?.Value.ToString());
+ engJsonContent = JsonNode.Parse(File.ReadAllText(enLocFile), documentOptions: DocOptions)!.AsObject();
+ deJsonContent = JsonNode.Parse(File.ReadAllText(deLocFile), documentOptions: DocOptions)!.AsObject();
+ Assert.Equal("New Author", deJsonContent["author"]?.ToString());
+ Assert.Equal("Test Asset", engJsonContent["author"]?.ToString());
}
[Fact]
diff --git a/test/Microsoft.TemplateEngine.Edge.UnitTests/HostConstraintTests.cs b/test/Microsoft.TemplateEngine.Edge.UnitTests/HostConstraintTests.cs
index d36959b3823..9aa38b3d0f5 100644
--- a/test/Microsoft.TemplateEngine.Edge.UnitTests/HostConstraintTests.cs
+++ b/test/Microsoft.TemplateEngine.Edge.UnitTests/HostConstraintTests.cs
@@ -1,12 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using FakeItEasy;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Edge.Constraints;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.TemplateEngine.Edge.UnitTests
@@ -47,7 +48,7 @@ public async Task CanReadConfiguration_WithoutVersion()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Host.HostIdentifier).Returns("host1");
A.CallTo(() => settings.Host.Version).Returns("2.0.0");
@@ -92,7 +93,7 @@ public async Task CanReadConfiguration_ExactVersion()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Host.HostIdentifier).Returns("host2");
A.CallTo(() => settings.Host.Version).Returns("2.0.0");
@@ -140,7 +141,7 @@ public async Task CanReadConfiguration_VersionRange()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Host.HostIdentifier).Returns("host3");
@@ -173,7 +174,7 @@ public async Task FailsOnWrongConfiguration()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Host.HostIdentifier).Returns("host3");
@@ -223,7 +224,7 @@ public async Task CanProcessDifferentVersions(string configuredVersion, string h
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Host.HostIdentifier).Returns("host1");
A.CallTo(() => settings.Host.Version).Returns(hostVersion);
@@ -273,7 +274,7 @@ public async Task CanProcessDifferentHostNames(string hostName, string fallbackH
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Host.HostIdentifier).Returns(hostName);
A.CallTo(() => settings.Host.Version).Returns(hostVersion);
diff --git a/test/Microsoft.TemplateEngine.Edge.UnitTests/OSConstraintTests.cs b/test/Microsoft.TemplateEngine.Edge.UnitTests/OSConstraintTests.cs
index b6538855344..543bc83fe05 100644
--- a/test/Microsoft.TemplateEngine.Edge.UnitTests/OSConstraintTests.cs
+++ b/test/Microsoft.TemplateEngine.Edge.UnitTests/OSConstraintTests.cs
@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.InteropServices;
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel;
using Microsoft.TemplateEngine.TestHelper;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.TemplateEngine.Edge.UnitTests
@@ -36,7 +37,7 @@ public async Task CanReadStringConfiguration()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
var constraintManager = new TemplateConstraintManager(_sharedSettings);
var evaluateResult = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default);
@@ -69,7 +70,7 @@ public async Task CanReadArrayConfiguration()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
var constraintManager = new TemplateConstraintManager(_sharedSettings);
var evaluateResult = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default);
diff --git a/test/Microsoft.TemplateEngine.Edge.UnitTests/SdkVersionConstraintTests.cs b/test/Microsoft.TemplateEngine.Edge.UnitTests/SdkVersionConstraintTests.cs
index 2adbdf7d973..4434f79d8ee 100644
--- a/test/Microsoft.TemplateEngine.Edge.UnitTests/SdkVersionConstraintTests.cs
+++ b/test/Microsoft.TemplateEngine.Edge.UnitTests/SdkVersionConstraintTests.cs
@@ -1,13 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using FakeItEasy;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Components;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Edge.Constraints;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.TemplateEngine.Edge.UnitTests
@@ -37,7 +38,7 @@ public async Task Evaluate_ArrayOfVersions(string sdkVersion, bool allowed)
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
ISdkInfoProvider sdkInfoProvider = new SdkInfoProviderMock(sdkVersion); //A.Fake();
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Components.OfType()).Returns(new[] { sdkInfoProvider });
@@ -76,7 +77,7 @@ public async Task Evaluate_SingleVersionRange(string sdkVersion, bool allowed)
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
ISdkInfoProvider sdkInfoProvider = new SdkInfoProviderMock(sdkVersion); //A.Fake();
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Components.OfType()).Returns(new[] { sdkInfoProvider });
@@ -110,7 +111,7 @@ public async Task Evaluate_AlternativeInstalledVersions(string sdkVersion, IRead
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
ISdkInfoProvider sdkInfoProvider = new SdkInfoProviderMock(sdkVersion, installedVersions); //A.Fake();
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Components.OfType()).Returns(new[] { sdkInfoProvider });
diff --git a/test/Microsoft.TemplateEngine.Edge.UnitTests/TemplateCacheTests.cs b/test/Microsoft.TemplateEngine.Edge.UnitTests/TemplateCacheTests.cs
index d4c4fa1af0e..5701de9005b 100644
--- a/test/Microsoft.TemplateEngine.Edge.UnitTests/TemplateCacheTests.cs
+++ b/test/Microsoft.TemplateEngine.Edge.UnitTests/TemplateCacheTests.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
+using System.Text.Json;
+using System.Text.Json.Nodes;
using FakeItEasy;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Abstractions;
@@ -13,8 +15,6 @@
using Microsoft.TemplateEngine.Edge.Settings;
using Microsoft.TemplateEngine.TestHelper;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.TemplateEngine.Edge.UnitTests
@@ -330,7 +330,7 @@ public void CanHandleHostData()
}
""";
- string hostFileFormatted = JObject.Parse(hostfile).ToString(Formatting.None);
+ string hostFileFormatted = JsonNode.Parse(hostfile)!.ToJsonString();
const string hostFileLocation = ".template.config/dotnetcli.host.json";
IDictionary templateSourceFiles = new Dictionary
@@ -390,21 +390,18 @@ private ITemplatePackage GetFakedTemplatePackage(string mountPointUri)
return managedTemplatePackage;
}
- private static JObject ReadObject(IPhysicalFileSystem fileSystem, string path)
+ private static JsonObject ReadObject(IPhysicalFileSystem fileSystem, string path)
{
using var fileStream = fileSystem.OpenRead(path);
using var textReader = new StreamReader(fileStream, System.Text.Encoding.UTF8, true);
- using var jsonReader = new JsonTextReader(textReader);
- return JObject.Load(jsonReader);
+ string content = textReader.ReadToEnd();
+ return JsonNode.Parse(content)!.AsObject();
}
private static void WriteObject(IPhysicalFileSystem fileSystem, string path, object obj)
{
using var fileStream = fileSystem.CreateFile(path);
- using var textWriter = new StreamWriter(fileStream, System.Text.Encoding.UTF8);
- using var jsonWriter = new JsonTextWriter(textWriter);
- var serializer = new JsonSerializer();
- serializer.Serialize(jsonWriter, obj);
+ JsonSerializer.Serialize(fileStream, obj);
}
}
}
diff --git a/test/Microsoft.TemplateEngine.Edge.UnitTests/WorkloadConstraintTests.cs b/test/Microsoft.TemplateEngine.Edge.UnitTests/WorkloadConstraintTests.cs
index fcfff0953c7..d525e67f38e 100644
--- a/test/Microsoft.TemplateEngine.Edge.UnitTests/WorkloadConstraintTests.cs
+++ b/test/Microsoft.TemplateEngine.Edge.UnitTests/WorkloadConstraintTests.cs
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Text.Json;
+using System.Text.Json.Nodes;
using FakeItEasy;
using Microsoft.Extensions.Logging;
using Microsoft.TemplateEngine.Abstractions;
@@ -9,7 +11,6 @@
using Microsoft.TemplateEngine.Edge.Constraints;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel;
using Microsoft.TemplateEngine.TestHelper;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.TemplateEngine.Edge.UnitTests
@@ -36,7 +37,7 @@ public async Task Evaluate_ArrayOfVersions(IReadOnlyList workloads, bool
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IWorkloadsInfoProvider workloadInfoProvider = new WorkloadsInfoProviderMock(workloads); //A.Fake();
IEngineEnvironmentSettings settings = A.Fake();
A.CallTo(() => settings.Components.OfType()).Returns(new[] { workloadInfoProvider });
@@ -68,7 +69,7 @@ public async Task Evaluate_MultipleConflictingProviders()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IWorkloadsInfoProvider workloadInfoProviderA = A.Fake();
A.CallTo(() => workloadInfoProviderA
.GetInstalledWorkloadsAsync(A._))
@@ -110,7 +111,7 @@ public async Task Evaluate_MultipleDuplicateProviders()
}
};
- var configModel = TemplateConfigModel.FromJObject(JObject.FromObject(config));
+ var configModel = TemplateConfigModel.FromJObject(JsonNode.Parse(JsonSerializer.Serialize(config))!.AsObject());
IWorkloadsInfoProvider workloadInfoProviderA = A.Fake();
A.CallTo(() => workloadInfoProviderA
.GetInstalledWorkloadsAsync(A._))
diff --git a/test/Microsoft.TemplateEngine.Mocks/MockTemplateInfo.cs b/test/Microsoft.TemplateEngine.Mocks/MockTemplateInfo.cs
index 3f2b35acb2f..073b2f25524 100644
--- a/test/Microsoft.TemplateEngine.Mocks/MockTemplateInfo.cs
+++ b/test/Microsoft.TemplateEngine.Mocks/MockTemplateInfo.cs
@@ -2,11 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Text;
+using System.Text.Json;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Abstractions.Constraints;
using Microsoft.TemplateEngine.Abstractions.Parameters;
using Microsoft.TemplateEngine.Utils;
-using Newtonsoft.Json;
#if XUNIT_V3
using Xunit.Sdk;
#else
@@ -246,26 +246,26 @@ public void Deserialize(IXunitSerializationInfo info)
Description = info.GetValue("template_description");
Author = info.GetValue("template_author");
#if XUNIT_V3
- _tags = JsonConvert.DeserializeObject>(info.GetValue("template_tags")!)
+ _tags = JsonSerializer.Deserialize>(info.GetValue("template_tags")!)
?? throw new Exception("Deserialiation failed");
- _parameters = JsonConvert.DeserializeObject>(info.GetValue("template_params")!)
+ _parameters = JsonSerializer.Deserialize>(info.GetValue("template_params")!)
?? throw new Exception("Deserialiation failed");
- _baselineInfo = JsonConvert.DeserializeObject(info.GetValue("template_baseline")!)
+ _baselineInfo = JsonSerializer.Deserialize(info.GetValue("template_baseline")!)
?? throw new Exception("Deserialiation failed");
- _classifications = JsonConvert.DeserializeObject(info.GetValue("template_classifications")!)
+ _classifications = JsonSerializer.Deserialize(info.GetValue("template_classifications")!)
?? throw new Exception("Deserialiation failed");
- _shortNameList = JsonConvert.DeserializeObject(info.GetValue("template_shortname")!)
+ _shortNameList = JsonSerializer.Deserialize(info.GetValue("template_shortname")!)
?? throw new Exception("Deserialiation failed");
#else
- _tags = JsonConvert.DeserializeObject>(info.GetValue("template_tags"))
+ _tags = JsonSerializer.Deserialize>(info.GetValue("template_tags"))
?? throw new Exception("Deserialiation failed");
- _parameters = JsonConvert.DeserializeObject>(info.GetValue