Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,6 @@ public class ConvertFromJsonCommand : Cmdlet

#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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,8 @@
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")]
Expand Down Expand Up @@ -88,22 +83,6 @@ protected override void BeginProcessing()
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>();
Expand All @@ -130,7 +109,6 @@ protected override void EndProcessing()
// 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)
{
Expand All @@ -142,17 +120,6 @@ protected override void EndProcessing()
}
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
}
}

Expand Down Expand Up @@ -517,11 +484,7 @@ private object ProcessValue(object obj, int depth)
}
else
{
#if CORECLR
rv = ProcessCustomObject<JsonIgnoreAttribute>(obj, depth);
#else
rv = ProcessCustomObject<ScriptIgnoreAttribute>(obj, depth);
#endif
isCustomObj = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ internal override void ProcessResponse(HttpResponseMessage response)
);
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,12 @@
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
{
Expand All @@ -45,7 +40,6 @@ public static object ConvertFromJson(string input, out ErrorRecord error)
}

error = null;
#if CORECLR
object obj = null;
try
{
Expand Down Expand Up @@ -89,28 +83,9 @@ public static object ConvertFromJson(string input, out ErrorRecord error)
// 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)
{
Expand Down Expand Up @@ -205,157 +180,5 @@ private static ICollection<object> PopulateFromJArray(JArray list, out ErrorReco
}
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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down