Inspired by dotnet show (#386)
* Changed the order of the projects, Web first to infer as startup. * Added encapsulated JSON serialization - and moved to System.Text.Json * Refactored a few minor updates out Co-authored-by: Eric Fleming <eric-fleming18@hotmail.com>
This commit is contained in:
@@ -4,6 +4,8 @@ VisualStudioVersion = 16.0.29102.190
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{419A6ACE-0419-4315-A6FB-B0E63D39432E}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{419A6ACE-0419-4315-A6FB-B0E63D39432E}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "src\Web\Web.csproj", "{227CF035-29B0-448D-97E4-944F9EA850E5}"
|
||||||
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Infrastructure", "src\Infrastructure\Infrastructure.csproj", "{7C461394-ABDC-43CD-A798-71249C58BA67}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Infrastructure", "src\Infrastructure\Infrastructure.csproj", "{7C461394-ABDC-43CD-A798-71249C58BA67}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationCore", "src\ApplicationCore\ApplicationCore.csproj", "{7FED7440-2311-4D1E-958B-3E887C585CD2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationCore", "src\ApplicationCore\ApplicationCore.csproj", "{7FED7440-2311-4D1E-958B-3E887C585CD2}"
|
||||||
@@ -26,8 +28,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
README.md = README.md
|
README.md = README.md
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "src\Web\Web.csproj", "{227CF035-29B0-448D-97E4-944F9EA850E5}"
|
|
||||||
EndProject
|
|
||||||
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{1FCBE191-34FE-4B2E-8915-CA81553958AD}"
|
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{1FCBE191-34FE-4B2E-8915-CA81553958AD}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<PackageReference Include="Ardalis.GuardClauses" Version="1.5.0" />
|
<PackageReference Include="Ardalis.GuardClauses" Version="1.5.0" />
|
||||||
<PackageReference Include="Ardalis.Specification" Version="3.0.0" />
|
<PackageReference Include="Ardalis.Specification" Version="3.0.0" />
|
||||||
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
||||||
|
<PackageReference Include="System.Text.Json" Version="4.7.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
18
src/ApplicationCore/Extensions/JsonExtensions.cs
Normal file
18
src/ApplicationCore/Extensions/JsonExtensions.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopWeb
|
||||||
|
{
|
||||||
|
public static class JsonExtensions
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true
|
||||||
|
};
|
||||||
|
|
||||||
|
public static T FromJson<T>(this string json) =>
|
||||||
|
JsonSerializer.Deserialize<T>(json, _jsonOptions);
|
||||||
|
|
||||||
|
public static string ToJson<T>(this T obj) =>
|
||||||
|
JsonSerializer.Serialize<T>(obj, _jsonOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -172,16 +172,15 @@ namespace Microsoft.eShopWeb.Web
|
|||||||
{
|
{
|
||||||
ResponseWriter = async (context, report) =>
|
ResponseWriter = async (context, report) =>
|
||||||
{
|
{
|
||||||
var result = JsonConvert.SerializeObject(
|
var result = new
|
||||||
new
|
{
|
||||||
|
status = report.Status.ToString(),
|
||||||
|
errors = report.Entries.Select(e => new
|
||||||
{
|
{
|
||||||
status = report.Status.ToString(),
|
key = e.Key,
|
||||||
errors = report.Entries.Select(e => new
|
value = Enum.GetName(typeof(HealthStatus), e.Value.Status)
|
||||||
{
|
})
|
||||||
key = e.Key,
|
}.ToJson();
|
||||||
value = Enum.GetName(typeof(HealthStatus), e.Value.Status)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
context.Response.ContentType = MediaTypeNames.Application.Json;
|
context.Response.ContentType = MediaTypeNames.Application.Json;
|
||||||
await context.Response.WriteAsync(result);
|
await context.Response.WriteAsync(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
|
|||||||
var response = await Client.GetAsync("/api/catalog/list");
|
var response = await Client.GetAsync("/api/catalog/list");
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||||
var model = JsonSerializer.Deserialize<CatalogIndexViewModel>(stringResponse, _jsonOptions);
|
var model = stringResponse.FromJson<CatalogIndexViewModel>();
|
||||||
|
|
||||||
Assert.Equal(10, model.CatalogItems.Count());
|
Assert.Equal(10, model.CatalogItems.Count());
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
|
|||||||
var response = await Client.GetAsync("/api/catalog/list?page=1");
|
var response = await Client.GetAsync("/api/catalog/list?page=1");
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||||
var model = JsonSerializer.Deserialize<CatalogIndexViewModel>(stringResponse, _jsonOptions);
|
var model = stringResponse.FromJson<CatalogIndexViewModel>();
|
||||||
|
|
||||||
Assert.Equal(2, model.CatalogItems.Count());
|
Assert.Equal(2, model.CatalogItems.Count());
|
||||||
}
|
}
|
||||||
|
|||||||
36
tests/UnitTests/ApplicationCore/Extensions/JsonExtensions.cs
Normal file
36
tests/UnitTests/ApplicationCore/Extensions/JsonExtensions.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions
|
||||||
|
{
|
||||||
|
public class JsonExtensions
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void CorrectlySerializesAndDeserializesObject()
|
||||||
|
{
|
||||||
|
var testParent = new TestParent
|
||||||
|
{
|
||||||
|
Id = 7,
|
||||||
|
Name = "Test name",
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new TestChild(),
|
||||||
|
new TestChild(),
|
||||||
|
new TestChild()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var json = testParent.ToJson();
|
||||||
|
var result = json.FromJson<TestParent>();
|
||||||
|
Assert.Equal(testParent, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
Theory,
|
||||||
|
InlineData("{ \"id\": 9, \"name\": \"Another test\" }", 9, "Another test"),
|
||||||
|
InlineData("{ \"id\": 3124, \"name\": \"Test Value 1\" }", 3124, "Test Value 1"),
|
||||||
|
]
|
||||||
|
public void CorrectlyDeserializesJson(string json, int expectedId, string expectedName) =>
|
||||||
|
Assert.Equal(new TestParent { Id = expectedId, Name = expectedName }, json.FromJson<TestParent>());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
17
tests/UnitTests/ApplicationCore/Extensions/TestChild.cs
Normal file
17
tests/UnitTests/ApplicationCore/Extensions/TestChild.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions
|
||||||
|
{
|
||||||
|
[DebuggerDisplay("Id={Id}, Date={Date}")]
|
||||||
|
public class TestChild : IEquatable<TestChild>
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
|
||||||
|
public DateTime Date { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
public bool Equals([AllowNull] TestChild other) =>
|
||||||
|
other?.Date == Date && other?.Id == Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
tests/UnitTests/ApplicationCore/Extensions/TestParent.cs
Normal file
21
tests/UnitTests/ApplicationCore/Extensions/TestParent.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions
|
||||||
|
{
|
||||||
|
public class TestParent : IEquatable<TestParent>
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<TestChild> Children { get; set; }
|
||||||
|
|
||||||
|
public bool Equals([AllowNull] TestParent other) =>
|
||||||
|
other?.Id == Id && other?.Name == Name &&
|
||||||
|
(other?.Children is null && Children is null ||
|
||||||
|
(other?.Children?.Zip(Children)?.All(t => t.First?.Equals(t.Second) ?? false) ?? false));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user