API
This commit is contained in:
@@ -27,6 +27,20 @@
|
||||
public const string Metrics = Base + "/metrics";
|
||||
}
|
||||
|
||||
public static class Scheduler
|
||||
{
|
||||
public const string GetAll = Base + "/schedulers/";
|
||||
|
||||
public const string GetByIp = Base + "/schedulers/ip/";
|
||||
//public const string Get = Base + "/schedulers/" + getParam;
|
||||
|
||||
//public const string GetAreas = Base + "/schedulers/" + getParam + "/areas";
|
||||
//public const string GetPlaces = Base + "/schedulers/" + getParam + "/places";
|
||||
//public const string GetTemplates = Base + "/schedulers/" + getParam + "/templates";
|
||||
|
||||
public const string getParam = "{id}";
|
||||
}
|
||||
|
||||
//public static class Layer
|
||||
//{
|
||||
// public const string GetAll = Base + "/layers/";
|
||||
@@ -37,6 +51,7 @@
|
||||
// public const string GetTemplates = Base + "/layers/" + getParam + "/templates";
|
||||
|
||||
// public const string getParam = "{id}";
|
||||
//}
|
||||
//
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
57
PARR.API/Contracts/V1/Requests/Queries/PaginationQuery.cs
Normal file
57
PARR.API/Contracts/V1/Requests/Queries/PaginationQuery.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
namespace PARR.API.Contracts.V1.Requests.Queries
|
||||
{
|
||||
public class PaginationQuery
|
||||
{
|
||||
private int pageSizeMax = 100;
|
||||
private int pageSizeDefault = 10;
|
||||
|
||||
private int pageNumberMin = 1;
|
||||
|
||||
public PaginationQuery()
|
||||
{
|
||||
PageNumber = pageNumberMin;
|
||||
PageSize = pageSizeDefault;
|
||||
}
|
||||
|
||||
public PaginationQuery(int pageNumber, int pageSize)
|
||||
{
|
||||
PageNumber = pageNumber;
|
||||
PageSize = pageSize;
|
||||
}
|
||||
|
||||
private int _pageNumber;
|
||||
public int PageNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pageNumber;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < pageNumberMin)
|
||||
_pageNumber = pageNumberMin;
|
||||
else
|
||||
_pageNumber = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int _pageSize;
|
||||
public int PageSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pageSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value > pageSizeMax)
|
||||
_pageSize = pageSizeMax;
|
||||
else
|
||||
_pageSize = value;
|
||||
|
||||
if (_pageSize < 1)
|
||||
_pageSize = pageSizeDefault;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace PARR.API.Contracts.V1.Requests.Queries
|
||||
{
|
||||
public class SchedulerGetAllQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// true - вкл задания, false - выкл задания, null - все задания
|
||||
/// </summary>
|
||||
public bool? IsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Список запланированных заданий на указанную дату
|
||||
/// </summary>
|
||||
public DateTimeOffset? StartDatePlanned { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace PARR.API.Contracts.V1.Requests.Queries
|
||||
{
|
||||
public class SchedulerGetByIpQuery
|
||||
{
|
||||
public string? Ip { get; set; }
|
||||
}
|
||||
}
|
||||
6
PARR.API/Contracts/V1/Responses/ApiHealthResponse.cs
Normal file
6
PARR.API/Contracts/V1/Responses/ApiHealthResponse.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace PARR.API.Contracts.V1.Responses
|
||||
{
|
||||
public class ApiHealthResponse
|
||||
{
|
||||
}
|
||||
}
|
||||
9
PARR.API/Contracts/V1/Responses/ApiVersionResponse.cs
Normal file
9
PARR.API/Contracts/V1/Responses/ApiVersionResponse.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace PARR.API.Contracts.V1.Responses
|
||||
{
|
||||
public class ApiVersionResponse
|
||||
{
|
||||
public string? Version { get; set; }
|
||||
|
||||
public string? Environment { get; set; }
|
||||
}
|
||||
}
|
||||
29
PARR.API/Contracts/V1/Responses/Base/BaseResponse.cs
Normal file
29
PARR.API/Contracts/V1/Responses/Base/BaseResponse.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace PARR.API.Contracts.V1.Responses.Base
|
||||
{
|
||||
public class BaseResponse
|
||||
{
|
||||
public BaseResponse() { }
|
||||
|
||||
public BaseResponse(bool isSuccess)
|
||||
{
|
||||
IsSuccess = isSuccess;
|
||||
}
|
||||
|
||||
public BaseResponse(bool isSuccess, List<ErrorModel> errors)
|
||||
{
|
||||
IsSuccess = isSuccess;
|
||||
Errors = errors;
|
||||
}
|
||||
|
||||
public BaseResponse(bool isSuccess, List<ErrorModel> errors, string message)
|
||||
{
|
||||
IsSuccess = isSuccess;
|
||||
Errors = errors;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public List<ErrorModel> Errors { get; set; } = new List<ErrorModel>();
|
||||
public bool IsSuccess { get; private set; }
|
||||
public string? Message { get; private set; }
|
||||
}
|
||||
}
|
||||
9
PARR.API/Contracts/V1/Responses/Base/ErrorModel.cs
Normal file
9
PARR.API/Contracts/V1/Responses/Base/ErrorModel.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace PARR.API.Contracts.V1.Responses.Base
|
||||
{
|
||||
public class ErrorModel
|
||||
{
|
||||
public string? FieldName { get; set; }
|
||||
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
}
|
||||
29
PARR.API/Contracts/V1/Responses/Base/PagedResponse.cs
Normal file
29
PARR.API/Contracts/V1/Responses/Base/PagedResponse.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace PARR.API.Contracts.V1.Responses.Base
|
||||
{
|
||||
public class PagedResponse<T> : BaseResponse
|
||||
{
|
||||
public PagedResponse(bool isSuccess) : base(isSuccess) { }
|
||||
|
||||
public PagedResponse(bool isSuccess, List<ErrorModel> errors) : base(isSuccess, errors) { }
|
||||
|
||||
public PagedResponse(bool isSuccess, List<ErrorModel> errors, string message) : base(isSuccess, errors, message) { }
|
||||
|
||||
|
||||
public PagedResponse(IEnumerable<T> data, bool isSuccess) : base(isSuccess) { Data = data; }
|
||||
|
||||
public PagedResponse(IEnumerable<T> data, bool isSuccess, List<ErrorModel> errors) : base(isSuccess, errors) { Data = data; }
|
||||
|
||||
public PagedResponse(IEnumerable<T> data, bool isSuccess, List<ErrorModel> errors, string message) : base(isSuccess, errors, message) { Data = data; }
|
||||
|
||||
|
||||
public IEnumerable<T>? Data { get; set; }
|
||||
|
||||
public int? PageNumber { get; set; }
|
||||
|
||||
public int? PageSize { get; set; }
|
||||
|
||||
public int? TotalPage { get; set; }
|
||||
|
||||
public int? TotalItems { get; set; }
|
||||
}
|
||||
}
|
||||
57
PARR.API/Contracts/V1/Responses/Base/Response.cs
Normal file
57
PARR.API/Contracts/V1/Responses/Base/Response.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using FluentValidation.Results;
|
||||
|
||||
namespace PARR.API.Contracts.V1.Responses.Base
|
||||
{
|
||||
public class Response<T> : BaseResponse
|
||||
{
|
||||
public Response(T response, bool isSuccess) : base(isSuccess)
|
||||
{
|
||||
Data = response;
|
||||
}
|
||||
|
||||
public Response(T response, bool isSuccess, List<ErrorModel> errors) : base(isSuccess, errors)
|
||||
{
|
||||
Data = response;
|
||||
}
|
||||
|
||||
public Response(T response, bool isSuccess, List<ErrorModel> errors, string message) : base(isSuccess, errors, message)
|
||||
{
|
||||
Data = response;
|
||||
}
|
||||
|
||||
public T? Data { get; private set; }
|
||||
}
|
||||
|
||||
|
||||
public class Response : Response<object?>
|
||||
{
|
||||
/// <summary>
|
||||
/// Респонс для валидации от FluentValidator
|
||||
/// </summary>
|
||||
/// <param name="validationErrors">ResultValidate.Errors</param>
|
||||
public Response(List<ValidationFailure> validationErrors) : base(null, false)
|
||||
{
|
||||
var errors = new List<ErrorModel>();
|
||||
foreach (var error in validationErrors)
|
||||
{
|
||||
errors.Add(new ErrorModel
|
||||
{
|
||||
FieldName = error.PropertyName,
|
||||
Message = error.ErrorMessage
|
||||
});
|
||||
}
|
||||
|
||||
Errors = errors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Респонс когда не нужно передавать объект
|
||||
/// </summary>
|
||||
/// <param name="isSuccess"></param>
|
||||
/// <param name="errors"></param>
|
||||
public Response(bool isSuccess, List<ErrorModel> errors) : base(null, isSuccess, errors)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
21
PARR.API/Contracts/V1/Responses/SchedulerResponse.cs
Normal file
21
PARR.API/Contracts/V1/Responses/SchedulerResponse.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace PARR.API.Contracts.V1.Responses
|
||||
{
|
||||
public class SchedulerBaseResponse
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public DateTimeOffset StartAt { get; set; }
|
||||
public int FrequencyMinute { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class SchedulerGetAllResponse: SchedulerBaseResponse
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
}
|
||||
|
||||
public class SchedulerResponse
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,49 @@
|
||||
using PARR.API.Controllers.V1.Base;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PARR.API.Contracts.V1;
|
||||
using PARR.API.Contracts.V1.Responses;
|
||||
using PARR.API.Contracts.V1.Responses.Base;
|
||||
using PARR.API.Controllers.V1.Base;
|
||||
using System.Reflection;
|
||||
|
||||
namespace PARR.API.Controllers.V1
|
||||
{
|
||||
public class ApiStatusController : BaseApiController
|
||||
{
|
||||
//TODO:
|
||||
/// <summary>
|
||||
/// Получить версию и окружение
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpGet(ApiRoutes.ApiStatus.Version)]
|
||||
public IActionResult GetVersion()
|
||||
{
|
||||
var version = Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
|
||||
|
||||
var response = new ApiVersionResponse
|
||||
{
|
||||
Environment = environment,
|
||||
Version = version
|
||||
};
|
||||
|
||||
return Ok(new Response<ApiVersionResponse>(response, true));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Проверка доступности системы
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpGet(ApiRoutes.ApiStatus.Health)]
|
||||
public IActionResult GetHealth()
|
||||
{
|
||||
//Так же можно реализовать проверку связи с БД
|
||||
//Проверка доступности хранилищ
|
||||
var response = new ApiHealthResponse { };
|
||||
|
||||
return Ok(new Response<ApiHealthResponse>(response, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
|
||||
namespace PARR.API.Controllers.V1
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly IHostService hostService;
|
||||
|
||||
public HomeController(IHostService hostService)
|
||||
{
|
||||
this.hostService = hostService;
|
||||
}
|
||||
|
||||
[HttpGet("test")]
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
var hosts = await hostService.Get().ToListAsync();
|
||||
//foreach (var host in hosts) { logger.LogInformation($"{host.HostName}"); }
|
||||
//return View();
|
||||
|
||||
return Ok(hosts.Select(t => new { t.HostName, t.IP, t.Id }));
|
||||
}
|
||||
}
|
||||
}
|
||||
78
PARR.API/Controllers/V1/ShchedullerController.cs
Normal file
78
PARR.API/Controllers/V1/ShchedullerController.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PARR.API.Contracts.V1.Requests.Queries;
|
||||
using PARR.API.Contracts.V1;
|
||||
using PARR.API.Controllers.V1.Base;
|
||||
using AutoMapper;
|
||||
using PARR.DAL.DomainModels;
|
||||
using PARR.DAL.Models;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PARR.API.Contracts.V1.Responses;
|
||||
using PARR.API.Contracts.V1.Responses.Base;
|
||||
using PARR.API.Extensions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using PARR.API.Services.Interfaces;
|
||||
|
||||
namespace PARR.API.Controllers.V1
|
||||
{
|
||||
public class ShchedullerController : BaseApiController
|
||||
{
|
||||
private readonly IMapper mapper;
|
||||
private readonly ISchedulerService schedulerService;
|
||||
private readonly IClientService clientService;
|
||||
|
||||
public ShchedullerController(
|
||||
IMapper mapper,
|
||||
ISchedulerService schedulerService,
|
||||
IClientService clientService
|
||||
)
|
||||
{
|
||||
this.mapper = mapper;
|
||||
this.schedulerService = schedulerService;
|
||||
this.clientService = clientService;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Список всех планировщиков постранично в соотвествии с фильтрами
|
||||
/// </summary>
|
||||
/// <param name="paginationQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.Scheduler.GetAll)]
|
||||
public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] SchedulerGetAllQuery filter)
|
||||
{
|
||||
var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery);
|
||||
IQueryable<Scheduler> query = schedulerService.Get().OrderBy(s => s.StartAt);
|
||||
|
||||
if (filter.IsEnabled.HasValue)
|
||||
query = query.Where(t => t.IsEnabled == filter.IsEnabled);
|
||||
|
||||
if (filter.StartDatePlanned.HasValue)
|
||||
query = query.Where(t => t.StartAt.DateTime.Date <= filter.StartDatePlanned.Value.DateTime.Date); ;
|
||||
|
||||
var schedulers = await schedulerService.GetPage(query, paginationFilter).ToListAsync();
|
||||
|
||||
if (!schedulers.Any())
|
||||
return NoContent();
|
||||
|
||||
var schedulerResponse = mapper.Map<List<SchedulerGetAllResponse>>(schedulers);
|
||||
var paginationResponse = new PagedResponse<SchedulerGetAllResponse>(schedulerResponse, true).GetPaginatedProps(paginationFilter, query);
|
||||
|
||||
return Ok(paginationResponse);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet(ApiRoutes.Scheduler.GetByIp)]
|
||||
public async Task<IActionResult> GetByClientIP([FromQuery] SchedulerGetByIpQuery requestQuery)
|
||||
{
|
||||
var ip = requestQuery.Ip ?? clientService.GetClientIp()?.ToString();
|
||||
if (string.IsNullOrEmpty(ip))
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Client IP address is null." } }));
|
||||
|
||||
// TODO;
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
59
PARR.API/Extensions/PaginationExtensions.cs
Normal file
59
PARR.API/Extensions/PaginationExtensions.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using PARR.API.Contracts.V1.Responses.Base;
|
||||
using PARR.DAL.DomainModels;
|
||||
|
||||
namespace PARR.API.Extensions
|
||||
{
|
||||
public static class PaginationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Заполняет TotalItems, PageNumber, PageSize, TotalPage
|
||||
/// </summary>
|
||||
/// <typeparam name="TypeResponse"></typeparam>
|
||||
/// <typeparam name="Query"></typeparam>
|
||||
/// <param name="pagedResponse"></param>
|
||||
/// <param name="paginationFilter"></param>
|
||||
/// <param name="quaryAllItemsApplyFilters"></param>
|
||||
/// <returns></returns>
|
||||
public static PagedResponse<TypeResponse> GetPaginatedProps<TypeResponse, Query>(
|
||||
this PagedResponse<TypeResponse> pagedResponse,
|
||||
PaginationFilter paginationFilter,
|
||||
IQueryable<Query> quaryAllItemsApplyFilters
|
||||
)
|
||||
{
|
||||
// TODO: CountAsync - подумать и затолкать в Task
|
||||
int totalItems = quaryAllItemsApplyFilters.Count();//.CountAsync().GetAwaiter().GetResult();
|
||||
return CreatePaginatedResponse(totalItems, paginationFilter, pagedResponse);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Заполняет TotalItems, PageNumber, PageSize, TotalPage
|
||||
/// </summary>
|
||||
/// <typeparam name="TypeResponse"></typeparam>
|
||||
/// <param name="pagedResponse"></param>
|
||||
/// <param name="paginationFilter"></param>
|
||||
/// <param name="totalItems"></param>
|
||||
/// <returns></returns>
|
||||
public static PagedResponse<TypeResponse> GetPaginatedProps<TypeResponse>(
|
||||
this PagedResponse<TypeResponse> pagedResponse,
|
||||
PaginationFilter paginationFilter,
|
||||
int totalItems
|
||||
)
|
||||
{
|
||||
return CreatePaginatedResponse(totalItems, paginationFilter, pagedResponse);
|
||||
}
|
||||
|
||||
private static PagedResponse<T> CreatePaginatedResponse<T>(int totalItems, PaginationFilter paginationFilter, PagedResponse<T> pagedResponse)
|
||||
{
|
||||
pagedResponse.TotalItems = totalItems;
|
||||
pagedResponse.PageNumber = paginationFilter.PageNumber >= 1 ? paginationFilter.PageNumber : (int?)null;
|
||||
pagedResponse.PageSize = paginationFilter.PageSize >= 1 ? paginationFilter.PageSize : (int?)null;
|
||||
pagedResponse.TotalPage =
|
||||
(pagedResponse.TotalItems.HasValue && pagedResponse.PageSize.HasValue)
|
||||
? (int)Math.Ceiling(pagedResponse.TotalItems.Value / (double)pagedResponse.PageSize.Value)
|
||||
: (int?)null;
|
||||
|
||||
return pagedResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ namespace PARR.API.Installers
|
||||
return new UriService(absoluteUri);
|
||||
});
|
||||
|
||||
|
||||
services.AddTransient<IClientService, ClientService>();
|
||||
//services.AddTransient<IFileService, FileService>();
|
||||
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@ namespace PARR.API.Installers
|
||||
"v1",
|
||||
new OpenApiInfo
|
||||
{
|
||||
Title = "GEO API",
|
||||
Title = "PARR API",
|
||||
Version = $"v{version}",
|
||||
Description = "API for the project \"GEO DVGD\"",
|
||||
Description = "API for the project \"PARR DVGD\"",
|
||||
Contact = new OpenApiContact { Email = "IVC_TrubnikovME@dvgd.rzd;IVC_KuznetsovMV@dvgd.rzd", Name = "Trubnikov M.E., Kuznetsov M.V." },
|
||||
License = new OpenApiLicense { Name = "© PTK-DVGD Software LLC" }
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using AutoMapper;
|
||||
using PARR.API.Contracts.V1.Responses;
|
||||
using PARR.DAL.Models;
|
||||
|
||||
namespace PARR.API.MappingProfiles
|
||||
{
|
||||
@@ -6,7 +8,11 @@ namespace PARR.API.MappingProfiles
|
||||
{
|
||||
public DomainToResponseProfile()
|
||||
{
|
||||
// из проекта наружу
|
||||
// --- Scheduler ---
|
||||
CreateMap<Scheduler, SchedulerBaseResponse>()
|
||||
.Include<Scheduler, SchedulerGetAllResponse>()
|
||||
.ForMember(d => d.FrequencyMinute, o => o.MapFrom(s => s.Frequency));
|
||||
CreateMap<Scheduler, SchedulerGetAllResponse>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using AutoMapper;
|
||||
using PARR.API.Contracts.V1.Requests.Queries;
|
||||
using PARR.DAL.DomainModels;
|
||||
|
||||
namespace PARR.API.MappingProfiles
|
||||
{
|
||||
@@ -6,7 +8,7 @@ namespace PARR.API.MappingProfiles
|
||||
{
|
||||
public RequestToDomainProfile()
|
||||
{
|
||||
// снаружи в проект
|
||||
CreateMap<PaginationQuery, PaginationFilter>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Contracts\V1\Requests\Queries\" />
|
||||
<Folder Include="Contracts\V1\Responses\" />
|
||||
<Folder Include="MappingProfiles\Resolvers\" />
|
||||
<Folder Include="Validators\" />
|
||||
</ItemGroup>
|
||||
|
||||
19
PARR.API/Services/Implementations/ClientService.cs
Normal file
19
PARR.API/Services/Implementations/ClientService.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using PARR.API.Services.Interfaces;
|
||||
using System.Net;
|
||||
|
||||
namespace PARR.API.Services.Implementations
|
||||
{
|
||||
public class ClientService : IClientService
|
||||
{
|
||||
private readonly IHttpContextAccessor httpContextAccessor;
|
||||
|
||||
public ClientService(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this.httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
public IPAddress? GetClientIp()
|
||||
{
|
||||
return httpContextAccessor.HttpContext?.Connection.RemoteIpAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
PARR.API/Services/Interfaces/IClientService.cs
Normal file
9
PARR.API/Services/Interfaces/IClientService.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Net;
|
||||
|
||||
namespace PARR.API.Services.Interfaces
|
||||
{
|
||||
public interface IClientService
|
||||
{
|
||||
IPAddress? GetClientIp();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user