Cannot apply TryTake if there is error when parsing Enum
VAllens opened this issue · comments
Get attribute value as friendly display name if property has DisplayName
attribute.
Or you design a custom attribute enhancement class that provides a custom friendly display name, column display order, and so on.
Or does Npoi.Mapper
already have a similar function? Do you have a better idea?
Sample data model code:
public class CatalogCareViewModel
{
/// <summary>
/// ISO/国际标准
/// </summary>
public virtual string ISO { get; set; }
/// <summary>
/// German/德语
/// </summary>
[DisplayName("German")]
public virtual string DE { get; set; }
/// <summary>
/// English/英语
/// </summary>
[DisplayName("English")]
public virtual string EN { get; set; }
/// <summary>
/// French/法语
/// </summary>
[DisplayName("French")]
public virtual string FR { get; set; }
/// <summary>
/// Russion/俄语
/// </summary>
[DisplayName("Russion")]
public virtual string RU { get; set; }
/// <summary>
/// Italian/意大利语
/// </summary>
[DisplayName("Italian")]
public virtual string IT { get; set; }
/// <summary>
/// Dutch/荷兰语
/// </summary>
[DisplayName("Dutch")]
public virtual string NL { get; set; }
/// <summary>
/// Norwegian/挪威
/// </summary>
[DisplayName("Norwegian")]
public virtual string NO { get; set; }
}
Sample excel sheet table
ISO | German | English | French | Russion | Italian | Dutch | Norwegian |
---|---|---|---|---|---|---|---|
value1 | value2 | value3 | value4 | value5 | value6 | value7 | value8 |
value1 | value2 | value3 | value4 | value5 | value6 | value7 | value8 |
value1 | value2 | value3 | value4 | value5 | value6 | value7 | value8 |
不好意思, 有点看不太懂, 用中文好吗?
我大体看了一下,你的组件是支持双向字段名映射的,现在这个已经没问题了。
但又有另外一个问题。
我调用了你的public static Mapper Map(this Mapper mapper, string columnName, Expression<Func<T, object>> propertySelector,
Func<IColumnInfo, object, bool> tryTake = null,
Func<IColumnInfo, object, bool> tryPut = null)方法。
想要实现导入时的枚举值自定义转换。
举例:###
枚举代码:####
public enum Category
{
[Description("Additional Care")]
AdditionalCare,
[Description("Bleach")]
Bleach,
[Description("Dry & Wring")]
DryWring,
[Description("Dry Clean")]
DryClean,
[Description("Iron")]
Iron,
[Description("Wash")]
Wash
}
Excel表格里是这样的枚举值,比如有以下三条数据
Category |
---|
Additional Care |
Bleach |
Dry & Wring |
导入过程没有任何异常。
var list = mapper.Take<TModel>().Select(t => t.Value).ToList();
list得到三条为null的数据。
调试过程发现,在这里发生异常:
public static bool TryGetCellValue(ICell cell, Type targetType, out object value)
......
value = Enum.Parse(targetType, cell.NumericCellValue.ToString(CultureInfo.InvariantCulture));
......
Take
方法返回的对象有错误信息.
枚举值目前是严格从名字来parse的, 并没有取相应的attribute, 因为
- 相关的attribute比较多, 包括Display, DisplayName, Description等
- 上面这些attribute的值不能保证唯一性, 取哪一个的值都可能会导致unexpected result,给查找问题增加难度.
你的例子可以用自定义TryTake 方法解决. 首页有例子.
mapper.Map<Sample>("columnA", o => o.MyEum, (column, o)=>
{
// custom logic to take value from cell.
}, null);
谢谢,是的,我就是定义了TryTake方法后报的异常。
mapper.Map<CatalogCareViewModel>("Category",
t => t.Category,
(column, target) =>
{
string value = column.CurrentValue.NullableToString(); //如果为null,返回string.Empty;
//枚举值为Key,枚举描述为Value
var key = categories.Where(t => t.Value == value).Select(t => t.Key).FirstOrDefault();
if (key == null) //如果为null,表示这不是一个合法的枚举描述
{
return false;
}
((CatalogCareViewModel) target).Category = (CareCategory) Enum.Parse(typeof(CareCategory), key);
return true;
},
(column, source) =>
{
//填充枚举描述
column.CurrentValue = ((CatalogCareViewModel) source).Category.GetDescription();
return true;
});
你的
private static void LoadRowData(IEnumerable<ColumnInfo> columns, IRow row, object target, IRowInfo rowInfo)
方法内部
走到MapHelper.TryGetCellValue
方法抛出异常,代码不再继续往下走,而是直接跳到catch
块。
意味着即便我定义了TryTake
处理逻辑,它也不会执行。
所以我觉得你应该把TryTake
是否为null
的判断以及执行放在MapHelper.TryGetCellValue
方法之前。
Hi, Donny.
还记得之前说过的自动化发布NuGet
包吗?完全可以在AppVeyor
上做到。
每次git push
触发AppVeyor
构建并且测试通过后发布小版本(如:3.1.0.yyyy
)到NuGet
。
打tag
发布常规版本(如:3.1.x.yyyy
)到NuGet
。
这个过程涉及到的密钥/token
等安全信息,可以通过环境变量
传入,以及使用AppVeyor
自带的Encrypt加密,防止泄漏。