Automapper - 将NameValueCollection转换为强类型集合

4
在 AutoMapper 中,我该如何将 NameValueCollection 映射到强类型集合?
Mapper.Map<NameValueCollection, List<MetaModel>>();

public class MetaModel
{
     public string Name;
     public string Value;
}
2个回答

4
建立在 @dtryon 的回答基础上,这个问题的难点在于没有办法将 NameValueCollection 中的内部对象映射到您的 DTO 类型。
您可以编写一个自定义转换器,从 NameValueCollection 中的项目构造 KeyValuePair<string, string> 对象。这将允许您创建一个通用转换器,利用另一个从 KeyValuePair 到您选择的目标类型的映射。例如:
public class NameValueCollectionConverter<T> : ITypeConverter<NameValueCollection, List<T>>
{
    public List<T> Convert(ResolutionContext ctx) 
    {
        NameValueCollection source = ctx.SourceValue as NameValueCollection;

        return source.Cast<string>()
            .Select (v => MapKeyValuePair(new KeyValuePair<string, string>(v, source[v])))
            .ToList();
    }

    private T MapKeyValuePair(KeyValuePair<string, string> source) 
    {
        return Mapper.Map<KeyValuePair<string, string>, T>(source);
    }
}

那么你需要定义一个从 KeyValuePair<string, string>MetaModel 的映射:

Mapper.CreateMap<KeyValuePair<string, string>, MetaModel>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Key))
    .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.Value));

最后,使用自定义转换器创建 NameValueCollectionList<MetaModel> 之间的映射。
Mapper.CreateMap<NameValueCollection, List<MetaModel>>()
    .ConvertUsing<NameValueCollectionConverter<MetaModel>>();

2

嗯,由于 NameValueCollection 是如此“特别”,我认为没有好的方法来做这件事。这主要是因为你无法获取到 NameValueCollection 内部的键/值对象。幸运的是,映射到 List<MetaModel> 的代码并不那么糟糕。我只需要手动映射它并继续工作:

[TestMethod]
    public void TestMethod2()
    {
        List<MetaModel> dest = new List<MetaModel>();
        NameValueCollection src = new NameValueCollection();

        src.Add("Key1", "Value1");
        src.Add("Key2", "Value2");
        src.Add("Key3", "Value3");
        src.Add("Key4", "Value4");
        src.Add("Key5", "Value5");

        foreach (var srcItem in src.AllKeys)
        {
            dest.Add(new MetaModel() { Name = srcItem, Value = src[srcItem] });
        }

        Assert.AreEqual(5, dest.Count);

    }

+1,虽然你可以将其包装在自定义解析器中,使其更具可重用性。 - Andrew Whitaker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接