我的AutoMapper客户ValueResolver Hook出了什么问题?

时间:2009-11-18 22:21:34

标签: asp.net-mvc automapper

我的Global.aspx中有以下钩子

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
        AutoMapper.Mapper.CreateMap<FormCollection, Models.IAmACustomer>().ForAllMembers(form => form.ResolveUsing<Models.FormCollectionValueResolver<Models.IAmACustomer>>());
    }

在我的控制器中:

[HttpPost]
    public ActionResult Create(FormCollection formCollection)
    {

        var customer = AutoMapper.Mapper.Map<FormCollection,Models.IAmACustomer> (formCollection,null);
    }

此行已执行,但我的自定义解析程序从未被调用。

解析器看起来像这样:

public class FormCollectionValueResolver<TDestination>:ValueResolver<FormCollection,TDestination>
{
//Code removed for brevity
}

应用程序编译并运行,但是没有自定义解析器,没有任何东西进入对象,它只是创建一个模拟对象,异常抛出get访问器。

2 个答案:

答案 0 :(得分:0)

永远不会调用FormCollectionValueResolver<Customer>的原因是ForAllMembers()方法迭代所有属性映射,如ForMember()方法所定义,应用指定的成员选项。但是,在您提供的代码示例中,未定义任何属性映射,因此永远不会调用解析器。

以下是如何使用ForAllMembers()方法的示例。

[Test]
public void AutoMapperForAllMembersTest()
{
    Mapper.CreateMap<Source, Destination>()
        .ForMember(dest => dest.Sum, 
            opt => opt.ResolveUsing<AdditionResolver>())
        .ForMember(dest => dest.Difference,
            opt => opt.ResolveUsing<SubtractionResolver>())
        .ForAllMembers(opt => opt.AddFormatter<CustomerFormatter>());

    Source source = new Source();
    source.Expression = new Expression
    {
        LeftHandSide = 2,
        RightHandSide = 1
    };

    Destination destination = Mapper.Map<Source, Destination>(source);
    Assert.That(destination.Sum, Is.EqualTo("*3*"));
    Assert.That(destination.Difference, Is.EqualTo("*1*"));
}    

public class Expression
{
    public int LeftHandSide { get; set; }

    public int RightHandSide { get; set; }
}

public class Source
{
    public Expression Expression { get; set; }
}

public class Destination
{
    public string Sum { get; set; }

    public string Difference { get; set; }
}

public class AdditionResolver : ValueResolver<Source, int>
{
    protected override int ResolveCore(Source source)
    {
        Expression expression = source.Expression;
        return expression.LeftHandSide + expression.RightHandSide;
    }
}

public class SubtractionResolver : ValueResolver<Source, int>
{
    protected override int ResolveCore(Source source)
    {
        Expression expression = source.Expression;
        return expression.LeftHandSide - expression.RightHandSide;
    }
}

public class CustomerFormatter : IValueFormatter
{
    public string FormatValue(ResolutionContext context)
    {
        return string.Format("*{0}*", context.SourceValue);
    }
}

答案 1 :(得分:0)

你应该考虑完全抛弃FormCollection:

http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx

基本上,您将依赖于强类型视图+自定义创建的表单ViewModel类型。这些表单具有类似验证属性的内容,因此您可以通过验证框架运行它们。如果它有效,那么只有从发布的表单更新持久性模型。我们不会直接从发布的表单创建域对象。