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:
David Pine
2020-06-11 14:47:05 -05:00
committed by GitHub
parent 70a919e145
commit 0af21d22f5
8 changed files with 105 additions and 13 deletions

View File

@@ -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

View File

@@ -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>

View 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);
}
}

View File

@@ -172,8 +172,7 @@ namespace Microsoft.eShopWeb.Web
{ {
ResponseWriter = async (context, report) => ResponseWriter = async (context, report) =>
{ {
var result = JsonConvert.SerializeObject( var result = new
new
{ {
status = report.Status.ToString(), status = report.Status.ToString(),
errors = report.Entries.Select(e => new errors = report.Entries.Select(e => new
@@ -181,7 +180,7 @@ namespace Microsoft.eShopWeb.Web
key = e.Key, key = e.Key,
value = Enum.GetName(typeof(HealthStatus), e.Value.Status) value = Enum.GetName(typeof(HealthStatus), e.Value.Status)
}) })
}); }.ToJson();
context.Response.ContentType = MediaTypeNames.Application.Json; context.Response.ContentType = MediaTypeNames.Application.Json;
await context.Response.WriteAsync(result); await context.Response.WriteAsync(result);
} }

View File

@@ -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());
} }

View 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>());
}
}

View 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;
}
}

View 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));
}
}