2011-07-01 12 views
7

से वस्तु बनाने के लिए अगर मैं निम्नलिखित वर्ग है:Automapper एक्सएमएल

class SPUser 
{ 
    public int ID { get; set; } 

    public string Name { get; set; } 
    public string LoginName { get; set; } 
    public string Email { get; set; } 

    public bool IsSiteAdmin { get; set; } 
    public bool IsSiteAuditor { get; set; } 
    public bool IsDomainGroup { get; set; } 

    public List<SPGroup> Groups { get; set; } 
} 

और मैं इस तरह के रूप SharePoint वेब सेवाओं, जो मेरी कक्षा पर एक संपत्ति के लिए एक विशेषता के साथ एक XML लौटने के लिए, का उपयोग कर रहा:

<Users> 
    <User Name="name" Description="desc" ..... /> 
</Users> 

क्या XML खंड को SPUser क्लास इंस्टेंस में मैप करने के लिए ऑटोमैपर का उपयोग करने का कोई तरीका है?

उत्तर

8

ब्लॉग हटा दिया गया है तय - यहाँ @DannyDouglass

करके पोस्ट का बिंग संग्रह है

सरल AutoMapper और Linq करने वाली Xml

साथ XML डेटा का उपयोग करना

मैं हाल ही में काम पर एक परिदृश्य में भाग गया जिसकी मैन्युअल रूप से कई एसओएपी वेब सेवाओं का उपभोग करने की आवश्यकता है, जो मुझे यकीन है कि आप कल्पना कर सकते हैं बल्कि एकान्त था। एक सहकर्मी (सेठ कार्नी) और मैंने कुछ अलग दृष्टिकोणों की कोशिश की, लेकिन हम अंततः एक समाधान पर बस गए जो एक्सएमएल की सरलीकृत खपत और आखिरकार कोड को अधिक टेस्टेबल बना दिया। एसओएपी संदेशों और हमारे द्वारा बनाए गए कस्टम अनुबंधों में लौटाए गए XElements (http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.aspx) के बीच एक लिंक बनाने के लिए एक ओपन सोर्स ऑब्जेक्ट-ऑब्जेक्ट मैपिंग टूल, ऑटोमैपर का लाभ उठाने के आसपास केंद्रित समाधान - एक पुन: प्रयोज्य तरीके से।

