CsvHelper Parsing boolean from String

让人想犯罪 __ 提交于 2019-12-23 02:18:13

问题


I'm currently trying to parse a value from a csv file that is a boolean. We've noticed that the value will successfully parse Yes and Y (in any case) but will not parse No and N

I'm mapping the value in the classmap like this:

Map(m => m.Enabled).Name("Enabled").TypeConverterOption(false, string.Empty);

Is there a reason why this would read Yes but not No and is there a way to add the ability to parse no?


回答1:


In version 4.0.3, this works.

void Main()
{
    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    using (var reader = new StreamReader(stream))
    using (var csv = new CsvReader(reader))
    {
        writer.WriteLine("Id,Name,IsSomething");
        writer.WriteLine("1,one,Yes");
        writer.WriteLine("2,two,Y");
        writer.WriteLine("3,three,No");
        writer.WriteLine("4,four,N");
        writer.Flush();
        stream.Position = 0;

        csv.Configuration.RegisterClassMap<TestMap>();
        csv.GetRecords<Test>().ToList().Dump();
    }
}

public class Test
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsSomething { get; set; }
}

public sealed class TestMap : ClassMap<Test>
{
    public TestMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
        Map(m => m.IsSomething)
            .TypeConverterOption.BooleanValues(true, true, "Yes", "Y")
            .TypeConverterOption.BooleanValues(false, true, "No", "N");
    }
}

In version 2.16.3 this works.

void Main()
{
    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    using (var reader = new StreamReader(stream))
    using (var csv = new CsvReader(reader))
    {
        writer.WriteLine("Id,Name,IsSomething");
        writer.WriteLine("1,one,Yes");
        writer.WriteLine("2,two,Y");
        writer.WriteLine("3,three,No");
        writer.WriteLine("4,four,N");
        writer.Flush();
        stream.Position = 0;

        csv.Configuration.RegisterClassMap<TestMap>();
        csv.GetRecords<Test>().ToList().Dump();
    }
}

public class Test
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsSomething { get; set; }
}

public sealed class TestMap : CsvClassMap<Test>
{
    public TestMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
        Map(m => m.IsSomething)
            .TypeConverterOption(true, "Yes", "Y")
            .TypeConverterOption(false, "No", "N");
    }
}



回答2:


We use the following in version 7

Usage for an individual mapping:

Map(m => m.IsSomething).Name("IsSomething").TypeConverter<MyBooleanConverter>();

Usage for applying to the CSV reader

csv.Configuration.TypeConverterCache.AddConverter<bool>(new MyBooleanConverter());

Code:

public sealed class MyBooleanConverter : DefaultTypeConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        if(TryParseConvertBoolean(text, out bool result))
        {
            return result;
        }

        return null;
    }

    public static bool TryParseConvertBoolean(string value, out bool result)
    {
        result = false;
        try
        {
            if (string.IsNullOrWhiteSpace(value))
                return false;
            else
            {
                var lower = value.ToLower();

                if (lower == "no" || lower == "n")
                {
                    result = false;
                    return true;
                }
                else if (lower == "yes" || lower == "y")
                {
                    result = true;
                    return true;
                }
            }
        }
        catch { }

        return false;
    }
}


来源:https://stackoverflow.com/questions/46970693/csvhelper-parsing-boolean-from-string

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!