Browse Source
* manage conflict (generic way) use toast to show error * fix httpservice after merge conflict, adapt to use new repositorymain
committed by
GitHub
17 changed files with 337 additions and 29 deletions
@ -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; } |
|
||||
} |
|
||||
} |
|
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue