Skip to content
This repository has been archived by the owner on Dec 2, 2023. It is now read-only.

Commit

Permalink
Project Break Out (#4)
Browse files Browse the repository at this point in the history
* Broke out project into an additional Abstraction project for users to be able to reference details from front end

Added client project to be able to support cleaner serialization and handling of ApiErrorDetails and standard objects

Added additional details and examples of other Http status codes

Changed example project to Blazor ASP.NET hosted

* Updated readme template and information. Removed 'AddExceptionAllClient' service collection helper. Added some unit tests

* Updated per PR#4Dev_Abstractions review
  • Loading branch information
1eyewonder authored Feb 18, 2022
1 parent 83d632d commit 56e059c
Show file tree
Hide file tree
Showing 129 changed files with 2,498 additions and 1,785 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ PublishScripts/

# NuGet Packages
*.nupkg
*.nuget.config.bak
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
Expand Down
12 changes: 12 additions & 0 deletions Example/Client/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
20 changes: 20 additions & 0 deletions Example/Client/Example.Client.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.1" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\ExceptionAll.Abstractions\ExceptionAll.Abstractions.csproj" />
<ProjectReference Include="..\..\src\ExceptionAll.Client\ExceptionAll.Client.csproj" />
<ProjectReference Include="..\Shared\Example.Shared.csproj" />
</ItemGroup>

</Project>
18 changes: 18 additions & 0 deletions Example/Client/Pages/Counter.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
private int currentCount = 0;

private void IncrementCount()
{
currentCount++;
}
}
47 changes: 47 additions & 0 deletions Example/Client/Pages/FetchData.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@page "/fetchdata"
@using Example.Shared
@inject HttpClient Http

<PageTitle>Weather forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}

@code {
private WeatherForecast[]? forecasts;

protected override async Task OnInitializedAsync()
{
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}
}
110 changes: 110 additions & 0 deletions Example/Client/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
@page "/"
@using ExceptionAll.Abstractions.Models
@using Example.Shared
@using ExceptionAll.Client.Exceptions
@using ExceptionAll.Client.Interfaces
@inject IExceptionAllClientFactory _exceptionAllClientFactory

<PageTitle>Index</PageTitle>

<button @onclick="@Endpoint1">Endpoint 1</button>
<button @onclick="@Endpoint2">Endpoint 2</button>
<button @onclick="@Endpoint3">Endpoint 3</button>
<button @onclick="@Endpoint4">Endpoint 4</button>

<br/>

<h1>Error Details</h1>
<br/>
@if (_errorDetails != null)
{
<h2>Title: @_errorDetails.Title</h2> <br/>
<h2>Message: @_errorDetails.Message</h2> <br/>
<h2>StatusCode: @_errorDetails.StatusCode.ToString()</h2>
<br/>
@foreach (var detail in _errorDetails.ContextDetails)
{
<h2>@detail.Key: @detail.Value</h2>
<br/>
}
}

<h1>Forecast</h1>
<br/>
@if (_forecasts != null)
{
@foreach (var forecast in _forecasts)
{
<h2>@forecast.Summary</h2> <br/>
}
}

@code
{
private ApiErrorDetails? _errorDetails;
private WeatherForecast[]? _forecasts;
private IExceptionAllClient _exceptionAllClient;
private IExceptionAllClient _clientWithHeader;

protected override void OnInitialized()
{
_exceptionAllClient = _exceptionAllClientFactory.CreateClient();
_clientWithHeader = _exceptionAllClientFactory.CreateClient("Test");
}

private async Task Endpoint1()
{
try
{
_forecasts = await _exceptionAllClient.GetContentAsync<WeatherForecast[]>("https://localhost:44304/WeatherForecast");
_errorDetails = null;
}
catch (ExceptionAllException e)
{
_errorDetails = e.ErrorDetails;
_forecasts = null;
}
}

private async Task Endpoint2()
{
try
{
_forecasts = await _exceptionAllClient.GetContentAsync<WeatherForecast[]>("https://localhost:44304/WeatherForecast/api/GetNullRefError?param=1");
_errorDetails = null;
}
catch (ExceptionAllException e)
{
_errorDetails = e.ErrorDetails;
_forecasts = null;
}
}

private async Task Endpoint3()
{
try
{
_forecasts = await _clientWithHeader.GetContentAsync<WeatherForecast[]>("https://localhost:44304/WeatherForecast/api/GetSomething?test=123");
_errorDetails = null;
}
catch (ExceptionAllException e)
{
_errorDetails = e.ErrorDetails;
_forecasts = null;
}
}

private async Task Endpoint4()
{
try
{
_forecasts = await _clientWithHeader.GetContentAsync<WeatherForecast[]>("https://localhost:44304/WeatherForecast/api/success");
_errorDetails = null;
}
catch (ExceptionAllException e)
{
_errorDetails = e.ErrorDetails;
_forecasts = null;
}
}
}
23 changes: 23 additions & 0 deletions Example/Client/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Example.Client;
using ExceptionAll.Client.Helpers;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddExceptionAllClientServices();

// Addition of a standard http client
builder.Services.AddHttpClient();

// Addition of a different http client, which has a special header for tracing
builder.Services.AddHttpClient("Test", x =>
{
x.DefaultRequestHeaders.Add("x-correlation-id", Guid.NewGuid().ToString());
});

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51369",
"sslPort": 44377
"applicationUrl": "http://localhost:4162",
"sslPort": 44304
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"Example": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7014;http://localhost:5014",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ExceptionAll.APIExample": {
"commandName": "Project",
"dotnetRunMessages": "true",
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
Expand Down
17 changes: 17 additions & 0 deletions Example/Client/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@inherits LayoutComponentBase

<div class="page">
<div class="sidebar">
<NavMenu />
</div>

<main>
<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>

<article class="content px-4">
@Body
</article>
</main>
</div>
81 changes: 81 additions & 0 deletions Example/Client/Shared/MainLayout.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}

.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {
.top-row:not(.auth) {
display: none;
}

.top-row.auth {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}

@media (min-width: 641px) {
.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
Loading

0 comments on commit 56e059c

Please sign in to comment.