2009-11-18 7 views
1

나는 내 컨트롤러에서 내 Global.aspx내 AutoMapper 고객 ValueResolver 후크에 어떤 문제가 있습니까?

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 
} 

응용 프로그램 컴파일 및 실행은, 그러나 사용자 지정 해결하지 않고, 아무것도 객체로 온다, 그냥 예외 던지는와 모의 객체 접근을 얻을 만듭니다.

답변

0

FormCollectionValueResolver<Customer>이 호출되지 않는 이유는 메서드에 정의 된대로 지정된 멤버 옵션을 적용하여 모든 속성 매핑을 반복하는 것입니다. 그러나 제공 한 코드 샘플에서는 속성 매핑이 정의되지 않았으므로 해결자가 결코 호출되지 않습니다.

다음은 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); 
    } 
} 
+0

유형 변환기는 모든 프로젝트에서 사용하는 모든 비즈니스 객체의 수동 이름 매핑을 사용하지 않습니다. automapper가이를 사용하는 방법을 파악할 수 있다면 바랄 것입니다. 컨트롤러가 아닌 모델 바인더에서 변환을하는 것이 유리한 것은 아닌가요? 또한 유효성 검사 또는 변환에 고객 개체가 예외를 throw하는 잘못된 사용자 입력과 같은 문제가있는 경우이 대답은 문제를 해결하지 못하는 것으로 보입니다. – Maslow

+0

나는 원래의 대답에서 조금 성급했다. 나는 그것의 완전한 편집을했다. 바라기를 나의 새로운 대답은 조금 더 도움이 될 것입니다. – mrydengren

+0

이 답변을 올바르게 이해하면'ForAllMembers()'는 커스텀 정의 된'.ForMember' 속성에만 적용됩니까? 여기에 제네릭을 정의 할 수있는 방법이 있습니까? 여기서는 각 속성을 명시 적으로 정의하지 않고 필요한 속성 이름을 어디에 있습니까? – Maslow

0

당신은 모두 FormCollection 죽겠다 고려해야합니다

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

기본적으로, 당신은 형태에 대한 강력한 형식의 뷰 + 사용자 정의 만든 뷰 모델 유형에 의지 할 것이다. 이 양식에는 유효성 검증 속성과 같은 것이 있으므로 유효성 검증 프레임 워크를 통해 실행할 수 있습니다. 그것이 유효한 경우에만 게시 된 양식에서 지속성 모델을 업데이트하십시오. 게시 된 양식에서 도메인 객체를 직접 만들지 않습니다.

+0

필자가 원하는대로 자동 작업을 수행 할 수 있다면 양식 용 사용자 지정 작성 ViewModelTypes를 디자인하지 않아도됩니다. – Maslow

+0

그런 다음 사용자 정의 IObjectMapper를 제안합니다.이 기능을 사용하면 더 많은 유연성과 깨끗한 후크가 제공됩니다. 작동 시키면 아무 문제없이 AM에 추가 할 수 있습니다. –

+0

커스텀 IObjectMapper, 포인터 또는 아이디어를 디자인하는 방법을 찾지 못했습니다. 나는 몇 번 시도해 보았고 그 수업이 어떻게 작동했는지 알 수 없었습니다. – Maslow

관련 문제