Automapper 定义了一个自定义变量,用于确定来自目标的多个属性的值

Automapper define a custom variable used to determine the values of several properties from destination

我正在使用 AutoMapper 将一些 DTO 映射到 ui 模型。但是,我的一个 DTO 包含一个带有序列化数据的字段(序列化数据代表另一个具有属性的对象),用于确定模型的几个属性的值。

例如:

public class SourceDTo
{
  public int Id {get; set;}
  public int Name {get; set;}
  public string SerializedDetails {get; set;} 
}

public source DestinationModel
{
  public int Id {get; set;}
  public int Name {get; set;}
  public string Address {get; set;}
  public string AccountNr {get; set;}
}

所以在这种情况下,当将源映射到目标时,我希望能够先反序列化 SerializedDetails 字段,然后使用它来映射具有该对象属性的 Address 和 AccountNr,而不是反序列化它两次,每次 属性。这可以用 AutoMapper 完成吗?

可能不是最优雅的解决方案YMMV:

CreateMap<Foo, Bar>()
    .ForMember(dest => dest.prop1
        , opt => opt.MapFrom((src, dest, destMember, context) => context.GetJsonObjectValue<string>("RawMessageJSON", "$.props.prop1")))
    .ForMember(dest => dest.prop2
        , opt => opt.MapFrom((src, dest, destMember, context) => context.GetJsonObjectValue<int>("RawMessageJSON", "$.props.prop2")));

JObject:

中提取 Json 路径值的辅助扩展方法
public static class AutomapperResolutionContextExtensions
{
    public static T GetJsonObjectValue<T>(this ResolutionContext context, string key, string jsonTokenPath)
        => ((JObject)context.Items[key]).SelectToken(jsonTokenPath).ToObject<T>();
}

这是我们正在映射的类:

public class Foo
{
    public string RawMessageString { get; set;}

    [NotMapped]
    public JObject RawMessageJSON => JObject.Parse(RawMessageString);
}

public class Bar
{
    public string prop1 { get; set; }
    public int prop2 { get; set; }        
}

当调用 Map() 时,我们将字符串反序列化为 JObject 并在 Items Dictionary 中传递它:

var bar = mapper.Map<Bar>(foo, opt => opt.Items["RawMessageJSON"] = foo.RawMessageJSON);