revert git version
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# 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"
|
||||
# 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.
|
||||
// make sure this is the same as USERNAME above
|
||||
"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.shell.linux": "/bin/bash"
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"bash": {
|
||||
"path": "bash",
|
||||
"icon": "terminal-bash"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-azuretools.azure-dev",
|
||||
"ms-dotnettools.csharp",
|
||||
"formulahendry.dotnet-test-explorer",
|
||||
"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
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
dotnet-version: '7.0.x'
|
||||
include-prerelease: true
|
||||
|
||||
- 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
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 3.1.x
|
||||
dotnet-version: 7.0.x
|
||||
|
||||
- name: Build with dotnet
|
||||
run: dotnet build ./eShopOnWeb.sln --configuration Release
|
||||
|
||||
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -10,7 +10,7 @@
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// 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": [],
|
||||
"cwd": "${workspaceFolder}/src/Web",
|
||||
"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.
|
||||
|
||||
> ### 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.
|
||||
|
||||
## 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.
|
||||
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}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
Directory.Packages.props = Directory.Packages.props
|
||||
docker-compose.override.yml = docker-compose.override.yml
|
||||
docker-compose.yml = docker-compose.yml
|
||||
.github\workflows\dotnetcore.yml = .github\workflows\dotnetcore.yml
|
||||
@@ -38,7 +39,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorAdmin", "src\BlazorAd
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorShared", "src\BlazorShared\BlazorShared.csproj", "{715CF7AF-A1EE-40A6-94A0-8DA3F3B2CAE9}"
|
||||
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
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "6.0.x",
|
||||
"version": "7.0.x",
|
||||
"rollForward": "latestFeature"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Microsoft.eShopWeb.ApplicationCore</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.GuardClauses" Version="4.0.1" />
|
||||
<PackageReference Include="Ardalis.Result" Version="4.1.0" />
|
||||
<PackageReference Include="Ardalis.Specification" Version="6.1.0" />
|
||||
<PackageReference Include="MediatR" Version="10.0.1" />
|
||||
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.5" />
|
||||
<PackageReference Include="Ardalis.GuardClauses" />
|
||||
<PackageReference Include="Ardalis.Result" />
|
||||
<PackageReference Include="Ardalis.Specification" />
|
||||
<PackageReference Include="System.Security.Claims" />
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
|
||||
<PackageReference Include="BlazorInputFile" Version="0.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.8" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="6.0.0" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Blazored.LocalStorage" />
|
||||
<PackageReference Include="BlazorInputFile" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" />
|
||||
<PackageReference Include="System.Net.Http.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -63,7 +63,7 @@ public class CustomAuthStateProvider : AuthenticationStateProvider
|
||||
|
||||
if (user == null || !user.IsAuthenticated)
|
||||
{
|
||||
return null;
|
||||
return new ClaimsPrincipal(new ClaimsIdentity());
|
||||
}
|
||||
|
||||
var identity = new ClaimsIdentity(
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@inject NavigationManager Navigation
|
||||
@using System.Web;
|
||||
|
||||
@inject NavigationManager Navigation
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
@code {
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Navigation.NavigateTo($"Identity/Account/Login?returnUrl=" +
|
||||
$"/{Uri.EscapeDataString(Navigation.ToBaseRelativePath(Navigation.Uri))}");
|
||||
var returnUrl = HttpUtility.UrlEncode($"/{Uri.EscapeDataString(Navigation.ToBaseRelativePath(Navigation.Uri))}");
|
||||
JsRuntime.InvokeVoidAsync("location.replace", $"Identity/Account/Login?returnUrl={returnUrl}");
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>BlazorShared</RootNamespace>
|
||||
<AssemblyName>BlazorShared</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BlazorInputFile" Version="0.2.0" />
|
||||
<PackageReference Include="FluentValidation" Version="11.2.1" />
|
||||
<PackageReference Include="BlazorInputFile" />
|
||||
<PackageReference Include="FluentValidation" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Microsoft.eShopWeb.Infrastructure</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" Version="6.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.0" />
|
||||
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ApplicationCore\ApplicationCore.csproj" />
|
||||
|
||||
@@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogBrandEndpoints;
|
||||
/// <summary>
|
||||
/// List Catalog Brands
|
||||
/// </summary>
|
||||
public class CatalogBrandListEndpoint : IEndpoint<IResult>
|
||||
public class CatalogBrandListEndpoint : IEndpoint<IResult, IRepository<CatalogBrand>>
|
||||
{
|
||||
private IRepository<CatalogBrand> _catalogBrandRepository;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public CatalogBrandListEndpoint(IMapper mapper)
|
||||
@@ -28,18 +27,17 @@ public class CatalogBrandListEndpoint : IEndpoint<IResult>
|
||||
app.MapGet("api/catalog-brands",
|
||||
async (IRepository<CatalogBrand> catalogBrandRepository) =>
|
||||
{
|
||||
_catalogBrandRepository = catalogBrandRepository;
|
||||
return await HandleAsync();
|
||||
return await HandleAsync(catalogBrandRepository);
|
||||
})
|
||||
.Produces<ListCatalogBrandsResponse>()
|
||||
.WithTags("CatalogBrandEndpoints");
|
||||
}
|
||||
|
||||
public async Task<IResult> HandleAsync()
|
||||
public async Task<IResult> HandleAsync(IRepository<CatalogBrand> catalogBrandRepository)
|
||||
{
|
||||
var response = new ListCatalogBrandsResponse();
|
||||
|
||||
var items = await _catalogBrandRepository.ListAsync();
|
||||
var items = await catalogBrandRepository.ListAsync();
|
||||
|
||||
response.CatalogBrands.AddRange(items.Select(_mapper.Map<CatalogBrandDto>));
|
||||
|
||||
|
||||
@@ -11,9 +11,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
||||
/// <summary>
|
||||
/// Get a Catalog Item by Id
|
||||
/// </summary>
|
||||
public class CatalogItemGetByIdEndpoint : IEndpoint<IResult, GetByIdCatalogItemRequest>
|
||||
public class CatalogItemGetByIdEndpoint : IEndpoint<IResult, GetByIdCatalogItemRequest, IRepository<CatalogItem>>
|
||||
{
|
||||
private IRepository<CatalogItem> _itemRepository;
|
||||
private readonly IUriComposer _uriComposer;
|
||||
|
||||
public CatalogItemGetByIdEndpoint(IUriComposer uriComposer)
|
||||
@@ -26,18 +25,17 @@ public class CatalogItemGetByIdEndpoint : IEndpoint<IResult, GetByIdCatalogItemR
|
||||
app.MapGet("api/catalog-items/{catalogItemId}",
|
||||
async (int catalogItemId, IRepository<CatalogItem> itemRepository) =>
|
||||
{
|
||||
_itemRepository = itemRepository;
|
||||
return await HandleAsync(new GetByIdCatalogItemRequest(catalogItemId));
|
||||
return await HandleAsync(new GetByIdCatalogItemRequest(catalogItemId), itemRepository);
|
||||
})
|
||||
.Produces<GetByIdCatalogItemResponse>()
|
||||
.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 item = await _itemRepository.GetByIdAsync(request.CatalogItemId);
|
||||
var item = await itemRepository.GetByIdAsync(request.CatalogItemId);
|
||||
if (item is null)
|
||||
return Results.NotFound();
|
||||
|
||||
|
||||
@@ -15,9 +15,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
||||
/// <summary>
|
||||
/// List Catalog Items (paged)
|
||||
/// </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 IMapper _mapper;
|
||||
|
||||
@@ -32,19 +31,19 @@ public class CatalogItemListPagedEndpoint : IEndpoint<IResult, ListPagedCatalogI
|
||||
app.MapGet("api/catalog-items",
|
||||
async (int? pageSize, int? pageIndex, int? catalogBrandId, int? catalogTypeId, IRepository<CatalogItem> itemRepository) =>
|
||||
{
|
||||
_itemRepository = itemRepository;
|
||||
return await HandleAsync(new ListPagedCatalogItemRequest(pageSize, pageIndex, catalogBrandId, catalogTypeId));
|
||||
return await HandleAsync(new ListPagedCatalogItemRequest(pageSize, pageIndex, catalogBrandId, catalogTypeId), itemRepository);
|
||||
})
|
||||
.Produces<ListPagedCatalogItemResponse>()
|
||||
.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 filterSpec = new CatalogFilterSpecification(request.CatalogBrandId, request.CatalogTypeId);
|
||||
int totalItems = await _itemRepository.CountAsync(filterSpec);
|
||||
int totalItems = await itemRepository.CountAsync(filterSpec);
|
||||
|
||||
var pagedSpec = new CatalogFilterPaginatedSpecification(
|
||||
skip: request.PageIndex.Value * request.PageSize.Value,
|
||||
@@ -52,7 +51,7 @@ public class CatalogItemListPagedEndpoint : IEndpoint<IResult, ListPagedCatalogI
|
||||
brandId: request.CatalogBrandId,
|
||||
typeId: request.CatalogTypeId);
|
||||
|
||||
var items = await _itemRepository.ListAsync(pagedSpec);
|
||||
var items = await itemRepository.ListAsync(pagedSpec);
|
||||
|
||||
response.CatalogItems.AddRange(items.Select(_mapper.Map<CatalogItemDto>));
|
||||
foreach (CatalogItemDto item in response.CatalogItems)
|
||||
|
||||
@@ -15,9 +15,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
||||
/// <summary>
|
||||
/// Creates a new Catalog Item
|
||||
/// </summary>
|
||||
public class CreateCatalogItemEndpoint : IEndpoint<IResult, CreateCatalogItemRequest>
|
||||
public class CreateCatalogItemEndpoint : IEndpoint<IResult, CreateCatalogItemRequest, IRepository<CatalogItem>>
|
||||
{
|
||||
private IRepository<CatalogItem> _itemRepository;
|
||||
private readonly 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
|
||||
(CreateCatalogItemRequest request, IRepository<CatalogItem> itemRepository) =>
|
||||
{
|
||||
_itemRepository = itemRepository;
|
||||
return await HandleAsync(request);
|
||||
return await HandleAsync(request, itemRepository);
|
||||
})
|
||||
.Produces<CreateCatalogItemResponse>()
|
||||
.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 catalogItemNameSpecification = new CatalogItemNameSpecification(request.Name);
|
||||
var existingCataloogItem = await _itemRepository.CountAsync(catalogItemNameSpecification);
|
||||
var existingCataloogItem = await itemRepository.CountAsync(catalogItemNameSpecification);
|
||||
if (existingCataloogItem > 0)
|
||||
{
|
||||
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);
|
||||
newItem = await _itemRepository.AddAsync(newItem);
|
||||
newItem = await itemRepository.AddAsync(newItem);
|
||||
|
||||
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.
|
||||
|
||||
newItem.UpdatePictureUri("eCatalog-item-default.png");
|
||||
await _itemRepository.UpdateAsync(newItem);
|
||||
await itemRepository.UpdateAsync(newItem);
|
||||
}
|
||||
|
||||
var dto = new CatalogItemDto
|
||||
|
||||
@@ -13,32 +13,29 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
||||
/// <summary>
|
||||
/// Deletes a Catalog Item
|
||||
/// </summary>
|
||||
public class DeleteCatalogItemEndpoint : IEndpoint<IResult, DeleteCatalogItemRequest>
|
||||
public class DeleteCatalogItemEndpoint : IEndpoint<IResult, DeleteCatalogItemRequest, IRepository<CatalogItem>>
|
||||
{
|
||||
private IRepository<CatalogItem> _itemRepository;
|
||||
|
||||
public void AddRoute(IEndpointRouteBuilder app)
|
||||
{
|
||||
app.MapDelete("api/catalog-items/{catalogItemId}",
|
||||
[Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async
|
||||
(int catalogItemId, IRepository<CatalogItem> itemRepository) =>
|
||||
{
|
||||
_itemRepository = itemRepository;
|
||||
return await HandleAsync(new DeleteCatalogItemRequest(catalogItemId));
|
||||
return await HandleAsync(new DeleteCatalogItemRequest(catalogItemId), itemRepository);
|
||||
})
|
||||
.Produces<DeleteCatalogItemResponse>()
|
||||
.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 itemToDelete = await _itemRepository.GetByIdAsync(request.CatalogItemId);
|
||||
var itemToDelete = await itemRepository.GetByIdAsync(request.CatalogItemId);
|
||||
if (itemToDelete is null)
|
||||
return Results.NotFound();
|
||||
|
||||
await _itemRepository.DeleteAsync(itemToDelete);
|
||||
await itemRepository.DeleteAsync(itemToDelete);
|
||||
|
||||
return Results.Ok(response);
|
||||
}
|
||||
|
||||
@@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
||||
/// <summary>
|
||||
/// Updates a Catalog Item
|
||||
/// </summary>
|
||||
public class UpdateCatalogItemEndpoint : IEndpoint<IResult, UpdateCatalogItemRequest>
|
||||
public class UpdateCatalogItemEndpoint : IEndpoint<IResult, UpdateCatalogItemRequest, IRepository<CatalogItem>>
|
||||
{
|
||||
private IRepository<CatalogItem> _itemRepository;
|
||||
private readonly 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
|
||||
(UpdateCatalogItemRequest request, IRepository<CatalogItem> itemRepository) =>
|
||||
{
|
||||
_itemRepository = itemRepository;
|
||||
return await HandleAsync(request);
|
||||
return await HandleAsync(request, itemRepository);
|
||||
})
|
||||
.Produces<UpdateCatalogItemResponse>()
|
||||
.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 existingItem = await _itemRepository.GetByIdAsync(request.Id);
|
||||
var existingItem = await itemRepository.GetByIdAsync(request.Id);
|
||||
|
||||
CatalogItem.CatalogItemDetails details = new(request.Name, request.Description, request.Price);
|
||||
existingItem.UpdateDetails(details);
|
||||
existingItem.UpdateBrand(request.CatalogBrandId);
|
||||
existingItem.UpdateType(request.CatalogTypeId);
|
||||
|
||||
await _itemRepository.UpdateAsync(existingItem);
|
||||
await itemRepository.UpdateAsync(existingItem);
|
||||
|
||||
var dto = new CatalogItemDto
|
||||
{
|
||||
|
||||
@@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogTypeEndpoints;
|
||||
/// <summary>
|
||||
/// List Catalog Types
|
||||
/// </summary>
|
||||
public class CatalogTypeListEndpoint : IEndpoint<IResult>
|
||||
public class CatalogTypeListEndpoint : IEndpoint<IResult, IRepository<CatalogType>>
|
||||
{
|
||||
private IRepository<CatalogType> _catalogTypeRepository;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public CatalogTypeListEndpoint(IMapper mapper)
|
||||
@@ -28,18 +27,17 @@ public class CatalogTypeListEndpoint : IEndpoint<IResult>
|
||||
app.MapGet("api/catalog-types",
|
||||
async (IRepository<CatalogType> catalogTypeRepository) =>
|
||||
{
|
||||
_catalogTypeRepository = catalogTypeRepository;
|
||||
return await HandleAsync();
|
||||
return await HandleAsync(catalogTypeRepository);
|
||||
})
|
||||
.Produces<ListCatalogTypesResponse>()
|
||||
.WithTags("CatalogTypeEndpoints");
|
||||
}
|
||||
|
||||
public async Task<IResult> HandleAsync()
|
||||
public async Task<IResult> HandleAsync(IRepository<CatalogType> catalogTypeRepository)
|
||||
{
|
||||
var response = new ListCatalogTypesResponse();
|
||||
|
||||
var items = await _catalogTypeRepository.ListAsync();
|
||||
var items = await catalogTypeRepository.ListAsync();
|
||||
|
||||
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.
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
#COPY ["src/PublicApi/PublicApi.csproj", "./PublicApi/"]
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BlazorShared;
|
||||
using BlazorShared.Models;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
@@ -83,9 +82,8 @@ builder.Services.AddCors(options =>
|
||||
});
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddMediatR(typeof(CatalogItem).Assembly);
|
||||
builder.Services.AddAutoMapper(typeof(MappingProfile).Assembly);
|
||||
builder.Configuration.AddEnvironmentVariables();
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
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": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
@@ -25,6 +16,32 @@
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"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">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Microsoft.eShopWeb.PublicApi</RootNamespace>
|
||||
<UserSecretsId>5b662463-1efd-4bae-bde4-befe0be3e8ff</UserSecretsId>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
@@ -10,28 +9,26 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.ApiEndpoints" Version="4.0.1" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
||||
<PackageReference Include="MediatR" Version="10.0.1" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
|
||||
<PackageReference Include="MinimalApi.Endpoint" Version="1.2.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.4.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.4.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8">
|
||||
<PackageReference Include="Ardalis.ApiEndpoints" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" />
|
||||
<PackageReference Include="MinimalApi.Endpoint" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" />
|
||||
<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>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "6.0.4",
|
||||
"version": "7.0.2",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
@@ -10,7 +7,6 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.eShopWeb.Infrastructure.Identity;
|
||||
using Microsoft.eShopWeb.Web.Configuration;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using MediatR;
|
||||
using Microsoft.eShopWeb.Web.Interfaces;
|
||||
using Microsoft.eShopWeb.Web.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.eShopWeb.Web.Configuration;
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Claims;
|
||||
using BlazorShared.Authorization;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
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;
|
||||
|
||||
@@ -14,10 +17,19 @@ namespace Microsoft.eShopWeb.Web.Controllers;
|
||||
public class UserController : ControllerBase
|
||||
{
|
||||
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;
|
||||
_signInManager = signInManager;
|
||||
_logger = logger;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -26,6 +38,25 @@ public class UserController : ControllerBase
|
||||
public async Task<IActionResult> GetCurrentUser() =>
|
||||
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)
|
||||
{
|
||||
if (claimsPrincipal.Identity == null || claimsPrincipal.Identity.Name == null || !claimsPrincipal.Identity.IsAuthenticated)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
# RUN COMMAND
|
||||
# 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
|
||||
|
||||
COPY *.sln .
|
||||
@@ -17,7 +17,7 @@ RUN dotnet restore
|
||||
|
||||
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
|
||||
COPY --from=build /app/src/Web/out ./
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
||||
|
||||
@@ -53,7 +53,7 @@ builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
builder.Services.AddScoped<ITokenClaimsService, IdentityTokenClaimService>();
|
||||
|
||||
builder.Configuration.AddEnvironmentVariables();
|
||||
builder.Services.AddCoreServices(builder.Configuration);
|
||||
builder.Services.AddWebServices(builder.Configuration);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>Microsoft.eShopWeb.Web</RootNamespace>
|
||||
@@ -14,28 +13,28 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.ListStartupServices" Version="1.1.4" />
|
||||
<PackageReference Include="Ardalis.Specification" Version="6.1.0" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
||||
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.2.1" />
|
||||
<PackageReference Include="Azure.Identity" Version="1.5.0" />
|
||||
<PackageReference Include="MediatR" Version="10.0.1" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
|
||||
<PackageReference Include="BuildBundlerMinifier" Version="3.2.449" Condition="'$(Configuration)'=='Release'" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8">
|
||||
<PackageReference Include="Ardalis.ListStartupServices" />
|
||||
<PackageReference Include="Ardalis.Specification" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" />
|
||||
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="MediatR" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" />
|
||||
<PackageReference Include="BuildBundlerMinifier" Condition="'$(Configuration)'=='Release'" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" />
|
||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\fonts\" />
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
"defaultProvider": "cdnjs",
|
||||
"libraries": [
|
||||
{
|
||||
"library": "jquery@3.3.1",
|
||||
"library": "jquery@3.6.3",
|
||||
"destination": "wwwroot/lib/jquery/"
|
||||
},
|
||||
{
|
||||
"library": "twitter-bootstrap@3.3.7",
|
||||
"library": "twitter-bootstrap@5.2.3",
|
||||
"files": [
|
||||
"css/bootstrap.css",
|
||||
"css/bootstrap.css.map",
|
||||
@@ -19,11 +19,11 @@
|
||||
"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/"
|
||||
},
|
||||
{
|
||||
"library": "jquery-validate@1.17.0",
|
||||
"library": "jquery-validate@1.19.5",
|
||||
"destination": "wwwroot/lib/jquery-validate/",
|
||||
"files": [
|
||||
"jquery.validate.min.js",
|
||||
@@ -35,7 +35,7 @@
|
||||
"destination": "wwwroot/lib/toastr/"
|
||||
},
|
||||
{
|
||||
"library": "aspnet-signalr@1.0.3",
|
||||
"library": "aspnet-signalr@1.0.27",
|
||||
"files": [
|
||||
"signalr.js",
|
||||
"signalr.min.js"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Microsoft.eShopWeb.FunctionalTests</RootNamespace>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -15,15 +14,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Microsoft.eShopWeb.IntegrationTests</RootNamespace>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Moq" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
|
||||
using Microsoft.eShopWeb.Web.ViewModels;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PublicApiIntegrationTests.CatalogItemEndpoints
|
||||
@@ -45,5 +48,26 @@ namespace PublicApiIntegrationTests.CatalogItemEndpoints
|
||||
|
||||
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">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
@@ -20,11 +19,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="MSTest.TestAdapter" />
|
||||
<PackageReference Include="MSTest.TestFramework" />
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Microsoft.eShopWeb.UnitTests</RootNamespace>
|
||||
<IsPackable>false</IsPackable>
|
||||
@@ -10,18 +9,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<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>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Moq" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
<PackageReference Include="xunit.runner.console" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user