使用Automapper映射到方法

时间:2010-11-27 06:47:54

标签: c# asp.net-mvc-2 automapper

我正在使用C#构建ASP.NET MVC 2应用程序,并且我成功地使用Automapper在ViewModel和业务对象之间来回映射值。

除了几个显式属性之外,我的业务对象还将字典包装为一个catch all,用于未明确定义的属性。类似于:

public class MyBusinessObject {
    public void SetExtraPropertyValue<T>(string key, T value) { 
        // ...
      }
    public T GetExtraPropertyValue<T>(string key, T defaultValue) {
        // ...
      }
}

在我的ViewModel中,我可以自由创建我想要的任何属性,但我无法修改业务对象。

所以我想说我创建了一个这样的视图模型:

class MyViewModel {
  public string CustomProp { get; set; }
}

我想要存储和检索的值需要使用

businessModelInstance.SetExtraPropertyValue("CustomProp", newVal);

businessModelInstance.GetExtraPropertyValue("CustomProp");

我向两个方向都有问题 首先,当从MyBusinessObject转到MyViewModel时,我认为在我的自定义Automapper配置文件中应该很简单:

CreateMap<MyBusinessObject, MyViewModel>()
  .ForMember(dest => dest.CustomProp, 
             opt => opt.MapFrom(s => s.GetExtraPropertyValue("CustomProp", "")));

但是,MyBusinessObject.CustomProp永远不会填充,但其他属性也是如此 其次,我不知道如何配置从MyViewModel.CustomProp获取值到调用MyBusinessObject.SetExtraPropertyValue

  • 有没有办法实现这一目标 使用Automapper进行映射?
  • 我是否有完全不同的攻击? 应该尝试?
  • 我是否必须在控制器中使用手动映射?例如,MyBusinessObject.SetExtraPropertyValue("CustomProp", MyViewModel.CustomProp)

<小时/> 更新:以下是基于@Patrick Steele建议的解决方案: 我向视图模型属性添加了一个自定义属性,我希望将其映射到额外的属性键。自定义TypeConverter使用反射来正确查找这些属性和地图属性。

public class ItemExtraPropertyConverter : ITypeConverter<MyViewModel, MyBusinessObject>
{
    public MyBusinessObject Convert(ResolutionContext context)
    {
        var destination = context.DestinationValue as MyBusinessObject;
        if (destination == null )
            throw new InvalidOperationException("Destination type is not of type MyBusinessObject");

        foreach (var property in context.SourceType.GetProperties())
            foreach (var attribute in property.GetCustomAttributes(true).OfType<ExtraPropertyAttribute>())
            {
                var key = attribute.Key;
                if (string.IsNullOrEmpty(key))
                    key = property.Name;
                destination.SetExtraPropertyValue(key, property.GetValue(context.SourceValue, null));
            }

        return destination;
    }
}

public class ExtraPropertyAttribute : Attribute
{
    public ExtraPropertyAttribute()
    {
    }
    public ExtraPropertyAttribute(string key)
    {
        Key = key;
    }

    public string Key { get; set; }
}

public class MyViewModel
{
    [ExtraProperty]
    public string CustomProp { get; set; }

    [ExtraProperty("OtherPropertyValue")]
    public string CustomProp2 { get; set; }
}

在自定义配置文件类的配置方法中:

CreateMap<MyViewModel, MyBusinessObject>()
            .ConvertUsing<ItemExtraPropertyConverter>();

1 个答案:

答案 0 :(得分:0)

我的猜测是你的GetExtraPropertyValue和SetExtraPropertyValue实现有问题。我汇总了一个快速测试,你上面提供的映射按预期工作。这是我用于测试的实现:

public class MyBusinessObject
{
    private readonly Dictionary<string, object> extraProperties = new Dictionary<string, object>();

    public int Id { get; set; }
    public string Name { get; set; }

    public void SetExtraPropertyValue<T>(string key, T value)
    {
        extraProperties.Add(key, value);
    }
    public T GetExtraPropertyValue<T>(string key, T defaultValue)
    {
        if (extraProperties.ContainsKey(key))
        {
            return (T)extraProperties[key];
        }

        return defaultValue;
    }
}