【问题标题】:Empty property value after Automapper v5 upgradeAutomapper v5 升级后的空属性值
【发布时间】:2016-08-01 10:19:39
【问题描述】:

我有以下代码在 Automapper v3 中工作,但在 v5 中不再工作。 更新 它也适用于 v4。

CallScheduleProfile 在其构造函数中将Title 属性设置为将true 值传递给它的类的实例。

CallScheduleProfileViewModel 在其构造函数中将Title 属性设置为传递true"Title" 值的不同类的实例。

我已经在 AutoMapper 中为所有 4 个类设置了映射,然后我调用了 Map。

结果是映射后CallScheduleProfileViewModel 上的Title 属性的布尔值为true,但FriendlyName 为空,即使它已在其构造函数中设置。

我认为正在发生的事情是 CallScheduleProfileViewModel 上的构造函数被调用并且 FriendlyName 被分配,但是当映射发生时,它调用 Entry 上的构造函数,然后映射 UxEntry 上的任何属性存在并将其分配给Title 属性,默认情况下FriendlyName 将为null,因为FriendlyName 不存在UxEntry,其值不会被复制。

我的假设可能是错误的,但无论哪种方式,我如何在映射中填充 FriendlyName

更新:我查看了有关嵌套类型的 Automapper documentation,并且文档中提供的代码也存在问题。如果我将字符串属性添加到InnerDest 并在OuterDest 构造函数中设置其值,则在Map 之后其值为null。

public static void Main(string[] args)
{
    Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<UxEntry<bool>, Entry<bool>>();

        cfg.CreateMap<CallScheduleProfile, CallScheduleProfileViewModel>();
    });

    var old = new CallScheduleProfile();

    var newmodel = Mapper.Map<CallScheduleProfile, CallScheduleProfileViewModel>(old);

    Console.WriteLine(newmodel.Title.Value);
    Console.WriteLine(newmodel.Title.FriendlyName);
}

public class UxEntry<T>
{
    public static implicit operator T(UxEntry<T> o)
    {
        return o.Value;
    }

    public UxEntry()
    {
        this.Value = default(T);
    }

    public UxEntry(T value)
    {
        this.Value = value;
    }

    public T Value { get; set; }
}


public class CallScheduleProfile
{
    public CallScheduleProfile()
    {
        this.Title = new UxEntry<bool>(true);
    }

    public UxEntry<bool> Title { get; set; }

}

public class Entry<T>
{
    public Entry()
    {
    }

    public Entry(T value, string friendlyName)
    {
        this.Value = value;
        this.FriendlyName = friendlyName;
    }

    public T Value { get; set; }
    public string FriendlyName { get; set; }

    public static implicit operator T(Entry<T> o)
    {
        return o.Value;
    }
}


public class CallScheduleProfileViewModel 
{
    public CallScheduleProfileViewModel()

    {
        this.Title = new Entry<bool>(true, "Title");
    }
    public Entry<bool> Title { get; set; }
}

【问题讨论】:

    标签: c# automapper automapper-5


    【解决方案1】:

    好吧,Automapper 将此属性映射到 null,因为:

    A) Entry&lt;T&gt; 类型的构造函数将此属性设置为 null

    B) Automapper 在 (!) CallScheduleProfileViewModel 中的构造函数被调用后创建 Entry&lt;T&gt; 的新实例。

    C) 没有为 Automapper 设置其他规则

    您可以在这里做的是更改配置,以便让 Automapper 知道应该有一个用于属性之一的默认值:

            Mapper.Initialize(cfg =>
            {
                // when UxEntry is mapped to Entry value "Title" is used for property FriendlyName
                cfg.CreateMap<UxEntry<bool>, Entry<bool>>()
                    .ForMember(dest => dest.FriendlyName, opt => opt.UseValue("Title"));
    
                cfg.CreateMap<CallScheduleProfile, CallScheduleProfileViewModel>();
            });
    

    现在我们可以从 CallScheduleProfileViewModel 的构造函数中删除多余的属性初始化。

    在没有其他更改的情况下运行您的代码会产生以下输出:

    true    
    Title
    

    【讨论】:

    • 我发现cfg.CreateMap&lt;CallScheduleProfile, CallScheduleProfileViewModel&gt;().ForMember(dest =&gt;dest.Title, o =&gt; o.UseDestinationValue()); 也有效
    猜你喜欢
    • 1970-01-01
    • 2017-02-19
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多