Skip to content

Commit 086fe44

Browse files
committed
1. add row data validator
2. rename ValueValidator* to CellValueValidator* 3. correct typos
1 parent f297ad9 commit 086fe44

File tree

4 files changed

+82
-13
lines changed

4 files changed

+82
-13
lines changed

src/Excel.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ public static class Excel
138138

139139
var value = row.GetCellValue(index, _formulaEvaluator);
140140

141-
// give a chance to the value validator
142-
if (config?.ValueValidator != null)
141+
// give a chance to the cell value validator
142+
if (null != config?.CellValueValidator)
143143
{
144-
var validationResult = config.ValueValidator(row.RowNum - 1, config.Index, value);
144+
var validationResult = config.CellValueValidator(row.RowNum - 1, config.Index, value);
145145
if (false == validationResult)
146146
{
147147
if (fluentConfig.SkipInvalidRows)
@@ -189,6 +189,22 @@ public static class Excel
189189

190190
if (itemIsValid)
191191
{
192+
// give a chance to the row data validator
193+
if (null != fluentConfig?.RowDataValidator)
194+
{
195+
var validationResult = fluentConfig.RowDataValidator(row.RowNum - 1, item);
196+
if (false == validationResult)
197+
{
198+
if (fluentConfig.SkipInvalidRows)
199+
{
200+
itemIsValid = false;
201+
continue;
202+
}
203+
204+
throw new ArgumentException($"Validation of row data at row {row.RowNum} failed!");
205+
}
206+
}
207+
192208
list.Add(item);
193209
}
194210
}

src/FluentConfiguration/FluentConfiguration.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@ namespace FluentExcel
1414
/// <typeparam name="TModel">The type of model.</typeparam>
1515
public class FluentConfiguration<TModel> : IFluentConfiguration where TModel : class
1616
{
17+
/// <summary>
18+
/// Typed row data validator delegate, validate current row before adding it to the result list.
19+
/// </summary>
20+
/// <param name="rowIndex">Index of current row in excel</param>
21+
/// <param name="rowData">Model data of current row</param>
22+
/// <returns>Whether the row data passes validation</returns>
23+
public delegate bool RowDataValidatorTypedDelegate(int rowIndex, TModel rowData);
24+
1725
private Dictionary<string, PropertyConfiguration> _propertyConfigurations;
1826
private List<StatisticsConfiguration> _statisticsConfigurations;
1927
private List<FilterConfiguration> _filterConfigurations;
2028
private List<FreezeConfiguration> _freezeConfigurations;
29+
private RowDataValidatorDelegate _rowDataValidator;
2130
private bool _skipInvalidRows;
2231

2332
/// <summary>
@@ -79,6 +88,12 @@ public IReadOnlyList<FreezeConfiguration> FreezeConfigurations
7988
}
8089
}
8190

91+
/// <summary>
92+
/// Gets the row data validator.
93+
/// </summary>
94+
/// <value>The row data validator.</value>
95+
public RowDataValidatorDelegate RowDataValidator { get { return _rowDataValidator; } }
96+
8297
/// <summary>
8398
/// Gets the value indicating whether to skip the rows with validation failure while loading the excel data.
8499
/// </summary>
@@ -261,6 +276,30 @@ public FluentConfiguration<TModel> HasFreeze(int columnSplit, int rowSplit, int
261276
return this;
262277
}
263278

279+
/// <summary>
280+
/// Configures the row data validator which validates each row before adding it to the result list.
281+
/// </summary>
282+
/// <returns>The <see cref="FluentConfiguration{TModel}"/>.</returns>
283+
/// <param name="rowDataValidator">The row data validator</param>
284+
public FluentConfiguration<TModel> HasRowDataValidator(RowDataValidatorTypedDelegate rowDataValidator)
285+
{
286+
if (null == rowDataValidator)
287+
{
288+
_rowDataValidator = null;
289+
return this;
290+
}
291+
292+
_rowDataValidator = (rowIndex, rowData) =>
293+
{
294+
var model = rowData as TModel;
295+
if (null == model && null != rowData) throw new ArgumentException($"the row data is not of type {typeof(TModel).Name}", nameof(rowData));
296+
297+
return rowDataValidator(rowIndex, model);
298+
};
299+
300+
return this;
301+
}
302+
264303
/// <summary>
265304
/// Configure whether to skip the rows with validation failure while loading the excel data.
266305
/// </summary>

