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