मैंने एक त्वरित डेमो लगाया जो दिखाता है कि आप ट्विटर पब्लिक टाइमलाइन (http://api.twitter.com/1/statuses/public_timeline.xml) (एपीआई के एक्सएमएल प्रतिक्रिया प्रकार का उपयोग करके) का उपभोग और प्रदर्शन करने के लिए एक ही दृष्टिकोण का उपयोग कैसे कर सकते हैं।

नोट: निम्न उदाहरण के लिए स्रोत कोड मेरी GitHub पृष्ठ पर पाया जा सकता है: https://github.com/DannyDouglass/AutoMapperXmlMappingDemo

  1. परियोजना सेटअप

हो रही एक बुनियादी MVC3 (डाउनलोड बीटा) परियोजना और बनाने के बाद संबंधित परीक्षण परियोजना, पहला कदम ऑटोमैपर पैकेज स्थापित करना था।मैं किसी भी ओपन सोर्स निर्भरताओं को स्थापित करने के लिए माइक्रोसॉफ्ट की हाल ही में घोषित पैकेज प्रबंधन प्रणाली NuGet का उपयोग कर रहा हूं। निम्न आदेश सभी कि मेरे MVC3 परियोजना में सेटअप AutoMapper की जरूरत थी था (NuGet यहाँ (http://weblogs.asp.net/scottgu/archive/2010/10/06/announcing-nupack-asp-net-mvc-3-beta-and-webmatrix-beta-2.aspx) और यहाँ (http://weblogs.asp.net/scottgu/archive/2010/10/06/announcing-nupack-asp-net-mvc-3-beta-and-webmatrix-beta-2.aspx) के बारे में अधिक पढ़ सकते हैं):

PM> add-package AutoMapper 
  1. मानचित्रण बनाना

ऑटोमैपर स्थापित के साथ मैं xml-to-object मैपिंग के लिए आवश्यक घटकों को बनाने शुरू करने के लिए तैयार हूं। - बस एक साधारण इकाई

public interface ITweetContract 
{ 
ulong Id { get; set; } 
string Name { get; set; } 
string UserName { get; set; } 
string Body { get; set; } 
string ProfileImageUrl { get; set; } 
string Created { get; set; } 
} 

यहाँ पागल कुछ भी नहीं है: पहला कदम एक त्वरित अपने आवेदन में इस्तेमाल किया ट्वीट वस्तु का प्रतिनिधित्व करने के अनुबंध पैदा कर रही है। ये सभी फ़ील्ड हैं जो कुछ क्षेत्रों के लिए एक अलग नाम का उपयोग कर ट्विटर एपीआई से प्रतिक्रिया में प्रदान की जाती हैं। सरल मामलों में जहां स्रोत और गंतव्य वस्तुओं में एक ही नाम आप सेटअप कर सकते हैं है में एक नक्शे के बहुत जल्दी इस सिंटैक्स का उपयोग:

Mapper.CreateMap<SourceObj, DestinationObj>(); 

हालांकि, AutoMapper Xml का समर्थन नहीं करता डिफ़ॉल्ट रूप से मैं क्षेत्रों है कि मैं हो जाएगा निर्दिष्ट करना मानचित्रण। ऑटोमैपर में फ़्लुएंट एपीआई का उपयोग करके मैं अपने फील्ड मैपिंग को चेन करने में सक्षम हूं। मेरे उदाहरण में मैप एक उदाहरण क्षेत्र पर एक नजर डालें - ट्वीट बॉडी:

Mapper.CreateMap<XElement, ITweetContract>() 
.ForMember(
    dest => dest.Body, 
    options => options.ResolveUsing<XElementResolver<string>>() 
     .FromMember(source => source.Element("text"))) 

यह पहली बार जटिल लग सकता है, लेकिन यह सब वास्तव में यहाँ क्या हो रहा है कि हम क्या मान का उपयोग करने पर AutoMapper करने के लिए विवरण प्रदान कर रहे हैं मेरे स्रोत ऑब्जेक्ट में और इसे गंतव्य ऑब्जेक्ट की संपत्ति पर कैसे मैप करना है।

options => options.ResolveUsing<XElementResolver<ulong>>() 
        .FromMember(source => source.Element("id"))) 

XElementResolver एक कस्टम मूल्य रिसोल्वर (http://automapper.codeplex.com/wikipage?title=Custom%20Value%20Resolvers) कि सेठ XmlElement स्रोत ऑब्जेक्ट को पार्स एक पुनः प्राप्त करने संभाल करने के साथ आया है: वहाँ एक विशेष लाइन मैं ऊपर शारीरिक क्षेत्र मानचित्रण में पर ध्यान केंद्रित करना चाहते हैं मानचित्रण में उपयोग के लिए दृढ़ता से टाइप मूल्य।

Mapper.CreateMap<XElement, ITweetContract>() 
.ForMember(
    dest => dest.Id, 
    options => options.ResolveUsing<XElementResolver<ulong>>() 
     .FromMember(source => source.Element("id"))) 
.ForMember(
    dest => dest.Name, 
    options => options.ResolveUsing<XElementResolver<string>>() 
     .FromMember(source => source.Element("user") 
      .Descendants("name").Single())) 
.ForMember(
    dest => dest.UserName, 
    options => options.ResolveUsing<XElementResolver<string>>() 
     .FromMember(source => source.Element("user") 
      .Descendants("screen_name").Single())) 
.ForMember(
    dest => dest.Body, 
    options => options.ResolveUsing<XElementResolver<string>>() 
     .FromMember(source => source.Element("text"))) 
.ForMember(
    dest => dest.ProfileImageUrl, 
    options => options.ResolveUsing<XElementResolver<string>>() 
     .FromMember(source => source.Element("user") 
      .Descendants("profile_image_url").Single())) 
.ForMember(
    dest => dest.Created, 
    options => options.ResolveUsing<XElementResolver<string>>() 
     .FromMember(source => source.Element("created_at"))); 
  1. जेनेरिक XElementResolver

यह कस्टम: मुझे लगता है कि एक पल में अधिक है, लेकिन इससे पहले कि हम अपना पूरा मानचित्रण पर एक नज़र डालें आगे बढ़ने विस्तार करेंगे मूल्य समाधानकर्ता वास्तविक कुंजी है जो इन XElement-to-Contract मानचित्रों को मूल समाधान में काम करने की अनुमति देती है। जैसा कि हमने उपरोक्त देखा है, मैंने इस उदाहरण में इस रिज़ॉल्यूवर का पुन: उपयोग किया है। यह सब है कि कस्टम समाधानकर्ता वर्ग बनाने के लिए जरूरी हो गया था था:

public class XElementResolver<T> : ValueResolver<XElement, T> 
{ 
protected override T ResolveCore(XElement source) 
{ 
    if (source == null || string.IsNullOrEmpty(source.Value)) 
     return default(T); 
    return (T)Convert.ChangeType(source.Value, typeof(T)); 
} 
} 

यह सामान्य XElementResolver उपयोग आसानी से ऊपर अपनी मैपिंग में लिया गया मान का प्रकार पारित करने के लिए अनुमति देता है। उदाहरण के लिए, निम्न सिंटैक्स दृढ़ता से() घोषणा से ऊपर क्रमांक क्षेत्र के .ForMember में XmlElement से लिया गया मान टाइप करने के लिए प्रयोग किया जाता है:

ResolveUsing<XElementResolver<ulong>>() 
मेरी मानचित्रण पूरी तरह से विन्यस्त और instantiated साथ

, मैं आह्वान करने के लिए तैयार हूँ उस नवीनतम सार्वजनिक टाइमलाइन को प्रदर्शित करने के लिए ट्विटर एपीआई और लीवरेज ऑटोमैपर।

  1. टुकड़े लाना एक साथ

मैं एक साधारण वर्ग ट्विटर एपीआई प्रतिक्रिया पुन: प्राप्त करने के लिए जिम्मेदार बनाया:

public class TwitterTimelineRetriever 
{ 
private readonly XDocument _twitterTimelineXml; 
public TwitterTimelineRetriever() 
{ 
    _twitterTimelineXml = XDocument 
     .Load("http://api.twitter.com/1/statuses/public_timeline.xml"); 
} 
public IEnumerable<ITweetContract> GetPublicTimeline(int numberOfTweets) 
{ 
    var tweets = _twitterTimelineXml.Descendants("status") 
     .Take(numberOfTweets); 
    return tweets.Select(Mapper.Map<XElement, ITweetContract>).ToList(); 
} 
} 

GetPublicTimeline विधि एक सरल तरीका है लौटने पर, आपने अनुमान लगाया है कि हमने पहले बनाए गए मानचित्र का लाभ उठाकर ट्विटर पब्लिक टाइमलाइन:

return tweets.Select(Mapper.Map<XElement, ITweetContract>).ToList(); 

मेरी MVC3 साइट की HomeController में मैं पुनः प्राप्ति विधि के लिए एक त्वरित कॉल कर सकते हैं, पिछले 10 परिणाम का अनुरोध:

public class HomeController : Controller 
{ 
private TwitterTimelineRetriever _twitterTimelineRetriever; 
public ActionResult Index() 
{ 
    _twitterTimelineRetriever = new TwitterTimelineRetriever(); 
    ViewModel.Message = "Twitter Public Timeline"; 
    return View(_twitterTimelineRetriever.GetPublicTimeline(10)); 
} 
} 

और अंत में, Microsoft से नए उस्तरा दृश्य इंजन का उपयोग कर मेरी दृश्य में एक छोटे से स्वरूपण के बाद, मैं मेरी सार्वजनिक टाइमलाइन प्रदर्शित हो रही है!

+6

ऑटोमैपर का उपयोग इस तरह के "ऑटो" का उपयोग कैसे कर रहा है, फिर मैन्युअल रूप से पीओसीओ में एक्सएमएल का उपयोग कर रहा है? – user2864740

7

इसके लिए आपको XML serialization in .NET की जांच करने की आवश्यकता है - यह किसी ऑब्जेक्ट को XML पर क्रमबद्ध करने या XML से deserialize करने का तरीका है।

ऑटोमैपर का उपयोग दो ऑब्जेक्ट्स के बीच गुण सेट करने के लिए किया जा सकता है - यह एक्सएमएल से बिल्कुल निपटता नहीं है।

अधिक संसाधन:

1

आप इस उद्देश्य से उपयोगकर्ता एक्सएमएल अक्रमांकन कर सकते हैं। .NET में हमारे पास XmlSerializer और DataContractSerializer

4

दिन में देर से बिट, लेकिन किसी ने XMLSerialization मार्ग को छोड़ने के बजाय एक्सएमएल को एक पॉको में मैप करने के लिए ऑटोमैपर का उपयोग किया है। मुझे निम्न ब्लॉग प्रविष्टि मिली: - Simplify Using Xml Data with AutoMapper and Linq-to-Xml

यह पर्याप्त है कि आप अपने सामान्य जेनरेट कस्टम रिज़ॉल्वर को लागू करने के लिए शुरू कर सकें यदि उदाहरण एक पर्याप्त नहीं है।

संपादित करें: तय लिंक संपादित करें: वास्तव में कड़ी

+0

ricardo - वह ब्लॉग प्रविष्टि बहुत उपयोगी थी। धन्यवाद!! –

+1

वह लिंक अब टूट गया है। यहां एक कामकाजी एक: http://dannydouglass.com/blog/2010/11/06/simplify-using-xml-data-with-automapper-and-linqtoxml/ – GFoley83

+1

@ GFoley83 आपका लिंक अब भी टूट गया है! –

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