src/FluentConfiguration/IFluentConfiguration.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ namespace FluentExcel
44
{
55
using System.Collections.Generic;
66

7+
/// <summary>
8+
/// Row data validator delegate, validate current row before adding it to the result list.
9+
/// </summary>
10+
/// <param name="rowIndex">Index of current row in excel</param>
11+
/// <param name="rowData">Model data of current row</param>
12+
/// <returns>Whether the row data passes validation</returns>
13+
public delegate bool RowDataValidatorDelegate(int rowIndex, object rowData);
14+
715
/// <summary>
816
/// Provides the interfaces for the fluent configuration.
917
/// </summary>
@@ -33,6 +41,12 @@ public interface IFluentConfiguration
3341
/// <value>The freeze config.</value>
3442
IReadOnlyList<FreezeConfiguration> FreezeConfigurations { get; }
3543

44+
/// <summary>
45+
/// Gets the row data validator.
46+
/// </summary>
47+
/// <value>The row data validator.</value>
48+
RowDataValidatorDelegate RowDataValidator { get; }
49+
3650
/// <summary>
3751
/// Gets the value indicating whether to skip the rows with validation failure while loading the excel data.
3852
/// </summary>

src/FluentConfiguration/PropertyConfiguration.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ namespace FluentExcel
55
using System;
66

77
/// <summary>
8-
/// Value validator delegate, validate value before <see cref="PropertyConfiguration.ValueConverter"/>
8+
/// Cell value validator delegate, validate current cell value before <see cref="PropertyConfiguration.ValueConverter"/>
99
/// </summary>
1010
/// <param name="rowIndex">Row index of current cell in excel</param>
1111
/// <param name="columnIndex">Column index of current cell in excel</param>
12-
/// <param name="value">value of current cell</param>
13-
/// <returns>Wether the value passes validation</returns>
14-
public delegate bool ValueValidatorDelegate(int rowIndex, int columnIndex, object value);
12+
/// <param name="value">Value of current cell</param>
13+
/// <returns>Whether the value passes validation</returns>
14+
public delegate bool CellValueValidatorDelegate(int rowIndex, int columnIndex, object value);
1515

1616
/// <summary>
1717
/// Represents the configuration for the specfidied property.
@@ -61,9 +61,9 @@ public class PropertyConfiguration
6161
public string Formatter { get; internal set; }
6262

6363
/// <summary>
64-
/// Gets the value validator to validate the value.
64+
/// Gets the cell value validator to validate the cell value.
6565
/// </summary>
66-
public ValueValidatorDelegate ValueValidator { get; internal set; }
66+
public CellValueValidatorDelegate CellValueValidator { get; internal set; }
6767

6868
/// <summary>
6969
/// Gets the value converter to convert the value.
@@ -149,13 +149,13 @@ public PropertyConfiguration HasValueConverter(Func<object, object> valueConvert
149149
}
150150

151151
/// <summary>
152-
/// Configures the value validator for the specified property.
152+
/// Configures the cell value validator for the specified property.
153153
/// </summary>
154-
/// <param name="valueValidator">The value validator.</param>
154+
/// <param name="cellValueValidator">The value validator.</param>
155155
/// <returns>The <see cref="PropertyConfiguration"/>.</returns>
156-
public PropertyConfiguration HasValueValidator(ValueValidatorDelegate valueValidator)
156+
public PropertyConfiguration HasValueValidator(CellValueValidatorDelegate cellValueValidator)
157157
{
158-
ValueValidator = valueValidator;
158+
CellValueValidator = cellValueValidator;
159159

160160
return this;
161161
}

0 commit comments

Comments
 (0)