mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Cleanup Json cmdlets (#5001)
This commit is contained in:
-23
@@ -35,29 +35,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
#region overrides
|
||||
|
||||
/// <summary>
|
||||
/// Prerequisite checks
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
#if CORECLR
|
||||
JsonObject.ImportJsonDotNetModule(this);
|
||||
#else
|
||||
try
|
||||
{
|
||||
System.Reflection.Assembly.Load(new AssemblyName("System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"));
|
||||
}
|
||||
catch (System.IO.FileNotFoundException)
|
||||
{
|
||||
ThrowTerminatingError(new ErrorRecord(
|
||||
new NotSupportedException(WebCmdletStrings.ExtendedProfileRequired),
|
||||
"ExtendedProfileRequired",
|
||||
ErrorCategory.NotInstalled,
|
||||
null));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Buffers InputObjet contents available in the pipeline.
|
||||
/// </summary>
|
||||
|
||||
-37
@@ -12,13 +12,8 @@ using System.Text;
|
||||
using System.Globalization;
|
||||
using Dbg = System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
#if CORECLR
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
#else
|
||||
using System.Collections.Specialized;
|
||||
using System.Web.Script.Serialization;
|
||||
#endif
|
||||
|
||||
// FxCop suppressions for resource strings:
|
||||
[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "WebCmdletStrings.resources", MessageId = "json")]
|
||||
@@ -88,22 +83,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
#if CORECLR
|
||||
JsonObject.ImportJsonDotNetModule(this);
|
||||
#else
|
||||
try
|
||||
{
|
||||
System.Reflection.Assembly.Load(new AssemblyName("System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"));
|
||||
}
|
||||
catch (System.IO.FileNotFoundException)
|
||||
{
|
||||
ThrowTerminatingError(new ErrorRecord(
|
||||
new NotSupportedException(WebCmdletStrings.ExtendedProfileRequired),
|
||||
"ExtendedProfileRequired",
|
||||
ErrorCategory.NotInstalled,
|
||||
null));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private List<object> _inputObjects = new List<object>();
|
||||
@@ -130,7 +109,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
// Pre-process the object so that it serializes the same, except that properties whose
|
||||
// values cannot be evaluated are treated as having the value null.
|
||||
object preprocessedObject = ProcessValue(objectToProcess, 0);
|
||||
#if CORECLR
|
||||
JsonSerializerSettings jsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None, MaxDepth = 1024 };
|
||||
if (EnumsAsStrings)
|
||||
{
|
||||
@@ -142,17 +120,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
string output = JsonConvert.SerializeObject(preprocessedObject, jsonSettings);
|
||||
WriteObject(output);
|
||||
#else
|
||||
// In Full CLR, we use the JavaScriptSerializer for which RecursionLimit was set to the default value of 100 (the actual recursion limit is 99 since
|
||||
// at 100 the exception is thrown). See https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.recursionlimit(v=vs.110).aspx
|
||||
// ProcessValue creates an object to be serialized from 1 to depth. However, the properties of the object at 'depth' should also be serialized,
|
||||
// and from the perspective of the serializer, this means it needs to support serializing depth + 1. For the JavaScriptSerializer to support this,
|
||||
// RecursionLimit needs to be set to depth + 2.
|
||||
JavaScriptSerializer helper = new JavaScriptSerializer() { RecursionLimit = (maxDepthAllowed + 2) };
|
||||
helper.MaxJsonLength = Int32.MaxValue;
|
||||
string output = helper.Serialize(preprocessedObject);
|
||||
WriteObject(Compress ? output : ConvertToPrettyJsonString(output));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,11 +484,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CORECLR
|
||||
rv = ProcessCustomObject<JsonIgnoreAttribute>(obj, depth);
|
||||
#else
|
||||
rv = ProcessCustomObject<ScriptIgnoreAttribute>(obj, depth);
|
||||
#endif
|
||||
isCustomObj = true;
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -69,8 +69,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
);
|
||||
bool convertSuccess = false;
|
||||
|
||||
// On CoreCLR, we need to explicitly load Json.NET
|
||||
JsonObject.ImportJsonDotNetModule(this);
|
||||
if (returnType == RestReturnType.Json)
|
||||
{
|
||||
convertSuccess = TryConvertToJson(str, out obj, ref ex) || TryConvertToXml(str, out obj, ref ex);
|
||||
|
||||
+1
-178
@@ -8,17 +8,12 @@ using System.Globalization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Management.Automation;
|
||||
using System.Text.RegularExpressions;
|
||||
#if CORECLR
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Reflection;
|
||||
#else
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Collections.Specialized;
|
||||
#endif
|
||||
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
@@ -45,7 +40,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
|
||||
error = null;
|
||||
#if CORECLR
|
||||
object obj = null;
|
||||
try
|
||||
{
|
||||
@@ -89,28 +83,9 @@ namespace Microsoft.PowerShell.Commands
|
||||
// the same as JavaScriptSerializer does
|
||||
throw new ArgumentException(msg, je);
|
||||
}
|
||||
#else
|
||||
//In ConvertTo-Json, to serialize an object with a given depth, we set the RecursionLimit to depth + 2, see JavaScriptSerializer constructor in ConvertToJsonCommand.cs.
|
||||
// Setting RecursionLimit to depth + 2 in order to support '$object | ConvertTo-Json –depth <value less than or equal to 100> | ConvertFrom-Json'.
|
||||
JavaScriptSerializer serializer = new JavaScriptSerializer(new JsonObjectTypeResolver()) { RecursionLimit = (maxDepthAllowed + 2) };
|
||||
serializer.MaxJsonLength = Int32.MaxValue;
|
||||
object obj = serializer.DeserializeObject(input);
|
||||
|
||||
if (obj is IDictionary<string, object>)
|
||||
{
|
||||
var dictionary = obj as IDictionary<string, object>;
|
||||
obj = PopulateFromDictionary(dictionary, out error);
|
||||
}
|
||||
else if (obj is ICollection<object>)
|
||||
{
|
||||
var list = obj as ICollection<object>;
|
||||
obj = PopulateFromList(list, out error);
|
||||
}
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
#if CORECLR
|
||||
// This function is a clone of PopulateFromDictionary using JObject as an input.
|
||||
private static PSObject PopulateFromJDictionary(JObject entries, out ErrorRecord error)
|
||||
{
|
||||
@@ -205,157 +180,5 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the Json.Net module to the given cmdlet execution context.
|
||||
/// </summary>
|
||||
/// <param name="cmdlet"></param>
|
||||
/// <returns></returns>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
|
||||
public static void ImportJsonDotNetModule(Cmdlet cmdlet)
|
||||
{
|
||||
const string jsonDotNetAssemblyName = "Newtonsoft.Json, Version=7.0.0.0";
|
||||
|
||||
// Check if the Newtonsoft.Json.dll assembly is loaded.
|
||||
try
|
||||
{
|
||||
System.Reflection.Assembly.Load(new AssemblyName(jsonDotNetAssemblyName));
|
||||
}
|
||||
catch (System.IO.FileNotFoundException)
|
||||
{
|
||||
// It is not, try to load it.
|
||||
// Make sure that PSModuleAutoLoadingPreference is not set to 'None'.
|
||||
PSModuleAutoLoadingPreference moduleAutoLoadingPreference =
|
||||
CommandDiscovery.GetCommandDiscoveryPreference(cmdlet.Context, SpecialVariables.PSModuleAutoLoadingPreferenceVarPath, "PSModuleAutoLoadingPreference");
|
||||
if (moduleAutoLoadingPreference == PSModuleAutoLoadingPreference.None)
|
||||
{
|
||||
cmdlet.ThrowTerminatingError(new ErrorRecord(
|
||||
new NotSupportedException(WebCmdletStrings.PSModuleAutoloadingPreferenceNotEnable),
|
||||
"PSModuleAutoloadingPreferenceNotEnable",
|
||||
ErrorCategory.NotEnabled,
|
||||
null));
|
||||
}
|
||||
|
||||
// Use module auto-loading to import Json.Net.
|
||||
var jsonNetModulePath = Path.Combine(System.Environment.GetEnvironmentVariable("ProgramFiles"), @"WindowsPowerShell\Modules\Json.Net");
|
||||
CmdletInfo cmdletInfo = cmdlet.Context.SessionState.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\\Import-Module");
|
||||
Exception exception;
|
||||
Collection<PSModuleInfo> importedModule = CommandDiscovery.AutoloadSpecifiedModule(jsonNetModulePath, cmdlet.Context, cmdletInfo.Visibility, out exception);
|
||||
|
||||
if ((importedModule == null) || (importedModule.Count == 0))
|
||||
{
|
||||
string errorMessage = StringUtil.Format(WebCmdletStrings.JsonNetModuleRequired, WebCmdletStrings.CouldNotAutoImportJsonNetModule);
|
||||
|
||||
cmdlet.ThrowTerminatingError(new ErrorRecord(
|
||||
new NotSupportedException(errorMessage, exception),
|
||||
"CouldNotAutoImportJsonNetModule",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
|
||||
// Finally, ensure that the Newtonsoft.Json.dll assembly was loaded.
|
||||
try
|
||||
{
|
||||
System.Reflection.Assembly.Load(new AssemblyName(jsonDotNetAssemblyName));
|
||||
}
|
||||
catch (System.IO.FileNotFoundException)
|
||||
{
|
||||
string errorMessage = StringUtil.Format(
|
||||
WebCmdletStrings.JsonNetModuleRequired,
|
||||
StringUtil.Format(WebCmdletStrings.JsonNetModuleFilesRequired, jsonNetModulePath));
|
||||
|
||||
cmdlet.ThrowTerminatingError(new ErrorRecord(
|
||||
new NotSupportedException(errorMessage),
|
||||
"JsonNetModuleRequired",
|
||||
ErrorCategory.NotInstalled,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
private static ICollection<object> PopulateFromList(ICollection<object> list, out ErrorRecord error)
|
||||
{
|
||||
error = null;
|
||||
List<object> result = new List<object>();
|
||||
|
||||
foreach (object element in list)
|
||||
{
|
||||
if (element is IDictionary<string, object>)
|
||||
{
|
||||
IDictionary<string, object> dic = element as IDictionary<string, object>;
|
||||
PSObject dicResult = PopulateFromDictionary(dic, out error);
|
||||
if (error != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
result.Add(dicResult);
|
||||
}
|
||||
else if (element is ICollection<object>)
|
||||
{
|
||||
ICollection<object> subList = element as ICollection<object>;
|
||||
ICollection<object> listResult = PopulateFromList(subList, out error);
|
||||
if (error != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
result.Add(listResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private static PSObject PopulateFromDictionary(IDictionary<string, object> entries, out ErrorRecord error)
|
||||
{
|
||||
error = null;
|
||||
PSObject result = new PSObject();
|
||||
foreach (KeyValuePair<string, object> entry in entries)
|
||||
{
|
||||
PSPropertyInfo property = result.Properties[entry.Key];
|
||||
if (property != null)
|
||||
{
|
||||
string errorMsg = string.Format(CultureInfo.InvariantCulture,
|
||||
WebCmdletStrings.DuplicateKeysInJsonString, property.Name, entry.Key);
|
||||
error = new ErrorRecord(
|
||||
new InvalidOperationException(errorMsg),
|
||||
"DuplicateKeysInJsonString",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (entry.Value is IDictionary<string, object>)
|
||||
{
|
||||
IDictionary<string, object> subEntries = entry.Value as IDictionary<string, object>;
|
||||
PSObject dicResult = PopulateFromDictionary(subEntries, out error);
|
||||
if (error != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
result.Properties.Add(new PSNoteProperty(entry.Key, dicResult));
|
||||
}
|
||||
else if (entry.Value is ICollection<object>)
|
||||
{
|
||||
ICollection<object> list = entry.Value as ICollection<object>;
|
||||
ICollection<object> listResult = PopulateFromList(list, out error);
|
||||
if (error != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
result.Properties.Add(new PSNoteProperty(entry.Key, listResult));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Properties.Add(new PSNoteProperty(entry.Key, entry.Value));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.PowerShell.CoreCLR.Eventing\Microsoft.PowerShell.CoreCLR.Eventing.csproj" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry.AccessControl" Version="4.4.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.4.0" />
|
||||
<PackageReference Include="System.Security.AccessControl" Version="4.4.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="4.4.0" />
|
||||
|
||||
Reference in New Issue
Block a user