forked from ddrilling/AsbCloudServer
Merge pull request '#24509912 - Валидация даты начала операции перед вставкой, удалением, импортом...' (#204) from fix/24509912-wellOperations-date-difference into dev
Reviewed-on: http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer/pulls/204
This commit is contained in:
commit
148e111b6a
@ -2,6 +2,7 @@
|
|||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -114,5 +115,20 @@ namespace AsbCloudApp.Repositories
|
|||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
|
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Валидация данных
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wellOperations"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperations);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Валидация данных (проверка с базой)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wellOperations"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<ValidationResult>> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperations, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -22,6 +23,8 @@ namespace AsbCloudInfrastructure.Repository;
|
|||||||
public class WellOperationRepository : IWellOperationRepository
|
public class WellOperationRepository : IWellOperationRepository
|
||||||
{
|
{
|
||||||
private const string KeyCacheSections = "OperationsBySectionSummarties";
|
private const string KeyCacheSections = "OperationsBySectionSummarties";
|
||||||
|
private const int Gap = 90;
|
||||||
|
|
||||||
private readonly IAsbCloudDbContext db;
|
private readonly IAsbCloudDbContext db;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
@ -311,7 +314,8 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
{
|
{
|
||||||
dtos = dtos
|
dtos = dtos
|
||||||
.GroupBy(o => o.IdParent!)
|
.GroupBy(o => o.IdParent!)
|
||||||
.Select(g => {
|
.Select(g =>
|
||||||
|
{
|
||||||
var idCategory = g.Key ?? int.MinValue;
|
var idCategory = g.Key ?? int.MinValue;
|
||||||
var category = parentRelationDictionary.GetValueOrDefault(idCategory);
|
var category = parentRelationDictionary.GetValueOrDefault(idCategory);
|
||||||
var newDto = new WellGroupOpertionDto
|
var newDto = new WellGroupOpertionDto
|
||||||
@ -330,6 +334,66 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ValidationResult>> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
var firstOperation = wellOperationDtos
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (firstOperation is null)
|
||||||
|
return Enumerable.Empty<ValidationResult>();
|
||||||
|
|
||||||
|
var request = new WellOperationRequest()
|
||||||
|
{
|
||||||
|
IdWell = firstOperation.IdWell,
|
||||||
|
OperationType = firstOperation.IdType,
|
||||||
|
};
|
||||||
|
|
||||||
|
var entities = await BuildQuery(request)
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
var wellOperationsUnion = entities.Union(wellOperationDtos).OrderBy(o => o.DateStart);
|
||||||
|
|
||||||
|
var results = Validate(wellOperationsUnion);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperationDtos)
|
||||||
|
{
|
||||||
|
var enumerator = wellOperationDtos.OrderBy(o => o.DateStart)
|
||||||
|
.GetEnumerator();
|
||||||
|
|
||||||
|
if (!enumerator.MoveNext())
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
var previous = enumerator.Current;
|
||||||
|
|
||||||
|
while(enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
var current = enumerator.Current;
|
||||||
|
var previousDateStart = previous.DateStart.ToUniversalTime();
|
||||||
|
var currentDateStart = current.DateStart.ToUniversalTime();
|
||||||
|
|
||||||
|
var previousDateEnd = previous.DateStart.AddHours(previous.DurationHours).ToUniversalTime();
|
||||||
|
|
||||||
|
if (previousDateStart.AddDays(Gap) < currentDateStart)
|
||||||
|
{
|
||||||
|
yield return new ValidationResult(
|
||||||
|
"Разница дат между операциями не должна превышать 90 дней",
|
||||||
|
new[] { nameof(wellOperationDtos) });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousDateEnd > currentDateStart)
|
||||||
|
{
|
||||||
|
yield return new ValidationResult(
|
||||||
|
"Предыдущая операция не завершена",
|
||||||
|
new[] { nameof(wellOperationDtos) });
|
||||||
|
}
|
||||||
|
|
||||||
|
previous = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<int> InsertRangeAsync(
|
public async Task<int> InsertRangeAsync(
|
||||||
IEnumerable<WellOperationDto> wellOperationDtos,
|
IEnumerable<WellOperationDto> wellOperationDtos,
|
||||||
|
@ -6,7 +6,7 @@ namespace AsbCloudWebApi.IntegrationTests;
|
|||||||
|
|
||||||
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>
|
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>
|
||||||
{
|
{
|
||||||
private readonly IServiceScope scope;
|
protected readonly IServiceScope scope;
|
||||||
|
|
||||||
protected readonly IAsbCloudDbContext dbContext;
|
protected readonly IAsbCloudDbContext dbContext;
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
using AsbCloudApp.Data;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Refit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.IntegrationTests.Clients;
|
||||||
|
|
||||||
|
public interface IWellOperationClient
|
||||||
|
{
|
||||||
|
private const string BaseRoute = "/api/well/{idWell}/wellOperations";
|
||||||
|
|
||||||
|
[Post(BaseRoute + "/{idType}/{deleteBeforeInsert}")]
|
||||||
|
Task<IApiResponse<int>> InsertRangeAsync(int idWell, int idType, bool deleteBeforeInsert, [Body] IEnumerable<WellOperationDto> dtos);
|
||||||
|
|
||||||
|
[Put(BaseRoute + "/{idOperation}")]
|
||||||
|
Task<IApiResponse<int>> UpdateAsync(int idWell, int idOperation, [FromBody] WellOperationDto value, CancellationToken token);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||||
|
using System.Net;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
||||||
|
|
||||||
|
|
||||||
|
public class WellOperationControllerTest : BaseIntegrationTest
|
||||||
|
{
|
||||||
|
private static int idWell = 1;
|
||||||
|
|
||||||
|
private readonly WellOperationDto[] dtos = new WellOperationDto[]
|
||||||
|
{
|
||||||
|
new WellOperationDto()
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
IdWell = idWell,
|
||||||
|
IdType = 1,
|
||||||
|
DateStart = DateTimeOffset.Now,
|
||||||
|
CategoryInfo = "1",
|
||||||
|
CategoryName = "1",
|
||||||
|
Comment = "1",
|
||||||
|
Day = 1,
|
||||||
|
DepthEnd = 20,
|
||||||
|
DepthStart = 10,
|
||||||
|
DurationHours = 1,
|
||||||
|
IdCategory = 5000,
|
||||||
|
IdParentCategory = null,
|
||||||
|
IdPlan = null,
|
||||||
|
IdUser = 1,
|
||||||
|
IdWellSectionType = 1,
|
||||||
|
LastUpdateDate = DateTimeOffset.Now,
|
||||||
|
NptHours = 1,
|
||||||
|
WellSectionTypeName = null,
|
||||||
|
UserName = null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly WellOperationDto[] dtosWithError = new WellOperationDto[]
|
||||||
|
{
|
||||||
|
new WellOperationDto()
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
IdWell = idWell,
|
||||||
|
IdType = 1,
|
||||||
|
DateStart = DateTimeOffset.Now,
|
||||||
|
CategoryInfo = "1",
|
||||||
|
CategoryName = "1",
|
||||||
|
Comment = "1",
|
||||||
|
Day = 1,
|
||||||
|
DepthEnd = 20,
|
||||||
|
DepthStart = 10,
|
||||||
|
DurationHours = 1,
|
||||||
|
IdCategory = 5000,
|
||||||
|
IdParentCategory = null,
|
||||||
|
IdPlan = null,
|
||||||
|
IdUser = 1,
|
||||||
|
IdWellSectionType = 1,
|
||||||
|
LastUpdateDate = DateTimeOffset.Now,
|
||||||
|
NptHours = 1,
|
||||||
|
WellSectionTypeName = null,
|
||||||
|
UserName = null
|
||||||
|
},
|
||||||
|
new WellOperationDto()
|
||||||
|
{
|
||||||
|
Id = 4,
|
||||||
|
IdWell = idWell,
|
||||||
|
IdType = 1,
|
||||||
|
DateStart = DateTimeOffset.Now.AddDays(1000),
|
||||||
|
CategoryInfo = "1",
|
||||||
|
CategoryName = "1",
|
||||||
|
Comment = "1",
|
||||||
|
Day = 1,
|
||||||
|
DepthEnd = 20,
|
||||||
|
DepthStart = 10,
|
||||||
|
DurationHours = 1,
|
||||||
|
IdCategory = 5000,
|
||||||
|
IdParentCategory = null,
|
||||||
|
IdPlan = null,
|
||||||
|
IdUser = 1,
|
||||||
|
IdWellSectionType = 1,
|
||||||
|
LastUpdateDate = DateTimeOffset.Now,
|
||||||
|
NptHours = 1,
|
||||||
|
WellSectionTypeName = null,
|
||||||
|
UserName = null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private IWellOperationClient wellOperationClient;
|
||||||
|
|
||||||
|
public WellOperationControllerTest(WebAppFactoryFixture factory)
|
||||||
|
: base(factory)
|
||||||
|
{
|
||||||
|
wellOperationClient = factory.GetAuthorizedHttpClient<IWellOperationClient>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Успешное добавление операций (без предварительной очистки данных)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Fact]
|
||||||
|
public async Task InsertRange_returns_success()
|
||||||
|
{
|
||||||
|
dbContext.CleanupDbSet<WellOperation>();
|
||||||
|
//act
|
||||||
|
var response = await wellOperationClient.InsertRangeAsync(idWell, 1, false, dtos);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Неуспешное добавление операций (без предварительной очистки данных)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Fact]
|
||||||
|
public async Task InsertRange_returns_error()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var response = await wellOperationClient.InsertRangeAsync(idWell, 1, false, dtosWithError);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Успешное добавление операций (с предварительной очисткой данных)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Fact]
|
||||||
|
public async Task InsertRangeWithDeleteBefore_returns_success()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var response = await wellOperationClient.InsertRangeAsync(idWell, 1, true, dtos);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Неуспешное добавление операций (с предварительной очисткой данных)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Fact]
|
||||||
|
public async Task InsertRangeWithDeleteBefore_returns_error()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var response = await wellOperationClient.InsertRangeAsync(idWell, 1, true, dtosWithError);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Успешное обновление операции
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Fact]
|
||||||
|
public async Task UpdateAsync_returns_success()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var dto = dtos.FirstOrDefault()!;
|
||||||
|
var response = await wellOperationClient.UpdateAsync(idWell, 1, dto, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Неуспешное обновление операции
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Fact]
|
||||||
|
public async Task UpdateAsync_returns_error()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var dto = dtosWithError.LastOrDefault()!;
|
||||||
|
var response = await wellOperationClient.UpdateAsync(idWell, 1, dto, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,27 @@ namespace AsbCloudWebApi.IntegrationTests.Data
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static WellOperation[] WellOperations = new WellOperation[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
IdWell = 1,
|
||||||
|
IdType = 1,
|
||||||
|
DateStart = DateTimeOffset.UtcNow.AddDays(-1),
|
||||||
|
CategoryInfo = "1",
|
||||||
|
Comment = "1",
|
||||||
|
DepthEnd = 20,
|
||||||
|
DepthStart = 10,
|
||||||
|
DurationHours = 1,
|
||||||
|
IdCategory = 5000,
|
||||||
|
IdPlan = null,
|
||||||
|
IdUser = 1,
|
||||||
|
IdWellSectionType = 1,
|
||||||
|
LastUpdateDate = DateTimeOffset.UtcNow
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static Deposit[] Deposits = new Deposit[] {
|
public static Deposit[] Deposits = new Deposit[] {
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,8 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>,
|
|||||||
dbContext.AddRange(Data.Defaults.RelationsCompanyWell);
|
dbContext.AddRange(Data.Defaults.RelationsCompanyWell);
|
||||||
dbContext.AddRange(Data.Defaults.Telemetries);
|
dbContext.AddRange(Data.Defaults.Telemetries);
|
||||||
dbContext.AddRange(Data.Defaults.Drillers);
|
dbContext.AddRange(Data.Defaults.Drillers);
|
||||||
await dbContext.SaveChangesAsync();
|
dbContext.AddRange(Data.Defaults.WellOperations);
|
||||||
|
await dbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public new async Task DisposeAsync()
|
public new async Task DisposeAsync()
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.WellOperationImport;
|
||||||
|
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.WellOperationImport;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -12,12 +18,6 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data.WellOperationImport;
|
|
||||||
using AsbCloudApp.Services.WellOperationImport;
|
|
||||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudInfrastructure;
|
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers
|
namespace AsbCloudWebApi.Controllers
|
||||||
{
|
{
|
||||||
@ -237,6 +237,10 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
wellOperation.IdUser = User.GetUserId();
|
wellOperation.IdUser = User.GetUserId();
|
||||||
wellOperation.IdType = idType;
|
wellOperation.IdType = idType;
|
||||||
|
|
||||||
|
var validationResult = await operationRepository.ValidateWithDbAsync(new[] { wellOperation }, cancellationToken);
|
||||||
|
if (validationResult.Any())
|
||||||
|
return this.ValidationBadRequest(validationResult);
|
||||||
|
|
||||||
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@ -287,11 +291,32 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
wellOperation.IdType = idType;
|
wellOperation.IdType = idType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var validationResult = await Validate(wellOperations, deleteBeforeInsert, cancellationToken);
|
||||||
|
if (validationResult.Any())
|
||||||
|
return this.ValidationBadRequest(validationResult);
|
||||||
|
|
||||||
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Валидация данных перед вставкой / обновлением / импортом
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wellOperations"></param>
|
||||||
|
/// <param name="deleteBeforeInsert"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task<IEnumerable<ValidationResult>> Validate(IEnumerable<WellOperationDto> wellOperations, bool deleteBeforeInsert, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (deleteBeforeInsert)
|
||||||
|
return operationRepository.Validate(wellOperations);
|
||||||
|
else
|
||||||
|
return await operationRepository.ValidateWithDbAsync(wellOperations, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Обновляет выбранную операцию на скважине
|
/// Обновляет выбранную операцию на скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -317,6 +342,10 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||||
value.IdUser = User.GetUserId();
|
value.IdUser = User.GetUserId();
|
||||||
|
|
||||||
|
var validationResult = await operationRepository.ValidateWithDbAsync(new[] { value }, token);
|
||||||
|
if (validationResult.Any())
|
||||||
|
return this.ValidationBadRequest(validationResult);
|
||||||
|
|
||||||
var result = await operationRepository.UpdateAsync(value, token)
|
var result = await operationRepository.UpdateAsync(value, token)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
|
@ -3,6 +3,8 @@ using AsbCloudWebApi.Converters;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc
|
namespace Microsoft.AspNetCore.Mvc
|
||||||
@ -53,6 +55,27 @@ namespace Microsoft.AspNetCore.Mvc
|
|||||||
return controller.BadRequest(problem);
|
return controller.BadRequest(problem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// Returns BadRequest with ValidationProblemDetails as body
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Используйте этот метод только если валидацию нельзя сделать через
|
||||||
|
/// атрибуты валидации или IValidatableObject модели.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="controller"></param>
|
||||||
|
/// <param name="validationResults"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static BadRequestObjectResult ValidationBadRequest(this ControllerBase controller, IEnumerable<ValidationResult> validationResults)
|
||||||
|
{
|
||||||
|
var errors = validationResults
|
||||||
|
.SelectMany(e => e.MemberNames.Select(name=> new { name, e.ErrorMessage }))
|
||||||
|
.ToDictionary(e => e.name, e => new[] { e.ErrorMessage ?? string.Empty });
|
||||||
|
var problem = new ValidationProblemDetails(errors);
|
||||||
|
return controller.BadRequest(problem);
|
||||||
|
}
|
||||||
|
|
||||||
public static MvcOptions UseDateOnlyTimeOnlyStringConverters(this MvcOptions options)
|
public static MvcOptions UseDateOnlyTimeOnlyStringConverters(this MvcOptions options)
|
||||||
{
|
{
|
||||||
TypeDescriptor.AddAttributes(typeof(DateOnly), new TypeConverterAttribute(typeof(DateOnlyTypeConverter)));
|
TypeDescriptor.AddAttributes(typeof(DateOnly), new TypeConverterAttribute(typeof(DateOnlyTypeConverter)));
|
||||||
|
Loading…
Reference in New Issue
Block a user