Что не так с моим AutoMapper Customer ValueResolver Hook? - PullRequest
1 голос
/ 19 ноября 2009

У меня есть следующий хук в моем 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 голосов
/ 28 ноября 2009

Вы должны рассмотреть возможность отказа от FormCollection:

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

В основном вы будете опираться на строго типизированные представления + созданные пользователем типы ViewModel для форм. Эти формы имеют такие атрибуты, как валидация, поэтому вы можете запускать их через рамки валидации. Если он действителен, только тогда вы обновляете свою модель персистентности из опубликованной формы. Мы избегаем создания доменных объектов непосредственно из опубликованной формы.

0 голосов
/ 27 ноября 2009

Причина, по которой 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...