8000 Make ConvertFrom-Json deserialize an array of objects with multiple lines. by Francisco-Gamino · Pull Request #3823 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Make ConvertFrom-Json deserialize an array of objects with multiple lines. #3823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 25, 2017
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 @@ -72,8 +72,8 @@ protected override void ProcessRecord()
protected override void EndProcessing()
{
// When Input is provided through pipeline, the input can be represented in the following two ways:
// 1. Each input to the buffer is a complete Json content. There can be multiple inputs of this format.
// 2. The complete buffer input collectively represent a single JSon format. This is typically the majority of the case.
// 1. Each input in the collection is a complete Json content. There can be multiple inputs of this format.
// 2. The complete input is a collection which represents a single Json content. This is typically the majority of the case.
if (_inputObjectBuffer.Count > 0)
{
if (_inputObjectBuffer.Count == 1)
Expand All @@ -85,6 +85,7 @@ protected override void EndProcessing()
bool successfullyConverted = false;
try
{
// Try to deserialize the first element.
successfullyConverted = ConvertFromJsonHelper(_inputObjectBuffer[0]);
}
catch (ArgumentException)
Expand All @@ -102,6 +103,7 @@ protected override void EndProcessing()
}
else
{
// Process the entire input as a single Json content.
ConvertFromJsonHelper(string.Join(System.Environment.NewLine, _inputObjectBuffer.ToArray()));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Text.RegularExpressions;
#if CORECLR
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -42,11 +43,28 @@ public static object ConvertFromJson(string input, out ErrorRecord error)
{
throw new ArgumentNullException("input");
}

error = null;
#if CORECLR
object obj = null;
try
{
// JsonConvert.DeserializeObject does not throw an exception when an invalid Json array is passed.
// This issue is being tracked by https://github.com/JamesNK/Newtonsoft.Json/issues/1321.
// To work around this, we need to identify when input is a Json array, and then try to parse it via JArray.Parse().

// If input starts with '[' or ends with ']' (ignoring white spaces).
if ((Regex.Match(input, @"(^\s*\[)|(\s*\]$)")).Success)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reg expression used here seems not right ... @Francisco-Gamino let's discuss it tomorrow.

{
// JArray.Parse() will throw a JsonException if the array is invalid.
// This will be caught by the catch block below, and then throw an
// ArgumentException - this is done to have same behavior as the JavaScriptSerializer.
JArray.Parse(input);

// Please note that if the Json array is valid, we don't do anything,
// we just continue the deserialization.
}

obj = JsonConvert.DeserializeObject(input, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.None, MaxDepth = 1024 });

// JObject is a IDictionary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ Describe "Json Tests" -Tags "Feature" {

# add a ScriptProperty called IsOld which returns whether the version is an older version
$versionObject | Add-Member -MemberType ScriptProperty -Name IsOld -Value { ($this.Major -le 3) }

$jstr = ConvertTo-Json $versionObject

# convert the JSON string to a JSON object
Expand Down Expand Up @@ -1455,4 +1454,25 @@ Describe "Json Bug fixes" -Tags "Feature" {
{
RunJsonTest $testCase
}

It "ConvertFrom-Json deserializes an array of PSObjects (in multiple lines) as a single string." {

# Create an array of PSCustomObjects, and serialize it
$array = [pscustomobject]@{ objectName = "object1Name"; objectValue = "object1Value" },
[pscustomobject]@{ objectName = "object2Name"; objectValue = "object2Value" }

# Serialize the array to a text file
$filePath = Join-Path $TESTDRIVE test.json
$array | ConvertTo-Json | Out-File $filePath -Encoding utf8

# Read the object as an array of PSObjects and deserialize it.
$result = Get-Content $filePath | ConvertFrom-Json
$result.Count | Should be 2
}

It "ConvertFrom-Json deserializes an array of strings (in multiple lines) as a single string." {

$result = "[1,","2,","3]" | ConvertFrom-Json
$result.Count | Should be 3
}
}
0