jaffa
jaffa

Reputation: 27370

How do I setup filehelpers with a required, not empty column

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

Answers (4)

Jordan Parker
Jordan Parker

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

David White
David White

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

shamp00
shamp00

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

shamp00
shamp00

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

Related Questions