manage conflict (generic way) use toast to show error (#588)
* manage conflict (generic way) use toast to show error * fix httpservice after merge conflict, adapt to use new repository
This commit is contained in:
@@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopWeb.ApplicationCore.Exceptions
|
|
||||||
{
|
|
||||||
public class DuplicateCatalogItemNameException : Exception
|
|
||||||
{
|
|
||||||
public DuplicateCatalogItemNameException(string message, int duplicateItemId) : base(message)
|
|
||||||
{
|
|
||||||
DuplicateItemId = duplicateItemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int DuplicateItemId { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
14
src/ApplicationCore/Exceptions/DuplicateException.cs
Normal file
14
src/ApplicationCore/Exceptions/DuplicateException.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopWeb.ApplicationCore.Exceptions
|
||||||
|
{
|
||||||
|
|
||||||
|
public class DuplicateException : Exception
|
||||||
|
{
|
||||||
|
public DuplicateException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Ardalis.Specification;
|
||||||
|
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopWeb.ApplicationCore.Specifications
|
||||||
|
{
|
||||||
|
public class CatalogItemNameSpecification : Specification<CatalogItem>
|
||||||
|
{
|
||||||
|
public CatalogItemNameSpecification(string catalogItemName)
|
||||||
|
{
|
||||||
|
Query.Where(item => string.Compare(catalogItemName, item.Name, true) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
src/BlazorAdmin/Helpers/ToastComponent.cs
Normal file
88
src/BlazorAdmin/Helpers/ToastComponent.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using BlazorAdmin.Services;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BlazorAdmin.Helpers
|
||||||
|
{
|
||||||
|
public class ToastComponent : ComponentBase, IDisposable
|
||||||
|
{
|
||||||
|
[Inject]
|
||||||
|
ToastService ToastService
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
protected string Heading
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
protected string Message
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
protected bool IsVisible
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
protected string BackgroundCssClass
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
protected string IconCssClass
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
ToastService.OnShow += ShowToast;
|
||||||
|
ToastService.OnHide += HideToast;
|
||||||
|
}
|
||||||
|
private void ShowToast(string message, ToastLevel level)
|
||||||
|
{
|
||||||
|
BuildToastSettings(level, message);
|
||||||
|
IsVisible = true;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
private void HideToast()
|
||||||
|
{
|
||||||
|
IsVisible = false;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
private void BuildToastSettings(ToastLevel level, string message)
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case ToastLevel.Info:
|
||||||
|
BackgroundCssClass = "bg-info";
|
||||||
|
IconCssClass = "info";
|
||||||
|
Heading = "Info";
|
||||||
|
break;
|
||||||
|
case ToastLevel.Success:
|
||||||
|
BackgroundCssClass = "bg-success";
|
||||||
|
IconCssClass = "check";
|
||||||
|
Heading = "Success";
|
||||||
|
break;
|
||||||
|
case ToastLevel.Warning:
|
||||||
|
BackgroundCssClass = "bg-warning";
|
||||||
|
IconCssClass = "exclamation";
|
||||||
|
Heading = "Warning";
|
||||||
|
break;
|
||||||
|
case ToastLevel.Error:
|
||||||
|
BackgroundCssClass = "bg-danger";
|
||||||
|
IconCssClass = "times";
|
||||||
|
Heading = "Error";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Message = message;
|
||||||
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ToastService.OnShow -= ShowToast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -106,13 +106,13 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<CatalogType> Types { get; set; }
|
public IEnumerable<CatalogType> Types { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<string> OnSaveClick { get; set; }
|
public EventCallback<string> OnSaveClick { get; set; }
|
||||||
|
|
||||||
private string LoadPicture => string.IsNullOrEmpty(_item.PictureBase64) ? string.Empty : $"data:image/png;base64, {_item.PictureBase64}";
|
private string LoadPicture => string.IsNullOrEmpty(_item.PictureBase64) ? string.Empty : $"data:image/png;base64, {_item.PictureBase64}";
|
||||||
private bool HasPicture => !string.IsNullOrEmpty(_item.PictureBase64);
|
private bool HasPicture => !string.IsNullOrEmpty(_item.PictureBase64);
|
||||||
@@ -124,13 +124,17 @@
|
|||||||
|
|
||||||
private async Task CreateClick()
|
private async Task CreateClick()
|
||||||
{
|
{
|
||||||
await CatalogItemService.Create(_item);
|
var result = await CatalogItemService.Create(_item);
|
||||||
await OnSaveClick.InvokeAsync(null);
|
if (result != null)
|
||||||
await Close();
|
{
|
||||||
|
await OnSaveClick.InvokeAsync(null);
|
||||||
|
await Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Open()
|
public async Task Open()
|
||||||
{
|
{
|
||||||
|
|
||||||
Logger.LogInformation("Now loading... /Catalog/Create");
|
Logger.LogInformation("Now loading... /Catalog/Create");
|
||||||
|
|
||||||
await new Css(JSRuntime).HideBodyOverflow();
|
await new Css(JSRuntime).HideBodyOverflow();
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ namespace BlazorAdmin
|
|||||||
|
|
||||||
builder.Services.AddScoped(sp => new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
builder.Services.AddScoped(sp => new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||||
|
|
||||||
|
builder.Services.AddScoped<ToastService>();
|
||||||
builder.Services.AddScoped<HttpService>();
|
builder.Services.AddScoped<HttpService>();
|
||||||
|
|
||||||
|
|
||||||
builder.Services.AddScoped<ILocalStorageService, LocalStorageService>();
|
builder.Services.AddScoped<ILocalStorageService, LocalStorageService>();
|
||||||
|
|
||||||
builder.Services.AddAuthorizationCore();
|
builder.Services.AddAuthorizationCore();
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ namespace BlazorAdmin.Services
|
|||||||
|
|
||||||
public async Task<CatalogItem> Create(CreateCatalogItemRequest catalogItem)
|
public async Task<CatalogItem> Create(CreateCatalogItemRequest catalogItem)
|
||||||
{
|
{
|
||||||
return (await _httpService.HttpPost<CreateCatalogItemResponse>("catalog-items", catalogItem)).CatalogItem;
|
var response = await _httpService.HttpPost<CreateCatalogItemResponse>("catalog-items", catalogItem);
|
||||||
|
return response?.CatalogItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CatalogItem> Edit(CatalogItem catalogItem)
|
public async Task<CatalogItem> Edit(CatalogItem catalogItem)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using BlazorShared;
|
using BlazorShared;
|
||||||
|
using BlazorShared.Models;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -9,11 +10,14 @@ namespace BlazorAdmin.Services
|
|||||||
public class HttpService
|
public class HttpService
|
||||||
{
|
{
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
|
private readonly ToastService _toastService;
|
||||||
private readonly string _apiUrl;
|
private readonly string _apiUrl;
|
||||||
|
|
||||||
public HttpService(HttpClient httpClient, BaseUrlConfiguration baseUrlConfiguration)
|
|
||||||
|
public HttpService(HttpClient httpClient, BaseUrlConfiguration baseUrlConfiguration, ToastService toastService)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
|
_toastService = toastService;
|
||||||
_apiUrl = baseUrlConfiguration.ApiBase;
|
_apiUrl = baseUrlConfiguration.ApiBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +53,12 @@ namespace BlazorAdmin.Services
|
|||||||
var result = await _httpClient.PostAsync($"{_apiUrl}{uri}", content);
|
var result = await _httpClient.PostAsync($"{_apiUrl}{uri}", content);
|
||||||
if (!result.IsSuccessStatusCode)
|
if (!result.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
var exception = JsonSerializer.Deserialize<ErrorDetails>(await result.Content.ReadAsStringAsync(), new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true
|
||||||
|
});
|
||||||
|
_toastService.ShowToast($"Error : {exception.Message}", ToastLevel.Error);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,13 +73,13 @@ namespace BlazorAdmin.Services
|
|||||||
var result = await _httpClient.PutAsync($"{_apiUrl}{uri}", content);
|
var result = await _httpClient.PutAsync($"{_apiUrl}{uri}", content);
|
||||||
if (!result.IsSuccessStatusCode)
|
if (!result.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
_toastService.ShowToast("Error", ToastLevel.Error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await FromHttpResponseMessage<T>(result);
|
return await FromHttpResponseMessage<T>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private StringContent ToJson(object obj)
|
private StringContent ToJson(object obj)
|
||||||
{
|
{
|
||||||
return new StringContent(JsonSerializer.Serialize(obj), Encoding.UTF8, "application/json");
|
return new StringContent(JsonSerializer.Serialize(obj), Encoding.UTF8, "application/json");
|
||||||
|
|||||||
55
src/BlazorAdmin/Services/ToastService.cs
Normal file
55
src/BlazorAdmin/Services/ToastService.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace BlazorAdmin.Services
|
||||||
|
{
|
||||||
|
public enum ToastLevel
|
||||||
|
{
|
||||||
|
Info,
|
||||||
|
Success,
|
||||||
|
Warning,
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToastService : IDisposable
|
||||||
|
{
|
||||||
|
public event Action<string, ToastLevel> OnShow;
|
||||||
|
public event Action OnHide;
|
||||||
|
private Timer Countdown;
|
||||||
|
public void ShowToast(string message, ToastLevel level)
|
||||||
|
{
|
||||||
|
OnShow?.Invoke(message, level);
|
||||||
|
StartCountdown();
|
||||||
|
}
|
||||||
|
private void StartCountdown()
|
||||||
|
{
|
||||||
|
SetCountdown();
|
||||||
|
if (Countdown.Enabled)
|
||||||
|
{
|
||||||
|
Countdown.Stop();
|
||||||
|
Countdown.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Countdown.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SetCountdown()
|
||||||
|
{
|
||||||
|
if (Countdown == null)
|
||||||
|
{
|
||||||
|
Countdown = new Timer(3000);
|
||||||
|
Countdown.Elapsed += HideToast;
|
||||||
|
Countdown.AutoReset = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void HideToast(object source, ElapsedEventArgs args)
|
||||||
|
{
|
||||||
|
OnHide?.Invoke();
|
||||||
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Countdown?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
@inherits BlazorAdmin.Helpers.BlazorLayoutComponent
|
@inherits BlazorAdmin.Helpers.BlazorLayoutComponent
|
||||||
|
|
||||||
|
|
||||||
<AuthorizeView Roles=@BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS>
|
<AuthorizeView Roles=@BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS>
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<NavMenu />
|
<NavMenu />
|
||||||
@@ -10,11 +11,13 @@
|
|||||||
</AuthorizeView>
|
</AuthorizeView>
|
||||||
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
|
|
||||||
<div class="top-row px-4">
|
<div class="top-row px-4">
|
||||||
<a href="https://github.com/dotnet-architecture/eShopOnWeb" target="_blank" class="ml-md-auto">About eShopOnWeb</a>
|
<a href="https://github.com/dotnet-architecture/eShopOnWeb" target="_blank" class="ml-md-auto">About eShopOnWeb</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content px-4">
|
<div class="content px-4">
|
||||||
|
<Toast></Toast>
|
||||||
@Body
|
@Body
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
13
src/BlazorAdmin/Shared/Toast.razor
Normal file
13
src/BlazorAdmin/Shared/Toast.razor
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
@inherits BlazorAdmin.Helpers.ToastComponent
|
||||||
|
|
||||||
|
@namespace BlazorAdmin.Shared
|
||||||
|
|
||||||
|
<div class="toast @(IsVisible ? "toast-visible" : null) @BackgroundCssClass">
|
||||||
|
<div class="toast-icon">
|
||||||
|
<i class="fa fa-@IconCssClass" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
<h5>@Heading</h5>
|
||||||
|
<p>@Message</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -153,6 +153,53 @@ a, .btn-link {
|
|||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
display: none;
|
||||||
|
padding: 1.5rem;
|
||||||
|
color: #fff;
|
||||||
|
z-index: 99999;
|
||||||
|
position: absolute;
|
||||||
|
width: 25rem;
|
||||||
|
top: 2rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-icon {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 01rem;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-body p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-visible {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
animation: fadein 1.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadein {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
.main .top-row:not(.auth) {
|
.main .top-row:not(.auth) {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
14
src/BlazorShared/Models/ErrorDetails.cs
Normal file
14
src/BlazorShared/Models/ErrorDetails.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace BlazorShared.Models
|
||||||
|
{
|
||||||
|
public class ErrorDetails
|
||||||
|
{
|
||||||
|
public int StatusCode { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,10 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||||
|
using Microsoft.eShopWeb.ApplicationCore.Exceptions;
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||||
|
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
||||||
using Swashbuckle.AspNetCore.Annotations;
|
using Swashbuckle.AspNetCore.Annotations;
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -38,8 +39,14 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints
|
|||||||
{
|
{
|
||||||
var response = new CreateCatalogItemResponse(request.CorrelationId());
|
var response = new CreateCatalogItemResponse(request.CorrelationId());
|
||||||
|
|
||||||
var newItem = new CatalogItem(request.CatalogTypeId, request.CatalogBrandId, request.Description, request.Name, request.Price, request.PictureUri);
|
var catalogItemNameSpecification = new CatalogItemNameSpecification(request.Name);
|
||||||
|
var existingCataloogItem = await _itemRepository.CountAsync(catalogItemNameSpecification, cancellationToken);
|
||||||
|
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, cancellationToken);
|
newItem = await _itemRepository.AddAsync(newItem, cancellationToken);
|
||||||
|
|
||||||
if (newItem.Id != 0)
|
if (newItem.Id != 0)
|
||||||
|
|||||||
46
src/PublicApi/MiddleWares/ExceptionMiddleware.cs
Normal file
46
src/PublicApi/MiddleWares/ExceptionMiddleware.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using BlazorShared.Models;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.eShopWeb.ApplicationCore.Exceptions;
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopWeb.PublicApi.MiddleWares
|
||||||
|
{
|
||||||
|
public class ExceptionMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
|
||||||
|
public ExceptionMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _next(httpContext);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await HandleExceptionAsync(httpContext, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
if (exception is DuplicateException duplicationException)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.Conflict;
|
||||||
|
await context.Response.WriteAsync(new ErrorDetails()
|
||||||
|
{
|
||||||
|
StatusCode = context.Response.StatusCode,
|
||||||
|
Message = duplicationException.Message
|
||||||
|
}.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ using Microsoft.eShopWeb.Infrastructure.Data;
|
|||||||
using Microsoft.eShopWeb.Infrastructure.Identity;
|
using Microsoft.eShopWeb.Infrastructure.Identity;
|
||||||
using Microsoft.eShopWeb.Infrastructure.Logging;
|
using Microsoft.eShopWeb.Infrastructure.Logging;
|
||||||
using Microsoft.eShopWeb.Infrastructure.Services;
|
using Microsoft.eShopWeb.Infrastructure.Services;
|
||||||
|
using Microsoft.eShopWeb.PublicApi.MiddleWares;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
@@ -178,6 +179,8 @@ namespace Microsoft.eShopWeb.PublicApi
|
|||||||
app.UseDeveloperExceptionPage();
|
app.UseDeveloperExceptionPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.UseMiddleware<ExceptionMiddleware>();
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ namespace Microsoft.eShopWeb.Web
|
|||||||
services.AddBlazoredLocalStorage();
|
services.AddBlazoredLocalStorage();
|
||||||
services.AddServerSideBlazor();
|
services.AddServerSideBlazor();
|
||||||
|
|
||||||
|
|
||||||
|
services.AddScoped<ToastService>();
|
||||||
services.AddScoped<HttpService>();
|
services.AddScoped<HttpService>();
|
||||||
services.AddBlazorServices();
|
services.AddBlazorServices();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user