return _data;
}
- private void VisitElement(JsonElement element) {
+ private void VisitElement(JsonElement element)
+ {
+ var isEmpty = true;
+
foreach (JsonProperty property in element.EnumerateObject())
{
+ isEmpty = false;
EnterContext(property.Name);
VisitValue(property.Value);
ExitContext();
}
+
+ if (isEmpty)
+ {
+ _data[_currentPath] = null;
+ }
}
private void VisitValue(JsonElement value)
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.Configuration.Test;
+using Xunit;
+
+namespace Microsoft.Extensions.Configuration.Json.Test
+{
+ public class EmptyObjectTest
+ {
+ [Fact]
+ public void EmptyObject_AddsAsNull()
+ {
+ var json = @"{
+ ""key"": { },
+ }";
+
+ var jsonConfigSource = new JsonConfigurationProvider(new JsonConfigurationSource());
+ jsonConfigSource.Load(TestStreamHelpers.StringToStream(json));
+
+ Assert.Null(jsonConfigSource.Get("key"));
+ }
+
+ [Fact]
+ public void NullObject_AddsEmptyString()
+ {
+ var json = @"{
+ ""key"": null,
+ }";
+
+ var jsonConfigSource = new JsonConfigurationProvider(new JsonConfigurationSource());
+ jsonConfigSource.Load(TestStreamHelpers.StringToStream(json));
+
+ Assert.Equal("", jsonConfigSource.Get("key"));
+ }
+
+ [Fact]
+ public void NestedObject_DoesNotAddParent()
+ {
+ var json = @"{
+ ""key"": {
+ ""nested"": ""value""
+ },
+ }";
+
+ var jsonConfigSource = new JsonConfigurationProvider(new JsonConfigurationSource());
+ jsonConfigSource.Load(TestStreamHelpers.StringToStream(json));
+
+ Assert.False(jsonConfigSource.TryGet("key", out _));
+ Assert.Equal("value", jsonConfigSource.Get("key:nested"));
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.Configuration.Test;
+using Xunit;
+using Xunit.Sdk;
+
+namespace Microsoft.Extensions.Configuration.Json.Test
+{
+ public class IntegrationTest
+ {
+ [Fact]
+ public void LoadJsonConfiguration()
+ {
+ var json = @"{
+ ""a"": ""b"",
+ ""c"": {
+ ""d"": ""e""
+ },
+ ""f"": """",
+ ""g"": null,
+ ""h"": {},
+ ""i"": {
+ ""k"": {}
+ }
+ }";
+
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.AddJsonStream(TestStreamHelpers.StringToStream(json));
+ var configuration = configurationBuilder.Build();
+
+ Assert.Collection(configuration.GetChildren(),
+ new Action<IConfigurationSection>[] {
+ x => AssertSection(x, "a", "b"),
+ x => AssertSection(x, "c", null, new Action<IConfigurationSection>[] {
+ x => AssertSection(x, "d", "e"),
+ }),
+ x => AssertSection(x, "f", ""),
+ x => AssertSection(x, "g", ""),
+ x => AssertSection(x, "h", null),
+ x => AssertSection(x, "i", null, new Action<IConfigurationSection>[] {
+ x => AssertSection(x, "k", null),
+ }),
+ });
+ }
+
+ private static void AssertSection(IConfigurationSection configurationSection, string key, string value)
+ => AssertSection(configurationSection, key, value, new Action<IConfigurationSection>[0]);
+
+ private static void AssertSection(IConfigurationSection configurationSection, string key, string value, Action<IConfigurationSection>[] childrenInspectors)
+ {
+ if (key != configurationSection.Key || value != configurationSection.Value)
+ {
+ throw new EqualException(
+ expected: GetString(key, value),
+ actual: GetString(configurationSection));
+ }
+
+ Assert.Collection(configurationSection.GetChildren(), childrenInspectors);
+ }
+
+ private static string GetString(IConfigurationSection configurationSection) => GetString(configurationSection.Key, configurationSection.Value);
+ private static string GetString(string key, string value) => $"\"{key}\":" + (value is null ? "null" : $"\"{value}\"");
+ }
+}
Assert.False(sectionNotExists);
}
+ [Theory]
+ [InlineData("Value1")]
+ [InlineData("")]
+ public void KeyWithValueAndWithoutChildrenExistsAsSection(string value)
+ {
+ // Arrange
+ var dict = new Dictionary<string, string>()
+ {
+ {"Mem1", value}
+ };
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.AddInMemoryCollection(dict);
+ var config = configurationBuilder.Build();
+
+ // Act
+ var sectionExists = config.GetSection("Mem1").Exists();
+
+ // Assert
+ Assert.True(sectionExists);
+ }
+
+ [Fact]
+ public void KeyWithNullValueAndWithoutChildrenIsASectionButNotExists()
+ {
+ // Arrange
+ var dict = new Dictionary<string, string>()
+ {
+ {"Mem1", null}
+ };
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.AddInMemoryCollection(dict);
+ var config = configurationBuilder.Build();
+
+ // Act
+ var sections = config.GetChildren();
+ var sectionExists = config.GetSection("Mem1").Exists();
+ var sectionChildren = config.GetSection("Mem1").GetChildren();
+
+ // Assert
+ Assert.Single(sections, section => section.Key == "Mem1");
+ Assert.False(sectionExists);
+ Assert.Empty(sectionChildren);
+ }
+
+ [Fact]
+ public void SectionWithChildrenHasNullValue()
+ {
+ // Arrange
+ var dict = new Dictionary<string, string>()
+ {
+ {"Mem1:KeyInMem1", "ValueInMem1"},
+ };
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.AddInMemoryCollection(dict);
+ var config = configurationBuilder.Build();
+
+ // Act
+ var sectionValue = config.GetSection("Mem1").Value;
+
+ // Assert
+ Assert.Null(sectionValue);
+ }
+
[Fact]
public void NullSectionDoesNotExist()
{