diff --git a/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs b/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs index e47a66e8..237c20b2 100644 --- a/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs +++ b/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs @@ -1,11 +1,14 @@ using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; namespace AsbCloudApp.Data.Trajectory { /// /// Базовая географическая траектория /// - public abstract class TrajectoryGeoDto : IId + public abstract class TrajectoryGeoDto : IId, IValidatableObject { /// /// ИД строки с координатами @@ -49,5 +52,11 @@ namespace AsbCloudApp.Data.Trajectory /// ИД пользователя /// public int IdUser { get; set; } + + /// + public IEnumerable Validate(ValidationContext validationContext) + { + return Enumerable.Empty(); + } } } diff --git a/AsbCloudApp/Services/IParserService.cs b/AsbCloudApp/Services/IParserService.cs index 252aee28..6fa095cd 100644 --- a/AsbCloudApp/Services/IParserService.cs +++ b/AsbCloudApp/Services/IParserService.cs @@ -33,5 +33,4 @@ public interface IParserService : IParserService /// public interface IParserService { - const string MessageTemplate = "Лист: {0}, Строка: {1}, Столбец: {2}. {3}"; } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ParserExcelService.cs b/AsbCloudInfrastructure/Services/ParserExcelService.cs new file mode 100644 index 00000000..a9a28d9e --- /dev/null +++ b/AsbCloudInfrastructure/Services/ParserExcelService.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Linq; +using AsbCloudApp.Data; +using AsbCloudApp.Requests.ParserOptions; +using AsbCloudApp.Services; +using ClosedXML.Excel; + +namespace AsbCloudInfrastructure.Services; + +public abstract class ParserExcelService : IParserService + where TDto : class, IValidatableObject, IId + where TOptions : IParserOptionsRequest +{ + protected readonly IServiceProvider serviceProvider; + + protected ParserExcelService(IServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + } + + protected abstract string SheetName { get; } + + protected abstract IDictionary PropertyColumnNumbers { get; } + + public abstract ParserResultDto Parse(Stream file, TOptions options); + + public abstract Stream GetTemplateFile(); + + protected abstract TDto ParseRow(IXLRow xlRow); + + private ValidationResultDto Validate(TDto dto, int rowNumber) + { + var validationResults = new List(); + + var isValid = dto.Validate(validationResults); + + if (isValid) + { + var validDto = new ValidationResultDto() + { + Item = dto + }; + + return validDto; + } + + var invalidDto = new ValidationResultDto + { + Item = dto, + Warnings = validationResults + .SelectMany(v => v.MemberNames + .Where(PropertyColumnNumbers.ContainsKey) + .Select(m => + { + var columnNumber = PropertyColumnNumbers[m]; + var errorMessage = v.ErrorMessage; + var warningMessage = string.Format(XLMessageTemplates.ProblemDetailsTemplate, SheetName, rowNumber, columnNumber, errorMessage); + var warning = new ValidationResult(warningMessage, new[] { m }); + return warning; + })) + }; + + return invalidDto; + } + + protected virtual ParserResultDto ParseExcelSheet(IXLWorksheet sheet, + int columnCount, + int headerRowsCount = 0) + { + if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < columnCount) + throw new FileFormatException(string.Format(XLMessageTemplates.FewerColumnsTemplate, SheetName)); + + var count = sheet.RowsUsed().Count() - headerRowsCount; + + if (count > 1024) + throw new FileFormatException(string.Format(XLMessageTemplates.ExceedingMaxRowLimitTemplate, SheetName)); + + if (count <= 0) + return new ParserResultDto(); + + var valiationResults = new List>(count); + var warnings = new List(); + + for (var i = 0; i < count; i++) + { + var row = sheet.Row(1 + i + headerRowsCount); + + try + { + var dto = ParseRow(row); + var validationResult = Validate(dto, row.RowNumber()); + valiationResults.Add(validationResult); + } + catch (FileFormatException ex) + { + var warning = new ValidationResult(ex.Message); + warnings.Add(warning); + } + } + + var parserResult = new ParserResultDto + { + Item = valiationResults + }; + + if (warnings.Any()) + parserResult.Warnings = warnings; + + return parserResult; + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ParserServiceBase.cs b/AsbCloudInfrastructure/Services/ParserServiceBase.cs deleted file mode 100644 index 8fa202af..00000000 --- a/AsbCloudInfrastructure/Services/ParserServiceBase.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.IO; -using System.Linq; -using AsbCloudApp.Data; -using AsbCloudApp.Requests.ParserOptions; -using AsbCloudApp.Services; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services; - -public abstract class ParserServiceBase : IParserService - where TDto : class, IId - where TOptions : IParserOptionsRequest -{ - protected readonly IServiceProvider serviceProvider; - - protected ParserServiceBase(IServiceProvider serviceProvider) - { - this.serviceProvider = serviceProvider; - } - - protected virtual ICollection ValidationResults { get; } = new List(); - - protected abstract string SheetName { get; } - - public abstract ParserResultDto Parse(Stream file, TOptions options); - - public abstract Stream GetTemplateFile(); - - protected virtual ValidationResultDto ValidateRow(int rowNumber, - IDictionary columnNumbers, - TDto dto) - { - var validationContext = new ValidationContext(dto, serviceProvider: null, items: null); - - if (dto is IValidatableObject dtoWithValidateMethod) - { - var validationResults = dtoWithValidateMethod.Validate(validationContext); - - foreach (var validationResult in validationResults) - ValidationResults.Add(validationResult); - } - - if (Validator.TryValidateObject(dto, validationContext, ValidationResults, true)) - { - var validRow = new ValidationResultDto - { - Item = dto - }; - - return validRow; - } - - var invalidRow = new ValidationResultDto - { - Item = dto, - }; - - var warnings = new List(); - - foreach (var validationResult in from v in ValidationResults - let memberNames = v.MemberNames.Where(columnNumbers.ContainsKey) - select memberNames.Select(x => - { - var columnNumber = columnNumbers[x]; - var errorMessage = v.ErrorMessage; - var warningMessage = string.Format(IParserService.MessageTemplate, SheetName, rowNumber, columnNumber, errorMessage); - var warning = new ValidationResult(warningMessage, new[] { x }); - return warning; - })) - { - warnings.AddRange(validationResult); - } - - invalidRow.Warnings = warnings; - - return invalidRow; - } - - protected virtual ParserResultDto ParseExcelSheet(IXLWorksheet sheet, - Func> parseRow, - int columnCount, - int headerRowsCount = 0) - { - if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < columnCount) - throw new FileFormatException($"Лист {SheetName} содержит меньшее количество столбцов."); - - var count = sheet.RowsUsed().Count() - headerRowsCount; - - if (count > 1024) - throw new FileFormatException($"Лист {SheetName} содержит слишком большое количество строк."); - - if (count <= 0) - return new ParserResultDto(); - - var dtos = new List>(count); - var warnings = new List(); - - for (var i = 0; i < count; i++) - { - var row = sheet.Row(1 + i + headerRowsCount); - - try - { - var dto = parseRow.Invoke(row); - dtos.Add(dto); - } - catch (FileFormatException ex) - { - var warning = new ValidationResult(ex.Message); - warnings.Add(warning); - } - } - - var parserResult = new ParserResultDto - { - Item = dtos - }; - - if (warnings.Any()) - parserResult.Warnings = warnings; - - return parserResult; - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanDrillingParser.cs b/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanDrillingParser.cs index cab930b4..5ad9e2ea 100644 --- a/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanDrillingParser.cs +++ b/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanDrillingParser.cs @@ -5,7 +5,6 @@ using System.Linq; using AsbCloudApp.Data; using AsbCloudApp.Data.ProcessMapPlan; using AsbCloudApp.Repositories; -using AsbCloudApp.Services; using ClosedXML.Excel; using Microsoft.Extensions.DependencyInjection; @@ -48,35 +47,39 @@ public class ProcessMapPlanDrillingParser : ProcessMapPlanParser "План"; + protected override IDictionary PropertyColumnNumbers => new Dictionary + { + { nameof(ProcessMapPlanDrillingDto.DepthStart), columnDepthStart }, + { nameof(ProcessMapPlanDrillingDto.DepthEnd), columnDepthEnd }, + { nameof(ProcessMapPlanDrillingDto.DeltaPressurePlan), columnPressurePlan }, + { nameof(ProcessMapPlanDrillingDto.DeltaPressureLimitMax), columnPressureLimitMax }, + { nameof(ProcessMapPlanDrillingDto.AxialLoadPlan), columnAxialLoadPlan }, + { nameof(ProcessMapPlanDrillingDto.AxialLoadLimitMax), columnAxialLoadLimitMax }, + { nameof(ProcessMapPlanDrillingDto.TopDriveTorquePlan), columnTopDriveTorquePlan }, + { nameof(ProcessMapPlanDrillingDto.TopDriveTorqueLimitMax), columnTopDriveTorqueLimitMax }, + { nameof(ProcessMapPlanDrillingDto.TopDriveSpeedPlan), columnTopDriveSpeedPlan }, + { nameof(ProcessMapPlanDrillingDto.TopDriveSpeedLimitMax), columnTopDriveSpeedLimitMax }, + { nameof(ProcessMapPlanDrillingDto.FlowPlan), columnFlowPlan }, + { nameof(ProcessMapPlanDrillingDto.FlowLimitMax), columnFlowLimitMax }, + { nameof(ProcessMapPlanDrillingDto.RopPlan), columnRopPlan }, + { nameof(ProcessMapPlanDrillingDto.UsageSaub), columnUsageSaub }, + { nameof(ProcessMapPlanDrillingDto.UsageSpin), columnUsageSpin }, + { nameof(ProcessMapPlanDrillingDto.Comment), columnComment } + }; + protected override string TemplateFileName => "ProcessMapPlanDrillingTemplate.xlsx"; - protected override ValidationResultDto ParseRow(IXLRow row) + protected override ProcessMapPlanDrillingDto ParseRow(IXLRow row) { var sectionCaption = row.Cell(columnSection).GetCellValue()?.Trim().ToLower(); var modeName = row.Cell(columnMode).GetCellValue()?.Trim().ToLower(); - var depthStart = row.Cell(columnDepthStart).GetCellValue(); - var depthEnd = row.Cell(columnDepthEnd).GetCellValue(); - var deltaPressurePlan = row.Cell(columnPressurePlan).GetCellValue(); - var deltaPressureLimitMax = row.Cell(columnPressureLimitMax).GetCellValue(); - var axialLoadPlan = row.Cell(columnAxialLoadPlan).GetCellValue(); - var axialLoadLimitMax = row.Cell(columnAxialLoadLimitMax).GetCellValue(); - var topDriveTorquePlan = row.Cell(columnTopDriveTorquePlan).GetCellValue(); - var topDriveTorqueLimitMax = row.Cell(columnTopDriveTorqueLimitMax).GetCellValue(); - var topDriveSpeedPlan = row.Cell(columnTopDriveSpeedPlan).GetCellValue(); - var topDriveSpeedLimitMax = row.Cell(columnTopDriveSpeedLimitMax).GetCellValue(); - var flowPlan = row.Cell(columnFlowPlan).GetCellValue(); - var flowLimitMax = row.Cell(columnFlowLimitMax).GetCellValue(); - var ropPlan = row.Cell(columnRopPlan).GetCellValue(); - var usageSaub = row.Cell(columnUsageSaub).GetCellValue(); - var usageSpin = row.Cell(columnUsageSpin).GetCellValue(); - var comment = row.Cell(columnComment).GetCellValue() ?? string.Empty; var section = sections.FirstOrDefault(s => string.Equals(s.Caption.Trim(), sectionCaption?.Trim(), StringComparison.CurrentCultureIgnoreCase)); if (section is null) { - var message = string.Format(IParserService.MessageTemplate, SheetName, row.RowNumber(), columnSection, + var message = string.Format(XLMessageTemplates.ProblemDetailsTemplate, SheetName, row.RowNumber(), columnSection, "Указана некорректная секция"); throw new FileFormatException(message); } @@ -85,7 +88,7 @@ public class ProcessMapPlanDrillingParser : ProcessMapPlanParser(), + DepthEnd = row.Cell(columnDepthEnd).GetCellValue(), + AxialLoadPlan = row.Cell(columnAxialLoadPlan).GetCellValue(), + AxialLoadLimitMax = row.Cell(columnAxialLoadLimitMax).GetCellValue(), + DeltaPressurePlan = row.Cell(columnPressurePlan).GetCellValue(), + DeltaPressureLimitMax = row.Cell(columnPressureLimitMax).GetCellValue(), + TopDriveTorquePlan = row.Cell(columnTopDriveTorquePlan).GetCellValue(), + TopDriveTorqueLimitMax = row.Cell(columnTopDriveTorqueLimitMax).GetCellValue(), + TopDriveSpeedPlan = row.Cell(columnTopDriveSpeedPlan).GetCellValue(), + TopDriveSpeedLimitMax = row.Cell(columnTopDriveSpeedLimitMax).GetCellValue(), + FlowPlan = row.Cell(columnFlowPlan).GetCellValue(), + FlowLimitMax = row.Cell(columnFlowLimitMax).GetCellValue(), + RopPlan = row.Cell(columnRopPlan).GetCellValue(), + UsageSaub = row.Cell(columnUsageSaub).GetCellValue(), + UsageSpin = row.Cell(columnUsageSpin).GetCellValue(), + Comment = row.Cell(columnComment).GetCellValue() ?? string.Empty }; - var columnNumbers = new Dictionary - { - { nameof(ProcessMapPlanDrillingDto.DepthStart), columnDepthStart }, - { nameof(ProcessMapPlanDrillingDto.DepthEnd), columnDepthEnd }, - { nameof(ProcessMapPlanDrillingDto.DeltaPressurePlan), columnPressurePlan }, - { nameof(ProcessMapPlanDrillingDto.DeltaPressureLimitMax), columnPressureLimitMax }, - { nameof(ProcessMapPlanDrillingDto.AxialLoadPlan), columnAxialLoadPlan }, - { nameof(ProcessMapPlanDrillingDto.AxialLoadLimitMax), columnAxialLoadLimitMax }, - { nameof(ProcessMapPlanDrillingDto.TopDriveTorquePlan), columnTopDriveTorquePlan }, - { nameof(ProcessMapPlanDrillingDto.TopDriveTorqueLimitMax), columnTopDriveTorqueLimitMax }, - { nameof(ProcessMapPlanDrillingDto.TopDriveSpeedPlan), columnTopDriveSpeedPlan }, - { nameof(ProcessMapPlanDrillingDto.TopDriveSpeedLimitMax), columnTopDriveSpeedLimitMax }, - { nameof(ProcessMapPlanDrillingDto.FlowPlan), columnFlowPlan }, - { nameof(ProcessMapPlanDrillingDto.FlowLimitMax), columnFlowLimitMax }, - { nameof(ProcessMapPlanDrillingDto.RopPlan), columnRopPlan }, - { nameof(ProcessMapPlanDrillingDto.UsageSaub), columnUsageSaub }, - { nameof(ProcessMapPlanDrillingDto.UsageSpin), columnUsageSpin }, - { nameof(ProcessMapPlanDrillingDto.Comment), columnComment } - }; - - return ValidateRow(row.RowNumber(), columnNumbers, dto); + return dto; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanParser.cs b/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanParser.cs index 5b7aab2d..ff76debb 100644 --- a/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanParser.cs +++ b/AsbCloudInfrastructure/Services/ProcessMapPlan/Parser/ProcessMapPlanParser.cs @@ -8,7 +8,7 @@ using ClosedXML.Excel; namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser; -public abstract class ProcessMapPlanParser : ParserServiceBase +public abstract class ProcessMapPlanParser : ParserExcelService where TDto : ProcessMapPlanBaseDto { protected ProcessMapPlanParser(IServiceProvider serviceProvider) @@ -20,16 +20,14 @@ public abstract class ProcessMapPlanParser : ParserServiceBase ParseRow(IXLRow row); - + public override ParserResultDto Parse(Stream file, IParserOptionsRequest options) { using var workbook = new XLWorkbook(file); var sheet = workbook.GetWorksheet(SheetName); - var processMaps = ParseExcelSheet(sheet, ParseRow, ColumnCount, HeaderRowsCount); + var processMaps = ParseExcelSheet(sheet, ColumnCount, HeaderRowsCount); return processMaps; } diff --git a/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryFactManualParser.cs b/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryFactManualParser.cs index ad173db7..e48fb575 100644 --- a/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryFactManualParser.cs +++ b/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryFactManualParser.cs @@ -1,5 +1,5 @@ using System; -using AsbCloudApp.Data; +using System.Collections.Generic; using AsbCloudApp.Data.Trajectory; using ClosedXML.Excel; @@ -7,33 +7,48 @@ namespace AsbCloudInfrastructure.Services.Trajectory.Parser; public class TrajectoryFactManualParser : TrajectoryParser { - protected override string SheetName => "Фактическая траектория"; - protected override string TemplateFileName => "TrajectoryFactManualTemplate.xlsx"; + #region Columns + + private const int columnWellboreDepth = 1; + private const int columnZenithAngle = 2; + private const int columnAzimuthGeo = 3; + private const int columnAzimuthMagnetic = 4; + private const int columnVerticalDepth = 5; + private const int columnComment = 6; + + #endregion public TrajectoryFactManualParser(IServiceProvider serviceProvider) : base(serviceProvider) { } - - protected override ValidationResultDto ParseRow(IXLRow row) + + protected override string SheetName => "Фактическая траектория"; + + protected override string TemplateFileName => "TrajectoryFactManualTemplate.xlsx"; + + protected override IDictionary PropertyColumnNumbers => new Dictionary { - var trajectoryRow = new TrajectoryGeoFactDto + { nameof(TrajectoryGeoFactDto.WellboreDepth), columnWellboreDepth }, + { nameof(TrajectoryGeoFactDto.ZenithAngle), columnZenithAngle }, + { nameof(TrajectoryGeoFactDto.AzimuthGeo), columnAzimuthGeo }, + { nameof(TrajectoryGeoFactDto.AzimuthMagnetic), columnAzimuthMagnetic }, + { nameof(TrajectoryGeoFactDto.VerticalDepth), columnVerticalDepth }, + { nameof(TrajectoryGeoFactDto.Comment), columnComment } + }; + + protected override TrajectoryGeoFactDto ParseRow(IXLRow row) + { + var dto = new TrajectoryGeoFactDto { - WellboreDepth = row.Cell(1).GetCellValue(), - ZenithAngle = row.Cell(2).GetCellValue(), - AzimuthGeo = row.Cell(3).GetCellValue(), - AzimuthMagnetic = row.Cell(4).GetCellValue(), - VerticalDepth = row.Cell(5).GetCellValue(), - Comment = row.Cell(6).GetCellValue() + WellboreDepth = row.Cell(columnWellboreDepth).GetCellValue(), + ZenithAngle = row.Cell(columnZenithAngle).GetCellValue(), + AzimuthGeo = row.Cell(columnAzimuthGeo).GetCellValue(), + AzimuthMagnetic = row.Cell(columnAzimuthMagnetic).GetCellValue(), + VerticalDepth = row.Cell(columnVerticalDepth).GetCellValue(), + Comment = row.Cell(columnComment).GetCellValue() }; - //TODO: Добавить валидацию модели - - var validationResult = new ValidationResultDto - { - Item = trajectoryRow - }; - - return validationResult; + return dto; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryParser.cs b/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryParser.cs index 410b1bed..c82cfc5c 100644 --- a/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryParser.cs +++ b/AsbCloudInfrastructure/Services/Trajectory/Parser/TrajectoryParser.cs @@ -8,7 +8,7 @@ using AsbCloudApp.Requests.ParserOptions; namespace AsbCloudInfrastructure.Services.Trajectory.Parser; -public abstract class TrajectoryParser : ParserServiceBase +public abstract class TrajectoryParser : ParserExcelService where T : TrajectoryGeoDto { private const int HeaderRowsCount = 2; @@ -21,8 +21,6 @@ public abstract class TrajectoryParser : ParserServiceBase ParseRow(IXLRow row); - public override Stream GetTemplateFile() => Assembly.GetExecutingAssembly().GetTemplateCopyStream(TemplateFileName) ?? throw new ArgumentNullException($"Файл '{TemplateFileName}' не найден"); @@ -33,7 +31,7 @@ public abstract class TrajectoryParser : ParserServiceBase { - protected override string SheetName => "Плановая траектория"; - protected override string TemplateFileName => "TrajectoryPlanTemplate.xlsx"; + #region Columns + + private const int columnWellboreDepth = 1; + private const int columnZenithAngle = 2; + private const int columnAzimuthGeo = 3; + private const int columnAzimuthMagnetic = 4; + private const int columnVerticalDepth = 5; + private const int columnRadius = 6; + private const int columnComment = 7; + + #endregion public TrajectoryPlanParser(IServiceProvider serviceProvider) : base(serviceProvider) { } - - protected override ValidationResultDto ParseRow(IXLRow row) + + protected override string SheetName => "Плановая траектория"; + + protected override string TemplateFileName => "TrajectoryPlanTemplate.xlsx"; + + protected override IDictionary PropertyColumnNumbers => new Dictionary { - var trajectoryRow = new TrajectoryGeoPlanDto + { nameof(TrajectoryGeoPlanDto.WellboreDepth), columnWellboreDepth }, + { nameof(TrajectoryGeoPlanDto.ZenithAngle), columnZenithAngle }, + { nameof(TrajectoryGeoPlanDto.AzimuthGeo), columnAzimuthGeo }, + { nameof(TrajectoryGeoPlanDto.AzimuthMagnetic), columnAzimuthMagnetic }, + { nameof(TrajectoryGeoPlanDto.VerticalDepth), columnVerticalDepth }, + { nameof(TrajectoryGeoPlanDto.Radius), columnRadius }, + { nameof(TrajectoryGeoPlanDto.Comment), columnComment } + }; + + protected override TrajectoryGeoPlanDto ParseRow(IXLRow row) + { + var dto = new TrajectoryGeoPlanDto { - WellboreDepth = row.Cell(1).GetCellValue(), - ZenithAngle = row.Cell(2).GetCellValue(), - AzimuthGeo = row.Cell(3).GetCellValue(), - AzimuthMagnetic = row.Cell(4).GetCellValue(), - VerticalDepth = row.Cell(5).GetCellValue(), - Radius = row.Cell(6).GetCellValue(), - Comment = row.Cell(7).GetCellValue() + WellboreDepth = row.Cell(columnWellboreDepth).GetCellValue(), + ZenithAngle = row.Cell(columnZenithAngle).GetCellValue(), + AzimuthGeo = row.Cell(columnAzimuthGeo).GetCellValue(), + AzimuthMagnetic = row.Cell(columnAzimuthMagnetic).GetCellValue(), + VerticalDepth = row.Cell(columnVerticalDepth).GetCellValue(), + Radius = row.Cell(columnRadius).GetCellValue(), + Comment = row.Cell(columnComment).GetCellValue() }; - //TODO: Добавить валидацию модели - - var validationResult = new ValidationResultDto - { - Item = trajectoryRow - }; - - return validationResult; + return dto; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/ValidationExtensions.cs b/AsbCloudInfrastructure/ValidationExtensions.cs new file mode 100644 index 00000000..feb9c06b --- /dev/null +++ b/AsbCloudInfrastructure/ValidationExtensions.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace AsbCloudInfrastructure; + +public static class ValidationExtensions +{ + public static bool Validate(this IValidatableObject validatableObject, ICollection validationResults) + { + var validationContext = new ValidationContext(validatableObject, serviceProvider: null, items: null); + + foreach (var validationResult in validatableObject.Validate(validationContext)) + validationResults.Add(validationResult); + + return Validator.TryValidateObject(validatableObject, validationContext, validationResults, true); + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/XLExtentions.cs b/AsbCloudInfrastructure/XLExtentions.cs index 8fc0220c..51545ff8 100644 --- a/AsbCloudInfrastructure/XLExtentions.cs +++ b/AsbCloudInfrastructure/XLExtentions.cs @@ -2,7 +2,6 @@ using System; using System.IO; using System.Linq; -using AsbCloudApp.Services; namespace AsbCloudInfrastructure; @@ -10,7 +9,7 @@ public static class XLExtentions { public static IXLWorksheet GetWorksheet(this IXLWorkbook workbook, string sheetName) => workbook.Worksheets.FirstOrDefault(ws => string.Equals(ws.Name.Trim(), sheetName.Trim(), StringComparison.CurrentCultureIgnoreCase)) - ?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}."); + ?? throw new FileFormatException(string.Format(XLMessageTemplates.NotFoundSheetTemplate, sheetName)); public static IXLCell SetCellValue(this IXLCell cell, T value) { @@ -40,7 +39,7 @@ public static class XLExtentions } catch { - var message = string.Format(IParserService.MessageTemplate, cell.Worksheet.Name, cell.Address.RowNumber, + var message = string.Format(XLMessageTemplates.ProblemDetailsTemplate, cell.Worksheet.Name, cell.Address.RowNumber, cell.Address.ColumnNumber, "Содержит некорректное значение"); throw new FileFormatException(message); } diff --git a/AsbCloudInfrastructure/XLMessageTemplates.cs b/AsbCloudInfrastructure/XLMessageTemplates.cs new file mode 100644 index 00000000..edb8eba9 --- /dev/null +++ b/AsbCloudInfrastructure/XLMessageTemplates.cs @@ -0,0 +1,12 @@ +namespace AsbCloudInfrastructure; + +public static class XLMessageTemplates +{ + public const string ProblemDetailsTemplate = "Лист: {0}, Строка: {1}, Столбец: {2}. {3}"; + + public const string NotFoundSheetTemplate = "Книга excel не содержит листа {0}"; + + public const string ExceedingMaxRowLimitTemplate = "Лист {0} содержит слишком большое количество строк"; + + public const string FewerColumnsTemplate = "Лист {0} содержит меньшее количество столбцов"; +} \ No newline at end of file