revert git version
This commit is contained in:
@@ -3,7 +3,8 @@
|
|||||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||||
#-------------------------------------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:6.0
|
FROM mcr.microsoft.com/dotnet/sdk:7.0
|
||||||
|
|
||||||
|
|
||||||
# This Dockerfile adds a non-root user with sudo access. Use the "remoteUser"
|
# This Dockerfile adds a non-root user with sudo access. Use the "remoteUser"
|
||||||
# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs
|
# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs
|
||||||
|
|||||||
@@ -25,15 +25,22 @@
|
|||||||
// Comment out to connect as root user. See https://aka.ms/vscode-remote/containers/non-root.
|
// Comment out to connect as root user. See https://aka.ms/vscode-remote/containers/non-root.
|
||||||
// make sure this is the same as USERNAME above
|
// make sure this is the same as USERNAME above
|
||||||
"remoteUser": "vscode",
|
"remoteUser": "vscode",
|
||||||
|
"runArgs": [
|
||||||
|
"-v",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
],
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.profiles.linux": {
|
||||||
|
"bash": {
|
||||||
|
"path": "bash",
|
||||||
|
"icon": "terminal-bash"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Set *default* container specific settings.json values on container create.
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
"settings": {
|
"extensions": [
|
||||||
"terminal.integrated.shell.linux": "/bin/bash"
|
|
||||||
},
|
|
||||||
|
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
|
||||||
"extensions": [
|
|
||||||
"ms-azuretools.azure-dev",
|
|
||||||
"ms-dotnettools.csharp",
|
"ms-dotnettools.csharp",
|
||||||
"formulahendry.dotnet-test-explorer",
|
"formulahendry.dotnet-test-explorer",
|
||||||
"ms-vscode.vscode-node-azure-pack",
|
"ms-vscode.vscode-node-azure-pack",
|
||||||
|
|||||||
2
.github/workflows/dotnetcore.yml
vendored
2
.github/workflows/dotnetcore.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: '6.0.x'
|
dotnet-version: '7.0.x'
|
||||||
include-prerelease: true
|
include-prerelease: true
|
||||||
|
|
||||||
- name: Build with dotnet
|
- name: Build with dotnet
|
||||||
|
|||||||
2
.github/workflows/richnav.yml
vendored
2
.github/workflows/richnav.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
- name: Setup .NET Core
|
- name: Setup .NET Core
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: 3.1.x
|
dotnet-version: 7.0.x
|
||||||
|
|
||||||
- name: Build with dotnet
|
- name: Build with dotnet
|
||||||
run: dotnet build ./eShopOnWeb.sln --configuration Release
|
run: dotnet build ./eShopOnWeb.sln --configuration Release
|
||||||
|
|||||||
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -10,7 +10,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build",
|
"preLaunchTask": "build",
|
||||||
// If you have changed target frameworks, make sure to update the program path.
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
"program": "${workspaceFolder}/src/Web/bin/Debug/net5.0/Web.dll",
|
"program": "${workspaceFolder}/src/Web/bin/Debug/net7.0/Web.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/src/Web",
|
"cwd": "${workspaceFolder}/src/Web",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
|||||||
68
Directory.Packages.props
Normal file
68
Directory.Packages.props
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageVersion Include="Ardalis.ApiEndpoints" Version="4.0.1" />
|
||||||
|
<PackageVersion Include="Ardalis.GuardClauses" Version="4.0.1" />
|
||||||
|
<PackageVersion Include="Ardalis.Specification.EntityFrameworkCore" Version="6.1.0" />
|
||||||
|
<PackageVersion Include="Ardalis.Result" Version="4.1.0" />
|
||||||
|
<PackageVersion Include="Ardalis.Specification" Version="6.1.0" />
|
||||||
|
<PackageVersion Include="Ardalis.ListStartupServices" Version="1.1.4" />
|
||||||
|
<PackageVersion Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
|
||||||
|
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.2.1" />
|
||||||
|
<PackageVersion Include="Azure.Identity" Version="1.6.0" />
|
||||||
|
<PackageVersion Include="BlazorInputFile" Version="0.2.0" />
|
||||||
|
<PackageVersion Include="Blazored.LocalStorage" Version="4.3.0" />
|
||||||
|
<PackageVersion Include="BuildBundlerMinifier" Version="3.2.449" PrivateAssets="All" />
|
||||||
|
<PackageVersion Include="FluentValidation" Version="11.4.0" />
|
||||||
|
<PackageVersion Include="MediatR" Version="11.1.0" />
|
||||||
|
<PackageVersion Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.2" PrivateAssets="all" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||||
|
<PackageVersion Include="Microsoft.Extensions.Identity.Core" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="7.0.0" />
|
||||||
|
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
|
||||||
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageVersion>
|
||||||
|
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
||||||
|
<PackageVersion Include="MinimalApi.Endpoint" Version="1.3.0" />
|
||||||
|
<PackageVersion Include="System.Net.Http.Json" Version="7.0.0" />
|
||||||
|
<PackageVersion Include="System.Security.Claims" Version="4.3.0" />
|
||||||
|
<PackageVersion Include="System.Text.Json" Version="7.0.1" />
|
||||||
|
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.25.1" />
|
||||||
|
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
|
<PackageVersion Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.5.0" />
|
||||||
|
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
|
||||||
|
<!-- Test -->
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
|
<PackageVersion Include="xunit" Version="2.4.2" />
|
||||||
|
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
|
</PackageVersion>
|
||||||
|
<PackageVersion Include="xunit.runner.console" Version="2.4.2">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
|
</PackageVersion>
|
||||||
|
<PackageVersion Include="Moq" Version="4.18.4" />
|
||||||
|
<PackageVersion Include="MSTest.TestAdapter" Version="3.0.2" />
|
||||||
|
<PackageVersion Include="MSTest.TestFramework" Version="3.0.2" />
|
||||||
|
<PackageVersion Include="coverlet.collector" Version="3.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -24,7 +24,7 @@ The **eShopOnWeb** sample is related to the [eShopOnContainers](https://github.c
|
|||||||
The goal for this sample is to demonstrate some of the principles and patterns described in the [eBook](https://aka.ms/webappebook). It is not meant to be an eCommerce reference application, and as such it does not implement many features that would be obvious and/or essential to a real eCommerce application.
|
The goal for this sample is to demonstrate some of the principles and patterns described in the [eBook](https://aka.ms/webappebook). It is not meant to be an eCommerce reference application, and as such it does not implement many features that would be obvious and/or essential to a real eCommerce application.
|
||||||
|
|
||||||
> ### VERSIONS
|
> ### VERSIONS
|
||||||
> #### The `main` branch is currently running ASP.NET Core 6.0.
|
> #### The `main` branch is currently running ASP.NET Core 7.0.
|
||||||
> #### Older versions are tagged.
|
> #### Older versions are tagged.
|
||||||
|
|
||||||
## Topics (eBook TOC)
|
## Topics (eBook TOC)
|
||||||
@@ -47,7 +47,9 @@ The store's home page should look like this:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Most of the site's functionality works with just the web application running. However, the site's Admin page relies on Blazor WebAssembly running in the browser, and it must communicate with the server using the site's PublicApi web application. You'll need to also run this project. You can configure Visual Studio to start multiple projects, or just go to the PublicApi folder in a terminal window and run `dotnet run` from there. After that from the Web folder you should run `dotnet run --launch-profile Web`. Now you should be able to browse to `https://localhost:5001/`. Note that if you use this approach, you'll need to stop the application manually in order to build the solution (otherwise you'll get file locking errors).
|
Most of the site's functionality works with just the web application running. However, the site's Admin page relies on Blazor WebAssembly running in the browser, and it must communicate with the server using the site's PublicApi web application. You'll need to also run this project. You can configure Visual Studio to start multiple projects, or just go to the PublicApi folder in a terminal window and run `dotnet run` from there. After that from the Web folder you should run `dotnet run --launch-profile Web`. Now you should be able to browse to `https://localhost:5001/`. The admin part in Blazor is accessible to `https://localhost:5001/admin`
|
||||||
|
|
||||||
|
Note that if you use this approach, you'll need to stop the application manually in order to build the solution (otherwise you'll get file locking errors).
|
||||||
|
|
||||||
After cloning or downloading the sample you must setup your database.
|
After cloning or downloading the sample you must setup your database.
|
||||||
To use the sample with a persistent database, you will need to run its Entity Framework Core migrations before you will be able to run the app.
|
To use the sample with a persistent database, you will need to run its Entity Framework Core migrations before you will be able to run the app.
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ EndProject
|
|||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0BD72BEA-EF42-4B72-8B69-12A39EC76FBA}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0BD72BEA-EF42-4B72-8B69-12A39EC76FBA}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
|
Directory.Packages.props = Directory.Packages.props
|
||||||
docker-compose.override.yml = docker-compose.override.yml
|
docker-compose.override.yml = docker-compose.override.yml
|
||||||
docker-compose.yml = docker-compose.yml
|
docker-compose.yml = docker-compose.yml
|
||||||
.github\workflows\dotnetcore.yml = .github\workflows\dotnetcore.yml
|
.github\workflows\dotnetcore.yml = .github\workflows\dotnetcore.yml
|
||||||
@@ -38,7 +39,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorAdmin", "src\BlazorAd
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorShared", "src\BlazorShared\BlazorShared.csproj", "{715CF7AF-A1EE-40A6-94A0-8DA3F3B2CAE9}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorShared", "src\BlazorShared\BlazorShared.csproj", "{715CF7AF-A1EE-40A6-94A0-8DA3F3B2CAE9}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublicApiIntegrationTests", "tests\PublicApiIntegrationTests\PublicApiIntegrationTests.csproj", "{D53EF010-8F8C-4337-A059-456E19D8AE63}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicApiIntegrationTests", "tests\PublicApiIntegrationTests\PublicApiIntegrationTests.csproj", "{D53EF010-8F8C-4337-A059-456E19D8AE63}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "6.0.x",
|
"version": "7.0.x",
|
||||||
"rollForward": "latestFeature"
|
"rollForward": "latestFeature"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<RootNamespace>Microsoft.eShopWeb.ApplicationCore</RootNamespace>
|
<RootNamespace>Microsoft.eShopWeb.ApplicationCore</RootNamespace>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Ardalis.GuardClauses" Version="4.0.1" />
|
<PackageReference Include="Ardalis.GuardClauses" />
|
||||||
<PackageReference Include="Ardalis.Result" Version="4.1.0" />
|
<PackageReference Include="Ardalis.Result" />
|
||||||
<PackageReference Include="Ardalis.Specification" Version="6.1.0" />
|
<PackageReference Include="Ardalis.Specification" />
|
||||||
<PackageReference Include="MediatR" Version="10.0.1" />
|
<PackageReference Include="System.Security.Claims" />
|
||||||
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
<PackageReference Include="System.Text.Json" />
|
||||||
<PackageReference Include="System.Text.Json" Version="6.0.5" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
|
<PackageReference Include="Blazored.LocalStorage" />
|
||||||
<PackageReference Include="BlazorInputFile" Version="0.2.0" />
|
<PackageReference Include="BlazorInputFile" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.8" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="6.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Identity.Core" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" />
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
|
<PackageReference Include="System.Net.Http.Json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class CustomAuthStateProvider : AuthenticationStateProvider
|
|||||||
|
|
||||||
if (user == null || !user.IsAuthenticated)
|
if (user == null || !user.IsAuthenticated)
|
||||||
{
|
{
|
||||||
return null;
|
return new ClaimsPrincipal(new ClaimsIdentity());
|
||||||
}
|
}
|
||||||
|
|
||||||
var identity = new ClaimsIdentity(
|
var identity = new ClaimsIdentity(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
await HttpClient.PostAsync("Identity/Account/Logout", null);
|
await HttpClient.PostAsync("User/Logout", null);
|
||||||
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
|
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
@inject NavigationManager Navigation
|
@using System.Web;
|
||||||
|
|
||||||
|
@inject NavigationManager Navigation
|
||||||
|
@inject IJSRuntime JsRuntime
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"Identity/Account/Login?returnUrl=" +
|
var returnUrl = HttpUtility.UrlEncode($"/{Uri.EscapeDataString(Navigation.ToBaseRelativePath(Navigation.Uri))}");
|
||||||
$"/{Uri.EscapeDataString(Navigation.ToBaseRelativePath(Navigation.Uri))}");
|
JsRuntime.InvokeVoidAsync("location.replace", $"Identity/Account/Login?returnUrl={returnUrl}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<RootNamespace>BlazorShared</RootNamespace>
|
<RootNamespace>BlazorShared</RootNamespace>
|
||||||
<AssemblyName>BlazorShared</AssemblyName>
|
<AssemblyName>BlazorShared</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BlazorInputFile" Version="0.2.0" />
|
<PackageReference Include="BlazorInputFile" />
|
||||||
<PackageReference Include="FluentValidation" Version="11.2.1" />
|
<PackageReference Include="FluentValidation" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<RootNamespace>Microsoft.eShopWeb.Infrastructure</RootNamespace>
|
<RootNamespace>Microsoft.eShopWeb.Infrastructure</RootNamespace>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" Version="6.1.0" />
|
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ApplicationCore\ApplicationCore.csproj" />
|
<ProjectReference Include="..\ApplicationCore\ApplicationCore.csproj" />
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogBrandEndpoints;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// List Catalog Brands
|
/// List Catalog Brands
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CatalogBrandListEndpoint : IEndpoint<IResult>
|
public class CatalogBrandListEndpoint : IEndpoint<IResult, IRepository<CatalogBrand>>
|
||||||
{
|
{
|
||||||
private IRepository<CatalogBrand> _catalogBrandRepository;
|
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public CatalogBrandListEndpoint(IMapper mapper)
|
public CatalogBrandListEndpoint(IMapper mapper)
|
||||||
@@ -28,18 +27,17 @@ public class CatalogBrandListEndpoint : IEndpoint<IResult>
|
|||||||
app.MapGet("api/catalog-brands",
|
app.MapGet("api/catalog-brands",
|
||||||
async (IRepository<CatalogBrand> catalogBrandRepository) =>
|
async (IRepository<CatalogBrand> catalogBrandRepository) =>
|
||||||
{
|
{
|
||||||
_catalogBrandRepository = catalogBrandRepository;
|
return await HandleAsync(catalogBrandRepository);
|
||||||
return await HandleAsync();
|
|
||||||
})
|
})
|
||||||
.Produces<ListCatalogBrandsResponse>()
|
.Produces<ListCatalogBrandsResponse>()
|
||||||
.WithTags("CatalogBrandEndpoints");
|
.WithTags("CatalogBrandEndpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> HandleAsync()
|
public async Task<IResult> HandleAsync(IRepository<CatalogBrand> catalogBrandRepository)
|
||||||
{
|
{
|
||||||
var response = new ListCatalogBrandsResponse();
|
var response = new ListCatalogBrandsResponse();
|
||||||
|
|
||||||
var items = await _catalogBrandRepository.ListAsync();
|
var items = await catalogBrandRepository.ListAsync();
|
||||||
|
|
||||||
response.CatalogBrands.AddRange(items.Select(_mapper.Map<CatalogBrandDto>));
|
response.CatalogBrands.AddRange(items.Select(_mapper.Map<CatalogBrandDto>));
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a Catalog Item by Id
|
/// Get a Catalog Item by Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CatalogItemGetByIdEndpoint : IEndpoint<IResult, GetByIdCatalogItemRequest>
|
public class CatalogItemGetByIdEndpoint : IEndpoint<IResult, GetByIdCatalogItemRequest, IRepository<CatalogItem>>
|
||||||
{
|
{
|
||||||
private IRepository<CatalogItem> _itemRepository;
|
|
||||||
private readonly IUriComposer _uriComposer;
|
private readonly IUriComposer _uriComposer;
|
||||||
|
|
||||||
public CatalogItemGetByIdEndpoint(IUriComposer uriComposer)
|
public CatalogItemGetByIdEndpoint(IUriComposer uriComposer)
|
||||||
@@ -26,18 +25,17 @@ public class CatalogItemGetByIdEndpoint : IEndpoint<IResult, GetByIdCatalogItemR
|
|||||||
app.MapGet("api/catalog-items/{catalogItemId}",
|
app.MapGet("api/catalog-items/{catalogItemId}",
|
||||||
async (int catalogItemId, IRepository<CatalogItem> itemRepository) =>
|
async (int catalogItemId, IRepository<CatalogItem> itemRepository) =>
|
||||||
{
|
{
|
||||||
_itemRepository = itemRepository;
|
return await HandleAsync(new GetByIdCatalogItemRequest(catalogItemId), itemRepository);
|
||||||
return await HandleAsync(new GetByIdCatalogItemRequest(catalogItemId));
|
|
||||||
})
|
})
|
||||||
.Produces<GetByIdCatalogItemResponse>()
|
.Produces<GetByIdCatalogItemResponse>()
|
||||||
.WithTags("CatalogItemEndpoints");
|
.WithTags("CatalogItemEndpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> HandleAsync(GetByIdCatalogItemRequest request)
|
public async Task<IResult> HandleAsync(GetByIdCatalogItemRequest request, IRepository<CatalogItem> itemRepository)
|
||||||
{
|
{
|
||||||
var response = new GetByIdCatalogItemResponse(request.CorrelationId());
|
var response = new GetByIdCatalogItemResponse(request.CorrelationId());
|
||||||
|
|
||||||
var item = await _itemRepository.GetByIdAsync(request.CatalogItemId);
|
var item = await itemRepository.GetByIdAsync(request.CatalogItemId);
|
||||||
if (item is null)
|
if (item is null)
|
||||||
return Results.NotFound();
|
return Results.NotFound();
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// List Catalog Items (paged)
|
/// List Catalog Items (paged)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CatalogItemListPagedEndpoint : IEndpoint<IResult, ListPagedCatalogItemRequest>
|
public class CatalogItemListPagedEndpoint : IEndpoint<IResult, ListPagedCatalogItemRequest, IRepository<CatalogItem>>
|
||||||
{
|
{
|
||||||
private IRepository<CatalogItem> _itemRepository;
|
|
||||||
private readonly IUriComposer _uriComposer;
|
private readonly IUriComposer _uriComposer;
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
@@ -32,19 +31,19 @@ public class CatalogItemListPagedEndpoint : IEndpoint<IResult, ListPagedCatalogI
|
|||||||
app.MapGet("api/catalog-items",
|
app.MapGet("api/catalog-items",
|
||||||
async (int? pageSize, int? pageIndex, int? catalogBrandId, int? catalogTypeId, IRepository<CatalogItem> itemRepository) =>
|
async (int? pageSize, int? pageIndex, int? catalogBrandId, int? catalogTypeId, IRepository<CatalogItem> itemRepository) =>
|
||||||
{
|
{
|
||||||
_itemRepository = itemRepository;
|
return await HandleAsync(new ListPagedCatalogItemRequest(pageSize, pageIndex, catalogBrandId, catalogTypeId), itemRepository);
|
||||||
return await HandleAsync(new ListPagedCatalogItemRequest(pageSize, pageIndex, catalogBrandId, catalogTypeId));
|
|
||||||
})
|
})
|
||||||
.Produces<ListPagedCatalogItemResponse>()
|
.Produces<ListPagedCatalogItemResponse>()
|
||||||
.WithTags("CatalogItemEndpoints");
|
.WithTags("CatalogItemEndpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> HandleAsync(ListPagedCatalogItemRequest request)
|
public async Task<IResult> HandleAsync(ListPagedCatalogItemRequest request, IRepository<CatalogItem> itemRepository)
|
||||||
{
|
{
|
||||||
|
await Task.Delay(1000);
|
||||||
var response = new ListPagedCatalogItemResponse(request.CorrelationId());
|
var response = new ListPagedCatalogItemResponse(request.CorrelationId());
|
||||||
|
|
||||||
var filterSpec = new CatalogFilterSpecification(request.CatalogBrandId, request.CatalogTypeId);
|
var filterSpec = new CatalogFilterSpecification(request.CatalogBrandId, request.CatalogTypeId);
|
||||||
int totalItems = await _itemRepository.CountAsync(filterSpec);
|
int totalItems = await itemRepository.CountAsync(filterSpec);
|
||||||
|
|
||||||
var pagedSpec = new CatalogFilterPaginatedSpecification(
|
var pagedSpec = new CatalogFilterPaginatedSpecification(
|
||||||
skip: request.PageIndex.Value * request.PageSize.Value,
|
skip: request.PageIndex.Value * request.PageSize.Value,
|
||||||
@@ -52,7 +51,7 @@ public class CatalogItemListPagedEndpoint : IEndpoint<IResult, ListPagedCatalogI
|
|||||||
brandId: request.CatalogBrandId,
|
brandId: request.CatalogBrandId,
|
||||||
typeId: request.CatalogTypeId);
|
typeId: request.CatalogTypeId);
|
||||||
|
|
||||||
var items = await _itemRepository.ListAsync(pagedSpec);
|
var items = await itemRepository.ListAsync(pagedSpec);
|
||||||
|
|
||||||
response.CatalogItems.AddRange(items.Select(_mapper.Map<CatalogItemDto>));
|
response.CatalogItems.AddRange(items.Select(_mapper.Map<CatalogItemDto>));
|
||||||
foreach (CatalogItemDto item in response.CatalogItems)
|
foreach (CatalogItemDto item in response.CatalogItems)
|
||||||
|
|||||||
@@ -15,9 +15,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new Catalog Item
|
/// Creates a new Catalog Item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CreateCatalogItemEndpoint : IEndpoint<IResult, CreateCatalogItemRequest>
|
public class CreateCatalogItemEndpoint : IEndpoint<IResult, CreateCatalogItemRequest, IRepository<CatalogItem>>
|
||||||
{
|
{
|
||||||
private IRepository<CatalogItem> _itemRepository;
|
|
||||||
private readonly IUriComposer _uriComposer;
|
private readonly IUriComposer _uriComposer;
|
||||||
|
|
||||||
public CreateCatalogItemEndpoint(IUriComposer uriComposer)
|
public CreateCatalogItemEndpoint(IUriComposer uriComposer)
|
||||||
@@ -31,26 +30,25 @@ public class CreateCatalogItemEndpoint : IEndpoint<IResult, CreateCatalogItemReq
|
|||||||
[Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async
|
[Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async
|
||||||
(CreateCatalogItemRequest request, IRepository<CatalogItem> itemRepository) =>
|
(CreateCatalogItemRequest request, IRepository<CatalogItem> itemRepository) =>
|
||||||
{
|
{
|
||||||
_itemRepository = itemRepository;
|
return await HandleAsync(request, itemRepository);
|
||||||
return await HandleAsync(request);
|
|
||||||
})
|
})
|
||||||
.Produces<CreateCatalogItemResponse>()
|
.Produces<CreateCatalogItemResponse>()
|
||||||
.WithTags("CatalogItemEndpoints");
|
.WithTags("CatalogItemEndpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> HandleAsync(CreateCatalogItemRequest request)
|
public async Task<IResult> HandleAsync(CreateCatalogItemRequest request, IRepository<CatalogItem> itemRepository)
|
||||||
{
|
{
|
||||||
var response = new CreateCatalogItemResponse(request.CorrelationId());
|
var response = new CreateCatalogItemResponse(request.CorrelationId());
|
||||||
|
|
||||||
var catalogItemNameSpecification = new CatalogItemNameSpecification(request.Name);
|
var catalogItemNameSpecification = new CatalogItemNameSpecification(request.Name);
|
||||||
var existingCataloogItem = await _itemRepository.CountAsync(catalogItemNameSpecification);
|
var existingCataloogItem = await itemRepository.CountAsync(catalogItemNameSpecification);
|
||||||
if (existingCataloogItem > 0)
|
if (existingCataloogItem > 0)
|
||||||
{
|
{
|
||||||
throw new DuplicateException($"A catalogItem with name {request.Name} already exists");
|
throw new DuplicateException($"A catalogItem with name {request.Name} already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
var newItem = new CatalogItem(request.CatalogTypeId, request.CatalogBrandId, request.Description, request.Name, request.Price, request.PictureUri);
|
var newItem = new CatalogItem(request.CatalogTypeId, request.CatalogBrandId, request.Description, request.Name, request.Price, request.PictureUri);
|
||||||
newItem = await _itemRepository.AddAsync(newItem);
|
newItem = await itemRepository.AddAsync(newItem);
|
||||||
|
|
||||||
if (newItem.Id != 0)
|
if (newItem.Id != 0)
|
||||||
{
|
{
|
||||||
@@ -59,7 +57,7 @@ public class CreateCatalogItemEndpoint : IEndpoint<IResult, CreateCatalogItemReq
|
|||||||
// In production, we recommend uploading to a blob storage and deliver the image via CDN after a verification process.
|
// In production, we recommend uploading to a blob storage and deliver the image via CDN after a verification process.
|
||||||
|
|
||||||
newItem.UpdatePictureUri("eCatalog-item-default.png");
|
newItem.UpdatePictureUri("eCatalog-item-default.png");
|
||||||
await _itemRepository.UpdateAsync(newItem);
|
await itemRepository.UpdateAsync(newItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dto = new CatalogItemDto
|
var dto = new CatalogItemDto
|
||||||
|
|||||||
@@ -13,32 +13,29 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes a Catalog Item
|
/// Deletes a Catalog Item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeleteCatalogItemEndpoint : IEndpoint<IResult, DeleteCatalogItemRequest>
|
public class DeleteCatalogItemEndpoint : IEndpoint<IResult, DeleteCatalogItemRequest, IRepository<CatalogItem>>
|
||||||
{
|
{
|
||||||
private IRepository<CatalogItem> _itemRepository;
|
|
||||||
|
|
||||||
public void AddRoute(IEndpointRouteBuilder app)
|
public void AddRoute(IEndpointRouteBuilder app)
|
||||||
{
|
{
|
||||||
app.MapDelete("api/catalog-items/{catalogItemId}",
|
app.MapDelete("api/catalog-items/{catalogItemId}",
|
||||||
[Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async
|
[Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async
|
||||||
(int catalogItemId, IRepository<CatalogItem> itemRepository) =>
|
(int catalogItemId, IRepository<CatalogItem> itemRepository) =>
|
||||||
{
|
{
|
||||||
_itemRepository = itemRepository;
|
return await HandleAsync(new DeleteCatalogItemRequest(catalogItemId), itemRepository);
|
||||||
return await HandleAsync(new DeleteCatalogItemRequest(catalogItemId));
|
|
||||||
})
|
})
|
||||||
.Produces<DeleteCatalogItemResponse>()
|
.Produces<DeleteCatalogItemResponse>()
|
||||||
.WithTags("CatalogItemEndpoints");
|
.WithTags("CatalogItemEndpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> HandleAsync(DeleteCatalogItemRequest request)
|
public async Task<IResult> HandleAsync(DeleteCatalogItemRequest request, IRepository<CatalogItem> itemRepository)
|
||||||
{
|
{
|
||||||
var response = new DeleteCatalogItemResponse(request.CorrelationId());
|
var response = new DeleteCatalogItemResponse(request.CorrelationId());
|
||||||
|
|
||||||
var itemToDelete = await _itemRepository.GetByIdAsync(request.CatalogItemId);
|
var itemToDelete = await itemRepository.GetByIdAsync(request.CatalogItemId);
|
||||||
if (itemToDelete is null)
|
if (itemToDelete is null)
|
||||||
return Results.NotFound();
|
return Results.NotFound();
|
||||||
|
|
||||||
await _itemRepository.DeleteAsync(itemToDelete);
|
await itemRepository.DeleteAsync(itemToDelete);
|
||||||
|
|
||||||
return Results.Ok(response);
|
return Results.Ok(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates a Catalog Item
|
/// Updates a Catalog Item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UpdateCatalogItemEndpoint : IEndpoint<IResult, UpdateCatalogItemRequest>
|
public class UpdateCatalogItemEndpoint : IEndpoint<IResult, UpdateCatalogItemRequest, IRepository<CatalogItem>>
|
||||||
{
|
{
|
||||||
private IRepository<CatalogItem> _itemRepository;
|
|
||||||
private readonly IUriComposer _uriComposer;
|
private readonly IUriComposer _uriComposer;
|
||||||
|
|
||||||
public UpdateCatalogItemEndpoint(IUriComposer uriComposer)
|
public UpdateCatalogItemEndpoint(IUriComposer uriComposer)
|
||||||
@@ -29,25 +28,24 @@ public class UpdateCatalogItemEndpoint : IEndpoint<IResult, UpdateCatalogItemReq
|
|||||||
[Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async
|
[Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async
|
||||||
(UpdateCatalogItemRequest request, IRepository<CatalogItem> itemRepository) =>
|
(UpdateCatalogItemRequest request, IRepository<CatalogItem> itemRepository) =>
|
||||||
{
|
{
|
||||||
_itemRepository = itemRepository;
|
return await HandleAsync(request, itemRepository);
|
||||||
return await HandleAsync(request);
|
|
||||||
})
|
})
|
||||||
.Produces<UpdateCatalogItemResponse>()
|
.Produces<UpdateCatalogItemResponse>()
|
||||||
.WithTags("CatalogItemEndpoints");
|
.WithTags("CatalogItemEndpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> HandleAsync(UpdateCatalogItemRequest request)
|
public async Task<IResult> HandleAsync(UpdateCatalogItemRequest request, IRepository<CatalogItem> itemRepository)
|
||||||
{
|
{
|
||||||
var response = new UpdateCatalogItemResponse(request.CorrelationId());
|
var response = new UpdateCatalogItemResponse(request.CorrelationId());
|
||||||
|
|
||||||
var existingItem = await _itemRepository.GetByIdAsync(request.Id);
|
var existingItem = await itemRepository.GetByIdAsync(request.Id);
|
||||||
|
|
||||||
CatalogItem.CatalogItemDetails details = new(request.Name, request.Description, request.Price);
|
CatalogItem.CatalogItemDetails details = new(request.Name, request.Description, request.Price);
|
||||||
existingItem.UpdateDetails(details);
|
existingItem.UpdateDetails(details);
|
||||||
existingItem.UpdateBrand(request.CatalogBrandId);
|
existingItem.UpdateBrand(request.CatalogBrandId);
|
||||||
existingItem.UpdateType(request.CatalogTypeId);
|
existingItem.UpdateType(request.CatalogTypeId);
|
||||||
|
|
||||||
await _itemRepository.UpdateAsync(existingItem);
|
await itemRepository.UpdateAsync(existingItem);
|
||||||
|
|
||||||
var dto = new CatalogItemDto
|
var dto = new CatalogItemDto
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogTypeEndpoints;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// List Catalog Types
|
/// List Catalog Types
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CatalogTypeListEndpoint : IEndpoint<IResult>
|
public class CatalogTypeListEndpoint : IEndpoint<IResult, IRepository<CatalogType>>
|
||||||
{
|
{
|
||||||
private IRepository<CatalogType> _catalogTypeRepository;
|
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public CatalogTypeListEndpoint(IMapper mapper)
|
public CatalogTypeListEndpoint(IMapper mapper)
|
||||||
@@ -28,18 +27,17 @@ public class CatalogTypeListEndpoint : IEndpoint<IResult>
|
|||||||
app.MapGet("api/catalog-types",
|
app.MapGet("api/catalog-types",
|
||||||
async (IRepository<CatalogType> catalogTypeRepository) =>
|
async (IRepository<CatalogType> catalogTypeRepository) =>
|
||||||
{
|
{
|
||||||
_catalogTypeRepository = catalogTypeRepository;
|
return await HandleAsync(catalogTypeRepository);
|
||||||
return await HandleAsync();
|
|
||||||
})
|
})
|
||||||
.Produces<ListCatalogTypesResponse>()
|
.Produces<ListCatalogTypesResponse>()
|
||||||
.WithTags("CatalogTypeEndpoints");
|
.WithTags("CatalogTypeEndpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> HandleAsync()
|
public async Task<IResult> HandleAsync(IRepository<CatalogType> catalogTypeRepository)
|
||||||
{
|
{
|
||||||
var response = new ListCatalogTypesResponse();
|
var response = new ListCatalogTypesResponse();
|
||||||
|
|
||||||
var items = await _catalogTypeRepository.ListAsync();
|
var items = await catalogTypeRepository.ListAsync();
|
||||||
|
|
||||||
response.CatalogTypes.AddRange(items.Select(_mapper.Map<CatalogTypeDto>));
|
response.CatalogTypes.AddRange(items.Select(_mapper.Map<CatalogTypeDto>));
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
EXPOSE 443
|
EXPOSE 443
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . .
|
COPY . .
|
||||||
#COPY ["src/PublicApi/PublicApi.csproj", "./PublicApi/"]
|
#COPY ["src/PublicApi/PublicApi.csproj", "./PublicApi/"]
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using BlazorShared;
|
using BlazorShared;
|
||||||
using BlazorShared.Models;
|
using BlazorShared.Models;
|
||||||
using MediatR;
|
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
@@ -83,9 +82,8 @@ builder.Services.AddCors(options =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
builder.Services.AddMediatR(typeof(CatalogItem).Assembly);
|
|
||||||
builder.Services.AddAutoMapper(typeof(MappingProfile).Assembly);
|
builder.Services.AddAutoMapper(typeof(MappingProfile).Assembly);
|
||||||
|
builder.Configuration.AddEnvironmentVariables();
|
||||||
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerGen(c =>
|
||||||
|
|||||||
@@ -1,13 +1,4 @@
|
|||||||
{
|
{
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:52023",
|
|
||||||
"sslPort": 44339
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"IIS Express": {
|
"IIS Express": {
|
||||||
"commandName": "IISExpress",
|
"commandName": "IISExpress",
|
||||||
@@ -25,6 +16,32 @@
|
|||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
},
|
},
|
||||||
"applicationUrl": "https://localhost:5099;http://localhost:5098"
|
"applicationUrl": "https://localhost:5099;http://localhost:5098"
|
||||||
|
},
|
||||||
|
"WSL": {
|
||||||
|
"commandName": "WSL2",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "https://localhost:5099/swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"ASPNETCORE_URLS": "https://localhost:5099;http://localhost:5098"
|
||||||
|
},
|
||||||
|
"distributionName": ""
|
||||||
|
},
|
||||||
|
"Docker": {
|
||||||
|
"commandName": "Docker",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
|
||||||
|
"publishAllPorts": true,
|
||||||
|
"useSSL": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:52023",
|
||||||
|
"sslPort": 44339
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<RootNamespace>Microsoft.eShopWeb.PublicApi</RootNamespace>
|
<RootNamespace>Microsoft.eShopWeb.PublicApi</RootNamespace>
|
||||||
<UserSecretsId>5b662463-1efd-4bae-bde4-befe0be3e8ff</UserSecretsId>
|
<UserSecretsId>5b662463-1efd-4bae-bde4-befe0be3e8ff</UserSecretsId>
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
@@ -10,28 +9,26 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Ardalis.ApiEndpoints" Version="4.0.1" />
|
<PackageReference Include="Ardalis.ApiEndpoints" />
|
||||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" />
|
||||||
<PackageReference Include="MediatR" Version="10.0.1" />
|
<PackageReference Include="MinimalApi.Endpoint" />
|
||||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||||
<PackageReference Include="MinimalApi.Endpoint" Version="1.2.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.4.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.4.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" >
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.8" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" />
|
||||||
|
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"dotnet-ef": {
|
"dotnet-ef": {
|
||||||
"version": "6.0.4",
|
"version": "7.0.2",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-ef"
|
"dotnet-ef"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Security.Claims;
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
@@ -10,7 +7,6 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
|
|||||||
using Microsoft.eShopWeb.Infrastructure.Identity;
|
using Microsoft.eShopWeb.Infrastructure.Identity;
|
||||||
using Microsoft.eShopWeb.Web.Configuration;
|
using Microsoft.eShopWeb.Web.Configuration;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account;
|
namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.eShopWeb.Web.Interfaces;
|
using Microsoft.eShopWeb.Web.Interfaces;
|
||||||
using Microsoft.eShopWeb.Web.Services;
|
using Microsoft.eShopWeb.Web.Services;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopWeb.Web.Configuration;
|
namespace Microsoft.eShopWeb.Web.Configuration;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
using System.Collections.Generic;
|
using System.Security.Claims;
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BlazorShared.Authorization;
|
using BlazorShared.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||||
|
using Microsoft.eShopWeb.Infrastructure.Identity;
|
||||||
|
using Microsoft.eShopWeb.Web.Configuration;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
|
||||||
namespace Microsoft.eShopWeb.Web.Controllers;
|
namespace Microsoft.eShopWeb.Web.Controllers;
|
||||||
|
|
||||||
@@ -14,10 +17,19 @@ namespace Microsoft.eShopWeb.Web.Controllers;
|
|||||||
public class UserController : ControllerBase
|
public class UserController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ITokenClaimsService _tokenClaimsService;
|
private readonly ITokenClaimsService _tokenClaimsService;
|
||||||
|
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||||
|
private readonly ILogger<UserController> _logger;
|
||||||
|
private readonly IMemoryCache _cache;
|
||||||
|
|
||||||
public UserController(ITokenClaimsService tokenClaimsService)
|
public UserController(ITokenClaimsService tokenClaimsService,
|
||||||
|
SignInManager<ApplicationUser> signInManager,
|
||||||
|
ILogger<UserController> logger,
|
||||||
|
IMemoryCache cache)
|
||||||
{
|
{
|
||||||
_tokenClaimsService = tokenClaimsService;
|
_tokenClaimsService = tokenClaimsService;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
_cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -26,6 +38,25 @@ public class UserController : ControllerBase
|
|||||||
public async Task<IActionResult> GetCurrentUser() =>
|
public async Task<IActionResult> GetCurrentUser() =>
|
||||||
Ok(await CreateUserInfo(User));
|
Ok(await CreateUserInfo(User));
|
||||||
|
|
||||||
|
[Route("Logout")]
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<IActionResult> Logout()
|
||||||
|
{
|
||||||
|
await _signInManager.SignOutAsync();
|
||||||
|
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
var userId = _signInManager.Context.User.Claims.First(c => c.Type == ClaimTypes.Name);
|
||||||
|
var identityKey = _signInManager.Context.Request.Cookies[ConfigureCookieSettings.IdentifierCookieName];
|
||||||
|
_cache.Set($"{userId.Value}:{identityKey}", identityKey, new MemoryCacheEntryOptions
|
||||||
|
{
|
||||||
|
AbsoluteExpiration = DateTime.Now.AddMinutes(ConfigureCookieSettings.ValidityMinutesPeriod)
|
||||||
|
});
|
||||||
|
|
||||||
|
_logger.LogInformation("User logged out.");
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<UserInfo> CreateUserInfo(ClaimsPrincipal claimsPrincipal)
|
private async Task<UserInfo> CreateUserInfo(ClaimsPrincipal claimsPrincipal)
|
||||||
{
|
{
|
||||||
if (claimsPrincipal.Identity == null || claimsPrincipal.Identity.Name == null || !claimsPrincipal.Identity.IsAuthenticated)
|
if (claimsPrincipal.Identity == null || claimsPrincipal.Identity.Name == null || !claimsPrincipal.Identity.IsAuthenticated)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
# RUN COMMAND
|
# RUN COMMAND
|
||||||
# docker run --name eshopweb --rm -it -p 5106:5106 web
|
# docker run --name eshopweb --rm -it -p 5106:5106 web
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY *.sln .
|
COPY *.sln .
|
||||||
@@ -17,7 +17,7 @@ RUN dotnet restore
|
|||||||
|
|
||||||
RUN dotnet publish -c Release -o out
|
RUN dotnet publish -c Release -o out
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
|
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=build /app/src/Web/out ./
|
COPY --from=build /app/src/Web/out ./
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using MediatR;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediatR;
|
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
|
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System.Linq;
|
using MediatR;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediatR;
|
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
|
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
|
|||||||
.AddDefaultTokenProviders();
|
.AddDefaultTokenProviders();
|
||||||
|
|
||||||
builder.Services.AddScoped<ITokenClaimsService, IdentityTokenClaimService>();
|
builder.Services.AddScoped<ITokenClaimsService, IdentityTokenClaimService>();
|
||||||
|
builder.Configuration.AddEnvironmentVariables();
|
||||||
builder.Services.AddCoreServices(builder.Configuration);
|
builder.Services.AddCoreServices(builder.Configuration);
|
||||||
builder.Services.AddWebServices(builder.Configuration);
|
builder.Services.AddWebServices(builder.Configuration);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<RootNamespace>Microsoft.eShopWeb.Web</RootNamespace>
|
<RootNamespace>Microsoft.eShopWeb.Web</RootNamespace>
|
||||||
@@ -14,28 +13,28 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Ardalis.ListStartupServices" Version="1.1.4" />
|
<PackageReference Include="Ardalis.ListStartupServices" />
|
||||||
<PackageReference Include="Ardalis.Specification" Version="6.1.0" />
|
<PackageReference Include="Ardalis.Specification" />
|
||||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" />
|
||||||
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.2.1" />
|
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" />
|
||||||
<PackageReference Include="Azure.Identity" Version="1.5.0" />
|
<PackageReference Include="Azure.Identity" />
|
||||||
<PackageReference Include="MediatR" Version="10.0.1" />
|
<PackageReference Include="MediatR" />
|
||||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
|
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" />
|
||||||
<PackageReference Include="BuildBundlerMinifier" Version="3.2.449" Condition="'$(Configuration)'=='Release'" PrivateAssets="All" />
|
<PackageReference Include="BuildBundlerMinifier" Condition="'$(Configuration)'=='Release'" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.8" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" />
|
||||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
|
<PackageReference Include="Microsoft.Web.LibraryManager.Build" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="wwwroot\fonts\" />
|
<Folder Include="wwwroot\fonts\" />
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
"defaultProvider": "cdnjs",
|
"defaultProvider": "cdnjs",
|
||||||
"libraries": [
|
"libraries": [
|
||||||
{
|
{
|
||||||
"library": "jquery@3.3.1",
|
"library": "jquery@3.6.3",
|
||||||
"destination": "wwwroot/lib/jquery/"
|
"destination": "wwwroot/lib/jquery/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"library": "twitter-bootstrap@3.3.7",
|
"library": "twitter-bootstrap@5.2.3",
|
||||||
"files": [
|
"files": [
|
||||||
"css/bootstrap.css",
|
"css/bootstrap.css",
|
||||||
"css/bootstrap.css.map",
|
"css/bootstrap.css.map",
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
"destination": "wwwroot/lib/bootstrap/dist/"
|
"destination": "wwwroot/lib/bootstrap/dist/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"library": "jquery-validation-unobtrusive@3.2.10",
|
"library": "jquery-validation-unobtrusive@4.0.0",
|
||||||
"destination": "wwwroot/lib/jquery-validation-unobtrusive/"
|
"destination": "wwwroot/lib/jquery-validation-unobtrusive/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"library": "jquery-validate@1.17.0",
|
"library": "jquery-validate@1.19.5",
|
||||||
"destination": "wwwroot/lib/jquery-validate/",
|
"destination": "wwwroot/lib/jquery-validate/",
|
||||||
"files": [
|
"files": [
|
||||||
"jquery.validate.min.js",
|
"jquery.validate.min.js",
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
"destination": "wwwroot/lib/toastr/"
|
"destination": "wwwroot/lib/toastr/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"library": "aspnet-signalr@1.0.3",
|
"library": "aspnet-signalr@1.0.27",
|
||||||
"files": [
|
"files": [
|
||||||
"signalr.js",
|
"signalr.js",
|
||||||
"signalr.min.js"
|
"signalr.min.js"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<RootNamespace>Microsoft.eShopWeb.FunctionalTests</RootNamespace>
|
<RootNamespace>Microsoft.eShopWeb.FunctionalTests</RootNamespace>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
@@ -15,15 +14,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
<PackageReference Include="xunit" Version="2.4.2" />
|
<PackageReference Include="xunit" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
<PackageReference Include="xunit.runner.visualstudio" />
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<DotNetCliToolReference Include="dotnet-xunit" />
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
|
||||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<RootNamespace>Microsoft.eShopWeb.IntegrationTests</RootNamespace>
|
<RootNamespace>Microsoft.eShopWeb.IntegrationTests</RootNamespace>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
<PackageReference Include="Moq" Version="4.18.2" />
|
<PackageReference Include="Moq" />
|
||||||
<PackageReference Include="xunit" Version="2.4.2" />
|
<PackageReference Include="xunit" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
<PackageReference Include="xunit.runner.visualstudio" >
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
||||||
using Microsoft.eShopWeb.Web.ViewModels;
|
using Microsoft.eShopWeb.Web.ViewModels;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PublicApiIntegrationTests.CatalogItemEndpoints
|
namespace PublicApiIntegrationTests.CatalogItemEndpoints
|
||||||
@@ -45,5 +48,26 @@ namespace PublicApiIntegrationTests.CatalogItemEndpoints
|
|||||||
|
|
||||||
Assert.AreEqual(totalExpected, model2.CatalogItems.Count());
|
Assert.AreEqual(totalExpected, model2.CatalogItems.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DataTestMethod]
|
||||||
|
[DataRow("catalog-items")]
|
||||||
|
[DataRow("catalog-brands")]
|
||||||
|
[DataRow("catalog-types")]
|
||||||
|
[DataRow("catalog-items/1")]
|
||||||
|
public async Task SuccessFullMutipleParallelCall(string endpointName)
|
||||||
|
{
|
||||||
|
var client = ProgramTest.NewClient;
|
||||||
|
var tasks = new List<Task<HttpResponseMessage>>();
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
var task = client.GetAsync($"/api/{endpointName}");
|
||||||
|
tasks.Add(task);
|
||||||
|
}
|
||||||
|
await Task.WhenAll(tasks.ToList());
|
||||||
|
var totalKO = tasks.Count(t => t.Result.StatusCode != HttpStatusCode.OK);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, totalKO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
@@ -20,11 +19,14 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
<PackageReference Include="MSTest.TestAdapter" />
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
<PackageReference Include="MSTest.TestFramework" />
|
||||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
<PackageReference Include="coverlet.collector">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<RootNamespace>Microsoft.eShopWeb.UnitTests</RootNamespace>
|
<RootNamespace>Microsoft.eShopWeb.UnitTests</RootNamespace>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
@@ -10,18 +9,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
<PackageReference Include="Moq" Version="4.18.2" />
|
<PackageReference Include="Moq" />
|
||||||
<PackageReference Include="xunit" Version="2.4.2" />
|
<PackageReference Include="xunit" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
<PackageReference Include="xunit.runner.visualstudio" />
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PackageReference Include="xunit.runner.console" />
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="xunit.runner.console" Version="2.4.2">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user