2012-02-03 2 views
14

일부 Model 데이터를 가져 와서 약간 바꾼 ViewModel이 있습니다.AutoMapper에서 사용자 지정 속성을 처리하는 방법

ViewModel에 대한 생성자에 DomainModel을 전달했기 때문에 "작동"하는 방법이 있지만 일대일 ViewModels에서 AutoMapper를 사용하고 있기 때문에 모든 ViewModel에서 매핑을 수행하는 방법을 배우십시오.

다음은 약간의 추가 기능을 수행하는 ViewModel의 예입니다.

public class UsersDetailsViewModel 
{ 
    public string UserName { get; set; } 
    public string Email { get; set; } 
    public string Website { get; set; } 
    public int ID { get; set; } 
    public List<OpenID> OpenIds { get; set; } 
    public string UserAge { get; set; } 
    public string About { get; set; } 
    public string Slug { get; set; } 
    public System.DateTime LastSeen { get; set; } 
    public string Region { get; set; } 
    public string MemberSince { get; set; } 
    public string Reputation { get; set; } 
    public bool IsUserMatch { get; set; } 

    private readonly MarkdownDeep.Markdown _markdown; 


    public UsersDetailsViewModel(Domain.User user) 
    { 
     AuthUserData currentuser = AuthenticationHelper.RetrieveAuthUser; 
     _markdown.NoFollowLinks = true; 
     _markdown.SafeMode = true; 
     _markdown.ExtraMode = false; 
     _markdown.MarkdownInHtml = true; 

     // We want to ensure that the user has a username, even if they 
     // haven't set one yet. What this does is check to see if the 
     // user.UserName field is blank, and if it is, it will set the 
     // username to "UserNNNN" where NNNN is the user ID number. 
     _UserName = (user.UserName != null) ? user.UserName : "User" + user.ID.ToString; 

     // Nothing fancy going on here, we're just re-passing the object from 
     // the database to the View. No data manipulation! 
     _Email = user.Email; 
     _Website = user.WebSite; 
     _ID = user.ID; 

     // Get's a list of all of the user's OpenID's 
     _OpenIds = user.OpenIDs.ToList; 

     // Converts the users birthdate to an age representation 
     _UserAge = user.BirthDate.ToAge; 
     //IE: 29 

     // Because some people can be real ass holes and try to submit bad 
     // data (scripts and shitè) we have to modify the "About" content in 
     // order to sanitize it. At the same time, we transform the Markdown 
     // into valid HTML. The raw input is stored without sanitization in 
     // the database. this could mean Javascript injection, etc, so the 
     // output ALWAYS needs to be sanitized. 

     // This method below was used in conjunction with MarkDownSharp 
     // _About = Trim(Utilities.HtmlSanitizer.Sanitize(Markdown.Transform(user.About))) 
     _About = _markdown.Transform(user.About); 

     // Removes spaces from Usernames in order to properly display the 
     // username in the address bar 
     _Slug = Strings.Replace(user.UserName, " ", "-"); 

     // Returns a boolean result if the current logged in user matches the 
     // details view of tBhe user in question. This is done so that we can 
     // show the edit button to logged in users. 
     _IsUserMatch = (currentuser.ID == user.ID); 


     // Grabs the users registration data and formats it to a <time> tag 
     // for use with the timeago jQuery plugin 
     _MemberSince = user.MemberSince; 

     // Grabs the users last activity and formats it to a <time> tag 
     // for use with the timeago jQuery plugin 
     _LastSeen = user.ActivityLogs.Reverse.FirstOrDefault.ActivityDate; 

     // Formats the users reputation to a comma Deliminated number 
     // IE: 19,000 or 123k 
     _Reputation = user.Reputation.ToShortHandNumber; 


     // Get the name of the users Default Region. 
     _Region = user.Region.Name.FirstOrDefault; 
    } 

} 

그리고 여기 내가 현재

public ActionResult Details(int id) 
{ 
    User user = _userService.GetUserByID(id); 

    if (user != null) { 
     Domain.ViewModels.UsersDetailsViewModel userviewmodel = new Domain.ViewModels.UsersDetailsViewModel(user); 
     return View(userviewmodel); 
    } else { 
     // Because of RESTful URL's, some people will want to "hunt around" 
     // for other users by entering numbers into the address. We need to 
     // gracefully redirect them to a not found page if the user doesn't 
     // exist. 
     throw new ResourceNotFoundException(); 
    } 

} 

은 어떻게 사용할 수 위의 뷰 모델을 활용하는 방법 (또는 내가 사용해야합니다) 당신은 아는 사용자 정의 처리를하는 동안 내 뷰 모델로 내 DomainModel를 매핑 AutoMapper를?

답변

38

맵을 작성하는 자동 모드에서는 대상 유형의 특정 구성원에 대해 추가 프로세스를 지정할 수 있습니다.

그래서 기본지도

Mapper.Map<Domain.User, UsersDetailsViewModel>(); 

가 더 복잡한 매핑을 정의하는 유창 구문이 될 것이다 :

Mapper.Map<Domain.User, UsersDetailsViewModel>() 
     .ForMember(vm=>vm.UserName, m=>m.MapFrom(u=>(u.UserName != null) 
               ? u.UserName 
               : "User" + u.ID.ToString())); 

여기 ForMember 두 개의 인수 첫 소요는 속성을 정의하는 당신을 님에게 매핑 중입니다. 두 번째 방법은 매핑을 정의하는 방법을 제공합니다. 예를 들어서 나는 껍질을 벗기고 쉬운 매핑 중 하나를 보여 주었다.

보다 어려운 매핑 (예 : CurrentUser 매핑)이 필요한 경우 IResolver 인터페이스를 구현하는 클래스를 만들고 매핑 논리를 해당 새 클러스터에 통합 한 다음 매핑에 추가 할 수 있습니다.

Mapper.Map<Domain.User, UsersDetailsViewModel>() 
    .ForMember(vm=>vm.IsUserMatch, m=>m.ResolveUsing<MatchingUserResolver>())); 

Mapper가 매핑을 수행하면 사용자 지정 해결 프로그램이 호출됩니다.

.ForMember 메소드의 구문을 발견하면 다른 모든 종류의 슬롯을 제자리에 배치합니다.

13

사용자 정의 매핑은 다음과 같은 코드로 (시작시) global.ascx에서 정의 할 수 있습니다 :

 AutoMapper.Mapper.CreateMap<Domain.User, UsersDetailsViewModel>() 
      .ForMember(o => o.Email, b => b.MapFrom(z => z.Email)) 
      .ForMember(o => o.UserName , b => b.MapFrom(user => (user.UserName != null) ? user.UserName : "User" + user.ID.ToString)); 

은() 메서드 BeforeMap를 통해 일부 초기화 할 수 있습니다. 그러나 당신은 당신의 뷰 모델을 약간 변경해야 할 수도 있습니다.

관련 문제