Merge pull request 'SES-91 Utworzenie modelu zwrotek AP oraz zajmowanie się domyślnymi exceptionami' (#22) from SES-91 into master
Reviewed-on: #22
This commit is contained in:
commit
cd1a0af239
@ -0,0 +1,119 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SessionCompanion.Extensions.EitherType
|
||||||
|
{
|
||||||
|
public class Either<TL, TR>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Kontruktor dla lewej zmiennej
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Wartość lewej zmiennej</param>
|
||||||
|
public Either(TL left)
|
||||||
|
{
|
||||||
|
this.Left = left;
|
||||||
|
this.IsLeft = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Konstruktor dla prawej zmiennej
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="right">Wartość prawej zmiennej</param>
|
||||||
|
public Either(TR right)
|
||||||
|
{
|
||||||
|
this.Right = right;
|
||||||
|
this.IsLeft = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lewa zmienna
|
||||||
|
/// </summary>
|
||||||
|
public TL Left { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prawa zmienna
|
||||||
|
/// </summary>
|
||||||
|
public TR Right { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zmienna informujaca czy wykorzystana zostąła zmienna lewa czy prawa
|
||||||
|
/// </summary>
|
||||||
|
public bool IsLeft { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tworzy obiekt typu Either wykorzystując zmienną lewą
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Wartość lewej zmiennej</param>
|
||||||
|
public static implicit operator Either<TL, TR>(TL left) => new Either<TL, TR>(left);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tworzy obiekt typu Either wykorzystując zmienną prawą
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="right">Wartosć prawej zmiennej</param>
|
||||||
|
public static implicit operator Either<TL, TR>(TR right) => new Either<TL, TR>(right);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bazowa metoda dopasowania wzorów.
|
||||||
|
/// Jeśli podana jest wartość lewa, to Match zwróci wynik lewej funkcji, w przeciwnym razie wynik prawej funkcji.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Typ zwracanej wartości</typeparam>
|
||||||
|
/// <param name="leftFunc">Lewa funkcja </param>
|
||||||
|
/// <param name="rightFunc">Prawa funkcja</param>
|
||||||
|
/// <returns>Wynik prawej/lewej funkcji</returns>
|
||||||
|
public T Match<T>(Func<TL, T> leftFunc, Func<TR, T> rightFunc)
|
||||||
|
{
|
||||||
|
if (leftFunc == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(leftFunc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightFunc == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(rightFunc));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.IsLeft ? leftFunc(this.Left) : rightFunc(this.Right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bazowa metoda dopasowania wzorów.
|
||||||
|
/// Jeśli podana jest wartość lewa, to Match wykona lewą funkcję, w przeciwnym razie wykona funkcję prawą.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="leftFunc">Lewa funkcja </param>
|
||||||
|
/// <param name="rightFunc">Prawa funkcja</param>
|
||||||
|
public void Match(Action<TL> leftFunc, Action<TR> rightFunc)
|
||||||
|
{
|
||||||
|
if (leftFunc == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(leftFunc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightFunc == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(rightFunc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.IsLeft)
|
||||||
|
{
|
||||||
|
leftFunc(this.Left);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rightFunc(this.Right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Funkcja ustala czy uzyta została lewa zmienna, jesli tak to zwraca jej wartość inaczej zwraca defaultowy obiekt
|
||||||
|
/// o typie takim jak lewa zmienna
|
||||||
|
/// </summary>
|
||||||
|
/// <returns> Wartosć lewej zmiennej lub defaultową wartość o typie lewej zmiennej</returns>
|
||||||
|
public TL LeftOrDefault() => this.Match(l => l, r => default(TL));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Funkcja ustala czy uzyta została prawa zmienna, jesli tak to zwraca jej wartość inaczej zwraca defaultowy obiekt
|
||||||
|
/// o typie takim jak lewa zmienna
|
||||||
|
/// </summary>
|
||||||
|
/// <returns> Wartosć lewej zmiennej lub defaultową wartość o typie prawej zmiennej</returns>
|
||||||
|
public TR RightOrDefault() => this.Match(l => default(TR), r => r);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,184 @@
|
|||||||
|
# Either
|
||||||
|
|
||||||
|
### Jak używać
|
||||||
|
|
||||||
|
Either umożliwa nam zwrócenie z metody bądź nawet kontrolera, dwóch możliwych wyników.
|
||||||
|
Dla ułatwienia zrozumienai poniżej podaję przykłady stosowania.
|
||||||
|
|
||||||
|
Jako typ zmiennej zwracanej z api:
|
||||||
|
W tym przypadku wskazujemy, że nasze api zwróci albo CharacterViewModel albo ErrorResponse
|
||||||
|
```cs
|
||||||
|
public async Task<Either<CharacterViewModel, ErrorResponse>> Get(int id)
|
||||||
|
```
|
||||||
|
Aby zwrócić ten typ mamy dwie możliwości.
|
||||||
|
Możemy wywołać metodę z serisu, która ma nam zwrócić CharacterViewModel.
|
||||||
|
Następnie sprawdzić czy otrzymana wartość CharacerViewModel zawiera jakiekolwiek dane i odpowiednio, jeśli tak to zwracamy otrzymany viewmodel a jeśli nie tworzymy ErrorResponse i zwracamy wynik:
|
||||||
|
```cs
|
||||||
|
public async Task<Either<CharacterViewModel, ErrorResponse>> Get(int id)
|
||||||
|
{
|
||||||
|
Either<CharacterViewModel, ErrorResponse> result = await _service.Get(id);
|
||||||
|
|
||||||
|
if (result.Left != null)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = new ErrorResponse { StatusCode = 400, Message = "Coś poszło nie tak" };
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
W przypadku jesli serwis nie znajdzie wartości otrzymamy:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"left":null,
|
||||||
|
"right":{
|
||||||
|
"statusCode":400,
|
||||||
|
"message":"Coś poszło nie tak"},
|
||||||
|
"isLeft":false}
|
||||||
|
```
|
||||||
|
|
||||||
|
Drugim sposobem jest zmiana działania serwisu:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
public async Task<Either<CharacterViewModel, ErrorResponse>> GetCharacter(int id)
|
||||||
|
{
|
||||||
|
var repoResult = await this.Repository.Get(id);
|
||||||
|
if (repoResult != null)
|
||||||
|
{
|
||||||
|
return Mapper.Map<CharacterViewModel>(repoResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new ErrorResponse()
|
||||||
|
{
|
||||||
|
StatusCode = 404,
|
||||||
|
Message = "Coś poszło nie tak"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Wtedy kontroler wygląda tak :
|
||||||
|
```sh
|
||||||
|
public async Task<Either<CharacterViewModel, ErrorResponse>> Get(int id)
|
||||||
|
{
|
||||||
|
return await this._service.GetCharacter(id);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Przypisanie nowej wartości
|
||||||
|
Jeśli z jakiegośpowodu będziemy chcieli zmienić wartość obiektu Either, musimy dokonać tego w taki oto sposób:
|
||||||
|
```cs
|
||||||
|
UserViewModel user = new UserViewModel() { Id = 1, Nickname = "Testowy", Password = "Secret" };
|
||||||
|
Either<UserViewModel, string> test = "asd";
|
||||||
|
|
||||||
|
// zmieniamy wartość Either
|
||||||
|
test = user;
|
||||||
|
|
||||||
|
// Warto zauważyć, że możemy zmienić wartość obiektu znajdujacego się wewnątrz
|
||||||
|
// którejś ze zmiennej o ile jest on publiczny
|
||||||
|
test.Left.Nickname = "test";
|
||||||
|
|
||||||
|
// Jednak jeśli dokonamy tego po zmianie wartości obietu na inny pomimo tego, że
|
||||||
|
// dla kodu jest to ok, to nie zadziała to poprawnie, ponieważ wartość starego obiektu
|
||||||
|
// jest zmieniana na null(dla boola na false)
|
||||||
|
test = "asd";
|
||||||
|
test.Left.Nickname = "błąd";
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### LeftOrDefault() oraz RightOrDefault()
|
||||||
|
|
||||||
|
Zwracają one wartość wybranej zmiennej bądź jej wartość defaultową.
|
||||||
|
Dla wiekszości obiektów jest to null, wyjatkiem jest tutaj bool, który zwróci nam false.
|
||||||
|
```cs
|
||||||
|
var test = (Either<bool, string>)true;
|
||||||
|
|
||||||
|
var a = test.LeftOrDefault(); // zwróci nam true
|
||||||
|
var b = test.RightOrDefault(); // zwróci nam null
|
||||||
|
|
||||||
|
test = "asd";
|
||||||
|
|
||||||
|
var c = test.LeftOrDefault(); // zwróci nam false
|
||||||
|
var d = test.RightOrDefault(); // zwróci nam "asd"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Match
|
||||||
|
|
||||||
|
Funkcja ta pozwala nam na odpalenie odpowiedniej metody w zależności od tego jako typ zmiennej jest aktualnie przechowywany w obiekcie Either. Niestety ograniczeniem jest to, ze obie funkcje musza docelowo zwrócić ten sam typ.
|
||||||
|
```cs
|
||||||
|
// ładujemy userviewmodel do obiektu Either i wywoływamy matcha pdając dwie funkcje
|
||||||
|
test = user;
|
||||||
|
// zwwrócny zostanie string "Test1"
|
||||||
|
test.Match(this.Test1, this.Test2);
|
||||||
|
|
||||||
|
// ładujemy stringa do obiektu Either i wywoływamy matcha pdając dwie funkcje
|
||||||
|
test = "asd";
|
||||||
|
// zwwrócny zostanie string "Test2"
|
||||||
|
test.Match(this.Test1, this.Test2);
|
||||||
|
|
||||||
|
public string Test1(UserViewModel viewModel)
|
||||||
|
{
|
||||||
|
return "Test1";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Test2(string text)
|
||||||
|
{
|
||||||
|
return "Test2";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Warto zauważyć, że możemy wykorzystać tutaj lambde by rozszerzyć nasze możliwości:
|
||||||
|
```cs
|
||||||
|
test = "asd";
|
||||||
|
|
||||||
|
test.Match(
|
||||||
|
Test1,
|
||||||
|
second =>
|
||||||
|
{
|
||||||
|
int z = Test2(second);
|
||||||
|
// tutaj możemy robić już co nam się tylko podoba
|
||||||
|
// pamiętać należy ze finalnie musimy coś zwrócić
|
||||||
|
// chyba, że nasze obie funkcje są typu void
|
||||||
|
return z.ToString();
|
||||||
|
});
|
||||||
|
|
||||||
|
public string Test1(UserViewModel viewModel)
|
||||||
|
{
|
||||||
|
return "Test1";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Test2(string text)
|
||||||
|
{
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Możemy też podać jedna funkcję typu void a drugą typu innego np. string albo int:
|
||||||
|
```cs
|
||||||
|
y = "";
|
||||||
|
test = "asd";
|
||||||
|
|
||||||
|
test.Match(
|
||||||
|
Test1,
|
||||||
|
second =>
|
||||||
|
{
|
||||||
|
var x = this.Test2(second);
|
||||||
|
//jednak nie ma możliwości zwrócenia wartości
|
||||||
|
// możemy za to zwrócić wyniki do zewnętrznej zmiennej
|
||||||
|
y = x;
|
||||||
|
});
|
||||||
|
|
||||||
|
public void Test1(UserViewModel viewModel)
|
||||||
|
{
|
||||||
|
//...coś robi
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Test2(string text)
|
||||||
|
{
|
||||||
|
return "Test2";
|
||||||
|
}
|
||||||
|
```
|
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -11,8 +11,7 @@ namespace SessionCompanion.Services.Profiles
|
|||||||
{
|
{
|
||||||
public UserProfile()
|
public UserProfile()
|
||||||
{
|
{
|
||||||
CreateMap<UserViewModel, User>();
|
CreateMap<UserViewModel, User>().ReverseMap();
|
||||||
CreateMap<User, UserViewModel>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace SessionCompanion.ViewModels.ApiResponses
|
||||||
|
{
|
||||||
|
public class ErrorResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Kod błędu
|
||||||
|
/// </summary>
|
||||||
|
public int StatusCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wiadomość błędu do pokazania
|
||||||
|
/// </summary>
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
namespace SessionCompanion.ViewModels.ApiResponses
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Wiadomość mówiąca o poprawnym wykonaniu zadania
|
||||||
|
/// </summary>
|
||||||
|
public class SuccessResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Konstruktor obiektu
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"> Wiadomość dotycząca operacji </param>
|
||||||
|
public SuccessResponse(string message)
|
||||||
|
{
|
||||||
|
this.SuccessCode = 200;
|
||||||
|
this.SuccessMessage = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Kod odpowiedzi, domyślnie nadawany jest 200
|
||||||
|
/// </summary>
|
||||||
|
public int SuccessCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wiadomość dotycząca wykoanania operacji
|
||||||
|
/// </summary>
|
||||||
|
public string SuccessMessage { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SessionCompanion.Database",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SessionCompanion.ViewModels", "SessionCompanion.ViewModels\SessionCompanion.ViewModels.csproj", "{7762AA75-7B60-4F28-B80A-B03E39140F89}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SessionCompanion.ViewModels", "SessionCompanion.ViewModels\SessionCompanion.ViewModels.csproj", "{7762AA75-7B60-4F28-B80A-B03E39140F89}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SessionCompanion.Services", "SessionCompanion.Services\SessionCompanion.Services.csproj", "{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SessionCompanion.Services", "SessionCompanion.Services\SessionCompanion.Services.csproj", "{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SessionCompanion.Extensions", "SessionCompanion.Extensions\SessionCompanion.Extensions.csproj", "{1EE35EB3-C703-407C-B390-5605A0A46884}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -33,6 +35,10 @@ Global
|
|||||||
{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C0A172ED-0F4C-4E78-8B64-28E2A756F62F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1EE35EB3-C703-407C-B390-5605A0A46884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1EE35EB3-C703-407C-B390-5605A0A46884}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1EE35EB3-C703-407C-B390-5605A0A46884}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1EE35EB3-C703-407C-B390-5605A0A46884}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SessionCompanion.ViewModels.ApiResponses;
|
||||||
|
|
||||||
|
namespace SessionCompanion.Configurations
|
||||||
|
{
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
using SessionCompanion.Extensions.ApiErrors;
|
||||||
|
|
||||||
|
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 Task HandleExceptionAsync(HttpContext context, Exception exception)
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
|
return context.Response.WriteAsync(new ErrorResponse()
|
||||||
|
{
|
||||||
|
StatusCode = context.Response.StatusCode,
|
||||||
|
Message = exception.Message
|
||||||
|
}.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace SessionCompanion.Extensions.ApiErrors
|
||||||
|
{
|
||||||
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
|
|
||||||
|
using SessionCompanion.Configurations;
|
||||||
|
|
||||||
|
public static class ExceptionMiddlewareExtensions
|
||||||
|
{
|
||||||
|
public static void ConfigureCustomExceptionMiddleware(this IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.UseMiddleware<ExceptionMiddleware>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,10 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
using SessionCompanion.Services.Interfaces;
|
using SessionCompanion.Services.Interfaces;
|
||||||
|
using SessionCompanion.ViewModels.CharacterViewModels;
|
||||||
|
|
||||||
namespace SessionCompanion.Controllers
|
namespace SessionCompanion.Controllers
|
||||||
{
|
{
|
||||||
using SessionCompanion.ViewModels.CharacterViewModels;
|
|
||||||
|
|
||||||
[Route("api/character")]
|
[Route("api/character")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class CharacterController : Controller
|
public class CharacterController : Controller
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\SessionCompanion.Database\SessionCompanion.Database.csproj" />
|
<ProjectReference Include="..\SessionCompanion.Database\SessionCompanion.Database.csproj" />
|
||||||
|
<ProjectReference Include="..\SessionCompanion.Extensions\SessionCompanion.Extensions.csproj" />
|
||||||
<ProjectReference Include="..\SessionCompanion.Services\SessionCompanion.Services.csproj" />
|
<ProjectReference Include="..\SessionCompanion.Services\SessionCompanion.Services.csproj" />
|
||||||
<ProjectReference Include="..\SessionCompanion.ViewModels\SessionCompanion.ViewModels.csproj" />
|
<ProjectReference Include="..\SessionCompanion.ViewModels\SessionCompanion.ViewModels.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -21,6 +21,8 @@ namespace SessionCompanion
|
|||||||
|
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
|
|
||||||
|
using SessionCompanion.Extensions.ApiErrors;
|
||||||
|
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -40,12 +42,14 @@ namespace SessionCompanion
|
|||||||
Configuration.GetConnectionString("DefaultConnection")));
|
Configuration.GetConnectionString("DefaultConnection")));
|
||||||
services.AddRepositories();
|
services.AddRepositories();
|
||||||
services.AddServices();
|
services.AddServices();
|
||||||
services.AddAutoMapper(typeof(Startup));
|
|
||||||
|
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
|
||||||
|
|
||||||
services.AddSignalR();
|
services.AddSignalR();
|
||||||
|
|
||||||
services.AddSwaggerGen(s =>
|
services.AddSwaggerGen(s =>
|
||||||
{
|
{
|
||||||
s.SwaggerDoc("v1", new OpenApiInfo { Title = "Dostêpne API", Version = "v1" });
|
s.SwaggerDoc("v1", new OpenApiInfo { Title = "Dost<EFBFBD>pne API", Version = "v1" });
|
||||||
var basePath = AppContext.BaseDirectory;
|
var basePath = AppContext.BaseDirectory;
|
||||||
var xmlPath = Path.Combine(basePath, "SessionCompanion.xml");
|
var xmlPath = Path.Combine(basePath, "SessionCompanion.xml");
|
||||||
s.IncludeXmlComments(xmlPath);
|
s.IncludeXmlComments(xmlPath);
|
||||||
@ -81,6 +85,8 @@ namespace SessionCompanion
|
|||||||
app.UseHsts();
|
app.UseHsts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.ConfigureCustomExceptionMiddleware();
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
if (!env.IsDevelopment())
|
if (!env.IsDevelopment())
|
||||||
|
Loading…
Reference in New Issue
Block a user