2012-02-03 37 views
14

Tôi đã có một ViewModel lấy một số dữ liệu Mô hình và hơi thay đổi nó.Cách xử lý các thuộc tính tùy chỉnh trong AutoMapper

Cách tôi đang thực hiện "hoạt động" vì tôi chỉ cần chuyển số DomainModel tới hàm dựng cho ViewModel, nhưng vì tôi đang sử dụng AutoMapper trên một số Chế độ xem một đối một của mình, tôi nghĩ tôi muốn hãy thử và tìm hiểu cách thực hiện ánh xạ trên tất cả các Chế độ xem.

Dưới đây là ví dụ về một ViewModel có thêm một chút.

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; 
    } 

} 

Và dưới đây là cách tôi hiện đang sử dụng các ViewModel trên

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(); 
    } 

} 

Làm thế nào tôi có thể sử dụng (hay tôi nên sử dụng) AutoMapper để lập bản đồ DomainModel tôi để ViewModel của tôi trong khi làm việc xử lý tùy chỉnh mà bạn nhìn thấy ở trên không?

Trả lời

38

Trên trình tự động nơi bạn tạo Bản đồ, bạn có thể chỉ định quy trình bổ sung cho các thành viên cụ thể của loại đích.

Vì vậy, nơi bản đồ mặc định của bạn sẽ là

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

có một cú pháp thông thạo để xác định ánh xạ phức tạp hơn:

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

Ở đây ForMember mất hai luận cứ là người đầu tiên xác định tài sản mà bạn đang ánh xạ tới. Thứ hai cung cấp một phương tiện xác định ánh xạ. Đối với một ví dụ tôi đã copped ra và hiển thị một trong những ánh xạ dễ dàng.

Nếu bạn yêu cầu ánh xạ khó hơn, (ví dụ như ánh xạ người dùng hiện tại), bạn có thể tạo một lớp thực hiện giao diện IResolver, kết hợp logic ánh xạ của bạn trong các bản sao mới và sau đó thêm vào bản đồ.

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

khi Mapper đến lập bản đồ, nó sẽ gọi trình phân giải tùy chỉnh của bạn.

Sau khi bạn khám phá cú pháp của phương pháp .ForMember, mọi thứ khác sẽ được đặt vào vị trí.

13

lập bản đồ tùy chỉnh có thể được định nghĩa trong global.ascx (lúc khởi động) bằng cách mã sau:

 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)); 

bạn có thể làm một số khởi tạo qua BeforeMap() phương pháp. Nhưng bạn có thể cần phải thực hiện một số thay đổi trong mô hình chế độ xem của mình.

Các vấn đề liên quan