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
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;

namespace RetrieveJSONProperty.DTOs;

public class Customer
{
[JsonPropertyName("FirstName")]
public string? Name { get; set; }

[JsonIgnore]
public string? Password { get; set; }

public int Age { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static IEnumerable<string> RetrievalUsingSerialization(object obj)
{
string json = JsonConvert.SerializeObject(obj);

var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
var values = JsonConvert.DeserializeObject<Dictionary<string, object?>>(json);

return values != null
? values.Keys
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using System.Text.Json.Serialization;

namespace RetrieveJSONProperty.Helper;
Expand All @@ -16,4 +18,17 @@ public static string[] GetJsonPropertyNames(object obj)

return propertyNames;
}
}

public static string[] GetSerializedPropertyNames<T>(JsonSerializerOptions? options = null)
{
options ??= JsonSerializerOptions.Default;
options.MakeReadOnly(populateMissingResolver: true);

JsonTypeInfo typeInfo = options.GetTypeInfo(typeof(T));

return typeInfo.Properties
.Where(property => property.Get is not null || property.Set is not null)
.Select(property => property.Name)
.ToArray();
}
}
16 changes: 16 additions & 0 deletions json-csharp/RetrieveJSONProperty/RetrieveJSONProperty/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Console.WriteLine("2. ListPropertywithValue");
Console.WriteLine("3. ResolverImplementation");
Console.WriteLine("4. AlternateImplementation();");
Console.WriteLine("5. SerializerMetadataImplementation");

string? option = Console.ReadLine();

Expand All @@ -32,6 +33,10 @@
AlternateImplementation();
break;

case "5":
SerializerMetadataImplementation();
break;

case "exit":
continueExecution = false;
break;
Expand Down Expand Up @@ -92,6 +97,17 @@ static void AlternateImplementation()
}
}

static void SerializerMetadataImplementation()
{
var propertyNames = JsonTextImplementation.GetSerializedPropertyNames<Sales>();

Console.WriteLine("JSON property names:");
foreach (var propertyName in propertyNames)
{
Console.WriteLine(propertyName);
}
}

static Sales CreateSalesObject()
{
Console.WriteLine("Enter YearlySales:");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>

</Project>
116 changes: 112 additions & 4 deletions json-csharp/RetrieveJSONProperty/Tests/RetrieveJSONPropertyUnitTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Text.Json;

namespace Tests;

[TestFixture]
Expand All @@ -17,7 +19,7 @@ public void GivenObjectWithJsonPropertyAttribute_WhenRetrievalUsingReflection_Th
var result = JsonHelper.RetrievalUsingReflection(sales);

// Assert
CollectionAssert.AreEquivalent(new[] { "Slx_PER_Year", "Slx_PER_DAY" }, result);
Assert.That(result, Is.EquivalentTo(new[] { "Slx_PER_Year", "Slx_PER_DAY" }));
}

[Test]
Expand All @@ -34,7 +36,20 @@ public void GivenSalesObject_WhenRetrievingKeyValuesUsingSerialization_ThenRetur
var result = JsonHelper.RetrievalUsingSerialization(sales);

// Assert
CollectionAssert.AreEqual(new[] { "Slx_PER_Year", "Slx_PER_DAY" }, result);
Assert.That(result, Is.EqualTo(new[] { "Slx_PER_Year", "Slx_PER_DAY" }));
}

[Test]
public void GivenObjectWithNonStringProperty_WhenRetrievingUsingSerialization_ThenReturnsAllNames()
{
// Arrange
var testObject = new NewtonsoftObjectWithNumber { Name = "Widget", Quantity = 3 };

// Act
var result = JsonHelper.RetrievalUsingSerialization(testObject);

// Assert
Assert.That(result, Is.EqualTo(new[] { "product_name", "Quantity" }));
}

[Test]
Expand All @@ -51,6 +66,83 @@ public void Given_ObjectWithJsonPropertyAttributes_WhenGetJsonPropertyNames_Then
Assert.That(result, Is.EqualTo(expected));
}

