AutoMapper 转换器因空值而失败

发布于 2024-08-20 07:50:28 字数 2098 浏览 7 评论 0原文

注意:这个问题现已过时,仅适用于旧版本的 AutoMapper。此处提到的错误已修复。


问题:

我有一个 AutoMapper 转换器,它采用 Nullable/bool? 并返回一个字符串。我将此全局应用到我的个人资料中,它适用于 truefalse,但不适用于 null

这是我的 AutoMapper 配置文件中的内容:

CreateMap<bool?, string>()
    .ConvertUsing<NullableBoolToLabel>();

这是转换器类:

public class NullableBoolToLabel : ITypeConverter<bool?, string>
{
    public string Convert(bool? source)
    {
        if (source.HasValue)
        {
            if (source.Value)
                return "Yes";
            else
                return "No";
        }
        else
            return "(n/a)";
    }
}

演示问题的示例

public class Foo
{
    public bool? IsFooBarred { get; set; }
}

public class FooViewModel
{
    public string IsFooBarred { get; set; }
}

public class TryIt
{
    public TryIt()
    {
        Mapper.CreateMap<bool?, string>().ConvertUsing<NullableBoolToLabel>();
        Mapper.CreateMap<Foo, FooViewModel>();

        // true (succeeds)
        var foo1 = new Foo { IsFooBarred = true };
        var fooViewModel1 = Mapper.Map<Foo, FooViewModel>(foo1);
        Debug.Print("[{0}]", fooViewModel1.IsFooBarred); // prints: [Yes] 

        // false (succeeds)
        var foo2 = new Foo { IsFooBarred = false };
        var fooViewModel2 = Mapper.Map<Foo, FooViewModel>(foo2);
        Debug.Print("[{0}]", fooViewModel2.IsFooBarred); // prints: [No] 

        // null (fails)
        var foo3 = new Foo { IsFooBarred = null };
        var fooViewModel3 = Mapper.Map<Foo, FooViewModel>(foo3);
        Debug.Print("[{0}]", fooViewModel3.IsFooBarred); // prints: []
                                                   // should print: [(n/a)]
    }
}

问题:

  1. 这是一个错误还是设计使然?
  2. 如果是设计使然,那么其背后的原因是什么?
  3. 你能推荐一个解决方法吗?

Note: this question is now out of date and only applies to old versions of AutoMapper. The bug referred to here has been fixed.


Problem:

I have an AutoMapper converter that takes a Nullable<bool>/bool? and returns a string. I apply this globally to my profile, and it works for true and false but not for null.

Here is what I have in my AutoMapper profile:

CreateMap<bool?, string>()
    .ConvertUsing<NullableBoolToLabel>();

And here is the converter class:

public class NullableBoolToLabel : ITypeConverter<bool?, string>
{
    public string Convert(bool? source)
    {
        if (source.HasValue)
        {
            if (source.Value)
                return "Yes";
            else
                return "No";
        }
        else
            return "(n/a)";
    }
}

Example that demonstrates problem

public class Foo
{
    public bool? IsFooBarred { get; set; }
}

public class FooViewModel
{
    public string IsFooBarred { get; set; }
}

public class TryIt
{
    public TryIt()
    {
        Mapper.CreateMap<bool?, string>().ConvertUsing<NullableBoolToLabel>();
        Mapper.CreateMap<Foo, FooViewModel>();

        // true (succeeds)
        var foo1 = new Foo { IsFooBarred = true };
        var fooViewModel1 = Mapper.Map<Foo, FooViewModel>(foo1);
        Debug.Print("[{0}]", fooViewModel1.IsFooBarred); // prints: [Yes] 

        // false (succeeds)
        var foo2 = new Foo { IsFooBarred = false };
        var fooViewModel2 = Mapper.Map<Foo, FooViewModel>(foo2);
        Debug.Print("[{0}]", fooViewModel2.IsFooBarred); // prints: [No] 

        // null (fails)
        var foo3 = new Foo { IsFooBarred = null };
        var fooViewModel3 = Mapper.Map<Foo, FooViewModel>(foo3);
        Debug.Print("[{0}]", fooViewModel3.IsFooBarred); // prints: []
                                                   // should print: [(n/a)]
    }
}

Questions:

  1. Is this a bug or by design?
  2. If it's by design, what is the reasoning behind it working this way?
  3. Can you recommend a workaround?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吻泪 2024-08-27 07:50:28

您需要为Map指定ConvertUsing吗?否则,我不确定它如何知道如何使用 Foo 类的 IsFooBarred 成员。但我不熟悉映射器,也许它可以解决这个问题(在前两种情况下似乎确实如此)。

如果您在 Convert 中放置断点,在这 3 种情况中的任何一种情况下,它都会被击中(在调试器中)吗?

Do you need to specify a ConvertUsing for the Map? Otherwise, I'm not sure how it would know how to use the IsFooBarred member of the Foo class. But I'm not familar with the Mapper, and perhaps it can figure this out (it does seem to in the first two cases).

If you put a breakpoint in Convert does it get hit (in the debugger) in any of the 3 cases?

兮颜 2024-08-27 07:50:28

这是 AutoMapper 中的一个错误,现已修复。

自从提出这个问题以来,ITypeConverter 界面也发生了变化。转换器现在看起来像这样:

public class NullableBoolToLabel : ITypeConverter<bool?, string>
{
    public string Convert(ResolutionContext context)
    {
        var source = (bool?)context.SourceValue;
        if (source.HasValue)
        {
            if (source.Value)
                return "Yes";
            else
                return "No";
        }
        else
            return "(n/a)";
    }
}

This was a bug in AutoMapper and has since been fixed.

The ITypeConverter interface has also changed since this question was asked. The converter would now look like this:

public class NullableBoolToLabel : ITypeConverter<bool?, string>
{
    public string Convert(ResolutionContext context)
    {
        var source = (bool?)context.SourceValue;
        if (source.HasValue)
        {
            if (source.Value)
                return "Yes";
            else
                return "No";
        }
        else
            return "(n/a)";
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文