Reputation: 27370
I've been looking through filehelpers documentation, but there doesn't seem anything to handle empty values in columns. I need to be able to set a 'non-empty' string attribute on all the columns.
Can anyone point me in the right direction?
Upvotes: 3
Views: 4747
Reputation: 1236
I needed the same thing for one of our projects that utilizes FileHelpers heavily and contributed to provide the new FieldNotEmptyAttribute, which could be used like so:
[DelimitedRecord("|")]
public class MyClass
{
[FieldNotEmpty()]
public string Field1;
public string Field2;
[FieldNotEmpty()]
public string Field3;
}
In the example above, if Field1 or Field3 is empty in the source file, then a ConvertException is thrown.
Upvotes: 2
Reputation: 21
Using a Converter will not work, as FileHelpers.FieldBase
checks for a zero length field, and returns Null, before invoking the Converter.
Using the public static FileHelperEngine GetEngine()
ensures that the AfterReadRecord
event validation is wired up correctly.
[DelimitedRecord(",")]
public class RequiredField
{
public string Required;
public static FileHelperEngine GetEngine()
{
var result = new FileHelperEngine(typeof(RequiredField));
result.AfterReadRecord += AfterReadValidation;
return result;
}
private static void AfterReadValidation(EngineBase sender, AfterReadRecordEventArgs args)
{
if (String.IsNullOrWhiteSpace(((RequiredField)args.Record).Required))
{
throw new ConvertException("RequiredField is Null or WhiteSpace", typeof(String));
}
}
}
Upvotes: 2
Reputation: 11326
You can perform any validation you want in the AfterReadRecord
event. If you want to continue processing the rest of the file if there is an error, you also need to set the ErrorMode
to SaveAndContinue
. See below for a working example.
[DelimitedRecord("|")]
public class MyClass
{
public string Field1;
public string Field2;
public string Field3;
}
class Program
{
static void Main(string[] args)
{
var engine = new FileHelperEngine<MyClass>();
engine.AfterReadRecord += new FileHelpers.Events.AfterReadHandler<MyClass>(engine_AfterReadRecord);
engine.ErrorMode = ErrorMode.SaveAndContinue;
// import a record with an invalid Email
MyClass[] validRecords = engine.ReadString("Hello||World");
ErrorInfo[] errors = engine.ErrorManager.Errors;
Assert.AreEqual(1, engine.TotalRecords); // 1 record was processed
Assert.AreEqual(0, validRecords.Length); // 0 records were valid
Assert.AreEqual(1, engine.ErrorManager.ErrorCount); // 1 error was found
Assert.That(errors[0].ExceptionInfo.Message == "Field2 is invalid");
}
static void engine_AfterReadRecord(EngineBase engine, FileHelpers.Events.AfterReadEventArgs<MyClass> e)
{
if (String.IsNullOrWhiteSpace(e.Record.Field1))
throw new Exception("Field1 is invalid");
if (String.IsNullOrWhiteSpace(e.Record.Field2))
throw new Exception("Field2 is invalid");
if (String.IsNullOrWhiteSpace(e.Record.Field3))
throw new Exception("Field3 is invalid");
}
}
Upvotes: 4
Reputation: 11326
By default an empty string will be parsed as String.Empty
in FileHelpers, but you can override this with a custom converter:
public class EmptyStringConverter : ConverterBase
{
public override object StringToField(string sourceString)
{
if (String.IsNullOrWhiteSpace(sourceString))
return null;
return sourceString;
}
}
Then you define your record class property like this
[FieldConverter(typeof(EmptyStringConverter))]
public string Field1;
If the string corresponding to Field1
is empty or blank, it will be converted to null.
Upvotes: 3