[Test]
public void GivenSalesType_WhenGetSerializedPropertyNames_ThenReturnJsonPropertyNames()
{
// Act
string[] result = JsonTextImplementation.GetSerializedPropertyNames<Sales>();

// Assert
Assert.That(result, Is.EqualTo(new[] { "Slx_PER_Year", "Slx_PER_DAY" }));
}

[Test]
public void GivenWebDefaults_WhenGetSerializedPropertyNames_ThenNamingPolicyAppliesOnlyWithoutAttribute()
{
// Arrange
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);

// Act
string[] result = JsonTextImplementation.GetSerializedPropertyNames<TestObjectWithAttributes>(options);

// Assert
Assert.That(result, Is.EqualTo(new[] { "FirstName", "LastName", "age" }));
}

[Test]
public void GivenWebDefaults_WhenSerializing_ThenOutputUsesSameNamesAsGetSerializedPropertyNames()
{
// Arrange
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
var testObject = new TestObjectWithAttributes { Name = "Ana", Surname = "Lee", Age = 30 };

// Act
string json = System.Text.Json.JsonSerializer.Serialize(testObject, options);
string[] namesInJson = JsonDocument.Parse(json).RootElement
.EnumerateObject()
.Select(property => property.Name)
.ToArray();

// Assert
Assert.That(namesInJson,
Is.EqualTo(JsonTextImplementation.GetSerializedPropertyNames<TestObjectWithAttributes>(options)));
}

[Test]
public void GivenIgnoredProperty_WhenGetSerializedPropertyNames_ThenSkipsIt()
{
// Act
string[] result = JsonTextImplementation.GetSerializedPropertyNames<ObjectWithIgnoredProperty>();

// Assert
Assert.That(result, Is.EqualTo(new[] { "id" }));
}

[Test]
public void GivenIgnoredProperty_WhenGetJsonPropertyNames_ThenReflectionStillReturnsIt()
{
// Act
string[] result = JsonTextImplementation.GetJsonPropertyNames(new ObjectWithIgnoredProperty());

// Assert
Assert.That(result, Is.EqualTo(new[] { "id", "Password" }));
}

[Test]
public void GivenCustomer_WhenComparingReflectionWithWebDefaultsMetadata_ThenOnlyMetadataAppliesPolicyAndIgnore()
{
// Arrange
var webOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);

// Act
string[] fromReflection = JsonTextImplementation.GetJsonPropertyNames(new Customer());
string[] fromSerializer = JsonTextImplementation.GetSerializedPropertyNames<Customer>(webOptions);

// Assert
Assert.That(fromReflection, Is.EqualTo(new[] { "FirstName", "Password", "Age" }));
Assert.That(fromSerializer, Is.EqualTo(new[] { "FirstName", "age" }));
}

[Test]
public void GivenValidProductObject_WhenGettingJsonPropertyForProductName_ThenReturnCorrectProperty()
{
Expand All @@ -65,10 +157,9 @@ public void GivenValidProductObject_WhenGettingJsonPropertyForProductName_ThenRe
var property = ResolverHelper.GetJsonProperty(sales, "Slx_per_day");

// Assert
Assert.IsNotNull(property);
Assert.That(property, Is.Not.Null);
Assert.That(property.PropertyName, Is.EqualTo("Slx_PER_DAY"));
Assert.That(property.PropertyType, Is.EqualTo(typeof(string)));

}

private class TestObjectWithAttributes
Expand All @@ -81,4 +172,21 @@ private class TestObjectWithAttributes

public int Age { get; set; }
}

private class NewtonsoftObjectWithNumber
{
[JsonProperty("product_name")]
public string? Name { get; set; }

public int Quantity { get; set; }
}

private class ObjectWithIgnoredProperty
{
[JsonPropertyName("id")]
public int Id { get; set; }

[System.Text.Json.Serialization.JsonIgnore]
public string? Password { get; set; }
}
}
14 changes: 7 additions & 7 deletions json-csharp/RetrieveJSONProperty/Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -10,12 +10,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="NUnit" Version="5.0.0" />
<PackageReference Include="NUnit3TestAdapter" Version="6.3.1" />
<PackageReference Include="NUnit.Analyzers" Version="4.15.0" />
<PackageReference Include="coverlet.collector" Version="10.1.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading