3

ユーザー入力エラーが原因で int フィールドにテキストが含まれることがある csv ファイルを処理しています。これは最初の列であり、基本的には一意のレコード ID である必要があります。を使用してエラーをキャッチしていますengine.ErrorManager.ErrorMode = ErrorMode.SaveAndContinue;

私がやりたいことは、エラーを無視して、テキストを選択した数値に置き換えて、処理された結果にその行を含めることです。

ファイル定義クラスファイルで宣言したデフォルト値に固執するプロセスでも問題ありません。 [FieldNullValue(typeof(int), "0")]

もう1つのことは、実行時にどのファイルを解析するかを次のように決定していることです。

Type t = assembly.GetType(assemblyName.Name + ".FileDefinitions." + className);  

FileHelperEngine engine = new FileHelperEngine(t);   

したがって、D.Lambertの提案を何に入れるかというコンテキストで実装する方法がわかりません。<CustomersFixedWithNumericId>明確にするために、アップロード/処理される7つの異なるファイル定義(クラスファイル)がありますが、それらすべてに CustomerId フィールドがあります。

4

1 に答える 1

2

FileHelpersの現在の状態を考えると、実際にはそのフィールドを文字列として定義し、それに対して独自の検証を行う必要があります。

これに対処するいくつかの異なる方法を検討しました。最初に、フィールドではなくプロパティを使用してレコードを設定してみました。これにより、Stringプロパティを作成し、Setの入力を検証できた可能性があります。これは、次の理由で困難であることが判明しました。

  • 属性はターゲットフィールドのみに設定されます(FileHelpersコードを変更する場合はかなり簡単に修正できます。
  • プロパティのプライベートフィールドは、[FieldNotInFile]属性(不快感)でマークする必要があります。
  • プロパティはRecordInfo.CreateCoreFields()メソッドでは処理されません。プロパティとフィールドのマージされたリストを正しい順序で作成する必要があるため、これは修正するのに少し複雑です。これが私がこの方法を検討するのをやめたポイントです。

次の計画:レコード定義をそのまま使用し、読み取り中に検証します。エンジンにイベントハンドラーを設定します。

    engine.AfterReadRecord += new Events.AfterReadHandler<CustomersFixedWithNumericId>(engine_AfterReadRecord);
    var res = engine.ReadFile(path);

次に、ハンドラーで不正な値を処理します。

    void engine_AfterReadRecord(EngineBase engine, Events.AfterReadEventArgs<CustomersFixedWithNumericId> e)
    {
        int intVal;
        int.TryParse(e.Record.CustomerID, out intVal);
        e.Record.CustomerID = intVal.ToString();
    }

どちらも完璧ではありませんが、2番目はかなり近いと思います。

補遺:これは、レイトバウンドクラスでの上記のテクニックを示しています。

public void TestMethod1()
{
    var assembly = System.Reflection.Assembly.GetExecutingAssembly();
    Type t = assembly.GetType("FileHelpers.Tests.CustomersFixedWithNumericId");
    FileHelperEngine engine = new FileHelperEngine(t);

    string path = @"pathtofile\BadCustomersFixedNumericId.txt";

    engine.AfterReadRecord += new Events.AfterReadHandler<object>(engine_AfterReadRecord);
    var res = engine.ReadFile(path);
}

void engine_AfterReadRecord(EngineBase engine, Events.AfterReadEventArgs<object> e)
{
    // validation here
}
于 2011-03-30T18:52:14.297 に答える