2012-02-03 17 views
14

में कस्टम प्रॉपर्टी को कैसे संभालें I have ViewModel है जो कुछ मॉडल डेटा लेता है और थोड़ा इसे बदल देता है।ऑटोमैपर

तरह से मैं यह कर रहा हूँ "काम" के बाद से मैं सिर्फ ViewModel के लिए निर्माता को DomainModel गुजरती हैं, लेकिन जब से मैं अपने एक-से-एक ViewModels में से कुछ पर AutoMapper उपयोग कर रहा हूँ, मैंने सोचा कि मैं था कोशिश करें और जानें कि सभी ViewModels में मैपिंग कैसे करें।

यहां एक व्यूमोडेल का एक उदाहरण है जो थोड़ा अतिरिक्त करता है।

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

} 

और यहाँ कैसे मैं वर्तमान में ऊपर ViewModel

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

} 

मैं का उपयोग कैसे कर सकते हैं का उपयोग (या मैं का उपयोग करना चाहिए) AutoMapper जब तुम ऊपर देखें कस्टम प्रसंस्करण कर मेरी ViewModel करने के लिए अपने DomainModel मैप करने के लिए?

उत्तर

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 दो तर्क पहले लेता संपत्ति को परिभाषित करता है कि आप मैपिंग कर रहे हैं दूसरा मैपिंग को परिभाषित करने का साधन प्रदान करता है। उदाहरण के लिए मैंने कॉपी किया है और आसान मैपिंग में से एक दिखाया है।

यदि आपको अधिक कठिन मैपिंग की आवश्यकता होती है, (जैसे आपका वर्तमान यूज़र मैपिंग) आप एक कक्षा बना सकते हैं जो आईरसॉल्वर इंटरफेस लागू करता है, तो उस नए क्लोज़ में अपने मैपिंग तर्क को शामिल करें और फिर इसे मैपिंग में जोड़ें।

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

जब मैपर मैपिंग करने के लिए आता है तो यह आपके कस्टम रिज़ॉल्वर का आह्वान करेगा।

एक बार जब आप .MMember विधि के सिंटैक्स को खोज लेंगे तो बाकी सब कुछ जगहों पर स्लॉट्स।

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 के माध्यम से कुछ प्रारंभ कर सकते हैं। लेकिन आपको अपने व्यूमोडेल में कुछ बदलाव करने की आवश्यकता हो सकती है।

संबंधित मुद्दे