2013-02-19 110 views

回答

0

OK,我发现这一点:

我们使用个WindowsRuntimeStreamExtensions类的System.IO流到 的Windows.Storage.Streams转换对象:

System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(VCardDataString)); 
IInputStream input= System.IO.WindowsRuntimeStreamExtensions.AsInputStream(ms); 
        ContactInformation info = await ContactInformation.ParseVcardAsync(input); 
        StoredContact phoneContact = new StoredContact(store, info); 
2

我用这个类

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.Collections.Specialized; 
using System.Collections.ObjectModel; 
using System.Text.RegularExpressions; 

namespace aaa 
{ 
    /// <summary> 
    /// Container class for vCard properties of vCard 2.1. 
    /// Considering current implementation of vCard support in MS Outlook, MS Outlook Express, Yahoo Mail and Eudora etc., 
    /// the following properties and attributes are not supported: 
    /// * Photo 
    /// * Address labels 
    /// * Delivery address types 
    /// * Mailer 
    /// * Timezone 
    /// * EMail types 
    /// * Sound 
    /// * Public key 
    /// * Extensions 
    /// * Geo 
    /// 
    /// So this vCard implementation is expected to be compatible with standard vCard fields of the vCard generated by these programs. 
    /// </summary> 
    public class VCard 
    { 
     readonly char[] lineBreak = { '\n', '\r' }; 
     #region Singlar Properties 

     private string formattedName; 

     public string FormattedName 
     { 
      get { return formattedName; } 
      set { formattedName = value.TrimEnd(lineBreak); } 
     } 

     string surname; 
     public string Surname 
     { 
      get { return surname; } 
      set { surname = value.TrimEnd(lineBreak); } 
     } 

     private string givenName; 

     public string GivenName 
     { 
      get { return givenName; } 
      set { givenName = value.TrimEnd(lineBreak); } 
     } 
     private string middleName; 

     public string MiddleName 
     { 
      get { return middleName; } 
      set { middleName = value.TrimEnd(lineBreak); } 
     } 

     private string prefix; 

     public string Prefix 
     { 
      get { return prefix; } 
      set { prefix = value.TrimEnd(lineBreak); } 
     } 
     private string suffix; 

     public string Suffix 
     { 
      get { return suffix; } 
      set { suffix = value.TrimEnd(lineBreak); } 
     } 

     private string title; 

     public string Title 
     { 
      get { return title; } 
      set { title = value.TrimEnd(lineBreak); } 
     } 

     private DateTime bday; 

     public DateTime Birthday 
     { 
      get { return bday; } 
      set { bday = value; } 
     } 

     private DateTime rev = DateTime.MinValue; 
     /// <summary> 
     /// If Rev in vCard is UTC, Rev will convert utc to local datetime. 
     /// </summary> 
     public DateTime Rev 
     { 
      get { return rev; } 
      set { rev = value; } 
     } 

     private string org; 

     public string Org 
     { 
      get { return org; } 
      set { org = value.TrimEnd(lineBreak); } 
     } 

     private string department; 

     public string Department 
     { 
      get { return department; } 
      set { department = value.TrimEnd(lineBreak); } 
     } 


     private string note; 

     public string Note 
     { 
      get { return note; } 
      set { note = value.TrimEnd(lineBreak); } 
     } 

     private string role; 

     public string Role 
     { 
      get { return role; } 
      set { role = value.TrimEnd(lineBreak); } 
     } 


     #endregion 


     #region Property Collections with attribute 

     private Collection<Address> addresses = new Collection<Address>(); 

     public Collection<Address> Addresses 
     { 
      get { return addresses; } 
      set { addresses = value; } 
     } 

     private Collection<PhoneNumber> phones = new Collection<PhoneNumber>(); 

     public Collection<PhoneNumber> Phones 
     { 
      get { return phones; } 
      set { phones = value; } 
     } 

     private Collection<EmailAddress> emails = new Collection<EmailAddress>(); 

     public Collection<EmailAddress> Emails 
     { 
      get { return emails; } 
      set { emails = value; } 
     } 

     private Collection<URL> urls = new Collection<URL>(); 

     public Collection<URL> URLs 
     { 
      get { return urls; } 
      set { urls = value; } 
     } 


     #endregion 

    } 
    /// <summary> 
    /// Read text and create data fields of collections. 
    /// 
    /// When testing, please be aware the following facts: 
    /// vCard standard has been around for more than 10 years, and widely accpeted by the industries. However, 
    /// the implementations from different vendors are a bit buggy, resulting data corruption during data exchanges. 
    /// For example 
    /// 1. MS Outlook 2003 can handle Unicode. When exporting to vCard, non-ASCII characters are encoded into QuotedPrintable over UTF8, 
    /// however, when importing, Outlook will fail to import those characters. 
    /// 2. Yahoo has similar problem. In additon, Rev in Yahoo vCard is not DateTime, a bit doggy. 
    /// 
    /// These applications just can not eat their own dog food. So when you are testing the exchanges of vCard, keep these facts in mind. 
    /// </summary> 
    public class VCardReader 
    { 
     const string regxLine = @"((?<strElement>[^\;^:]*) ((;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE)))|(;CHARSET=UTF-?8)|(;[\w]*))* (:(?<strValue> (([^\n\r]*=[\n\r]+)*[^\n\r]*[^=][\n\r]*))))"; 
     const string regxN = @"(?<strElement>(N)) ((;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE)))|(;CHARSET=UTF-?8))* (:(?<strSurname>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))(;(?<strGivenName>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))? (;(?<strMidName>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))? (;(?<strPrefix>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))? (;(?<strSuffix>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))?"; 
     const string regxFN = @"(?<strElement>(FN))((;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE)))|(;CHARSET=UTF-?8))* (:(?<strFN>(([^\n\r]*=[\n\r]+)*[^\n\r]*[^=][\n\r]*)))"; 
     const string regxTitle = @"(?<strElement>(TITLE))((;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE)))|(;CHARSET=UTF-?8))* (:(?<strTITLE>[^\n\r]*))"; 
     const string regxOrg = @"(?<strElement>(ORG)) ((;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE)))|(;CHARSET=UTF-?8))* (:(?<strORG>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))(;(?<strDept>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))?"; 
     const string regxAdr = @"(?<strElement>(ADR)) (;(?<strAttr>(HOME|WORK)))?((;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE)))|(;CHARSET=UTF-?8))*(:(?<strPo>([^;]*))) (;(?<strBlock>([^;]*))) (;(?<strStreet>([^;]*))) (;(?<strCity>([^;]*))) (;(?<strRegion>([^;]*))) (;(?<strPostcode>([^;]*)))(;(?<strNation>(([^;^\n\r]*(=\n\r)?)*[^;^\n\r]*[^;]*(\n\r)?)))"; 
     const string regxNote = @"((?<strElement>(NOTE)) ((;CHARSET=UTF-?8)|(;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE))))* (:(?<strValue> (([^\n\r]*=[\n\r]+)*[^\n\r]*[^=][\n\r]*))))"; 
     const string regxRole = @"(?<strElement>(ROLE)) ((;(ENCODING=)?(?<strAttr>(QUOTED-PRINTABLE)))|(;CHARSET=UTF-?8))* (:(?<strROLE>(([^\n\r]*=[\n\r]+)*[^\n\r]*[^=][\n\r]*)))"; 
     /// <summary> 
     /// Analyze vCard text into vCard properties. 
     /// </summary> 
     /// <param name="vCardText">vCard text.</param> 
     /// <returns>vCard object.</returns> 
     public static VCard ParseText(string vCardText) 
     { 
      VCard v = new VCard(); 
      RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace; 

      Regex regex; 
      Match m; 
      MatchCollection mc; 

      // NameValueCollection vCardLines = new NameValueCollection(); 
      regex = new Regex(regxLine, options); 
      MatchCollection matches = regex.Matches(vCardText); 

      foreach (Match match in matches) 
      { 
       string ss; 

       string vCardLine = match.Value; 
       switch (match.Groups["strElement"].Value) 
       { 
        case "FN": 
         regex = new Regex(regxFN, options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
         { 
          if (m.Groups["strAttr"].Value == "QUOTED-PRINTABLE") 
           v.FormattedName = QuotedPrintable.Decode(m.Groups["strFN"].Value); 
          else 
           v.FormattedName = m.Groups["strFN"].Value; 
         } 
         break; 
        case "N": 
         regex = new Regex(regxN, options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
         { 
          if (m.Groups["strAttr"].Value == "QUOTED-PRINTABLE") 
          { 
           v.Surname = QuotedPrintable.Decode(m.Groups["strSurname"].Value); 
           v.GivenName = QuotedPrintable.Decode(m.Groups["strGivenName"].Value); 
           v.MiddleName = QuotedPrintable.Decode(m.Groups["strMidName"].Value); 
           v.Prefix = QuotedPrintable.Decode(m.Groups["strPrefix"].Value); 
           v.Suffix = QuotedPrintable.Decode(m.Groups["strSuffix"].Value); 
          } 
          else 
          { 
           v.Surname = m.Groups["strSurname"].Value; 
           v.GivenName = m.Groups["strGivenName"].Value; 
           v.MiddleName = m.Groups["strMidName"].Value; 
           v.Prefix = m.Groups["strPrefix"].Value; 
           v.Suffix = m.Groups["strSuffix"].Value; 
          } 

         } 
         break; 
        case "TITLE": 
         regex = new Regex(regxTitle, options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
         { 
          if (m.Groups["strAttr"].Value == "QUOTED-PRINTABLE") 
           v.Title = QuotedPrintable.Decode(m.Groups["strTITLE"].Value); 
          else 
           v.Title = m.Groups["strTITLE"].Value; 
         } 
         break; 
        case "ORG": 
         regex = new Regex(regxOrg, options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
         { 
          if (m.Groups["strAttr"].Value == "QUOTED-PRINTABLE") 
          { 
           v.Org = QuotedPrintable.Decode(m.Groups["strORG"].Value); 
           v.Department = QuotedPrintable.Decode(m.Groups["strDept"].Value); 
          } 
          else 
          { 
           v.Org = m.Groups["strORG"].Value; 
           v.Department = m.Groups["strDept"].Value; 
          } 

         } 
         break; 
        case "BDAY": 
         regex = new Regex(@"(?<strElement>(BDAY)) (:(?<strBDAY>[^\n\r]*))", options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
         { 
          string bdayStr = m.Groups["strBDAY"].Value; 
          if (!String.IsNullOrEmpty(bdayStr)) 
          { 
           string[] expectedFormats = { "yyyyMMdd", "yyMMdd", "yyyy-MM-dd" }; 
           v.Birthday = DateTime.ParseExact(bdayStr, expectedFormats, null, System.Globalization.DateTimeStyles.AllowWhiteSpaces); 
          } 
         } 
         break; 
        case "REV": 
         regex = new Regex(@"(?<strElement>(REV)) (;CHARSET=utf-8)? (:(?<strREV>[^\n\r]*))", options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
         { 
          string revStr = m.Groups["strREV"].Value; 
          if (!String.IsNullOrEmpty(revStr)) 
          { 
           string[] expectedFormats = { "yyyyMMddHHmmss", "yyyyMMddTHHmmssZ" }; 
           v.Rev = DateTime.ParseExact(revStr, expectedFormats, null, System.Globalization.DateTimeStyles.AllowWhiteSpaces); 
          } 
         } 
         break; 
        case "EMAIL": 
         regex = new Regex(@"((?<strElement>(EMAIL)) ((;(?<strPref>(PREF))))* (;[^:]*)* (:(?<strValue>[^\n\r]*)))", options); 
         mc = regex.Matches(vCardLine); 
         if (mc.Count > 0) 
         { 
          for (int i = 0; i < mc.Count; i++) 
          { 
           EmailAddress email = new EmailAddress(); 
           v.Emails.Add(email); 
           m = mc[i]; 
           email.Address = m.Groups["strValue"].Value; 

           if (m.Groups["strPref"].Value == "PREF") 
            email.Pref = true; 
          } 
         } 

         break; 
        case "TEL": 
         regex = new Regex(@"((?<strElement>(TEL)) ((;(?<strType>(VOICE|CELL|PAGER|MSG|FAX)))| (;(?<strAttr>(HOME|WORK)))| (;(?<strPref>(PREF)))?)* (:(?<strValue>[^\n\r]*)))", options); 
         mc = regex.Matches(vCardLine); 
         if (mc.Count > 0) 
         { 
          for (int i = 0; i < mc.Count; i++) 
          { 
           PhoneNumber phone = new PhoneNumber(); 
           v.Phones.Add(phone); 
           m = mc[i]; 
           phone.Number = m.Groups["strValue"].Value; 
           ss = m.Groups["strAttr"].Value; 
           if (ss == "HOME") 
            phone.HomeWorkTypes = HomeWorkTypes.HOME; 
           else if (ss == "WORK") 
            phone.HomeWorkTypes = HomeWorkTypes.WORK; 

           if (m.Groups["strPref"].Value == "PREF") 
            phone.Pref = true; 

           CaptureCollection types = m.Groups["strType"].Captures; 
           foreach (Capture capture in types) 
           { 
            switch (capture.Value) 
            { 
             case "VOICE": 
              phone.PhoneTypes |= PhoneTypes.VOICE; 
              break; 
             case "CELL": phone.PhoneTypes |= PhoneTypes.CELL; 
              break; 
             case "PAGER": phone.PhoneTypes |= PhoneTypes.PAGER; 
              break; 
             case "MSG": phone.PhoneTypes |= PhoneTypes.MSG; 
              break; 
             case "FAX": phone.PhoneTypes |= PhoneTypes.FAX; 
              break; 
            } 
           } 

          } 
         } 
         break; 
        case "ADR": 
         regex = new Regex(regxAdr, options); 
         mc = regex.Matches(vCardLine); 
         if (mc.Count > 0) 
         { 
          for (int i = 0; i < mc.Count; i++) 
          { 
           Address address = new Address(); 
           v.Addresses.Add(address); 
           m = mc[i]; 
           ss = m.Groups["strAttr"].Value; 
           if (ss == "HOME") 
            address.HomeWorkType = HomeWorkTypes.HOME; 
           else if (ss == "WORK") 
            address.HomeWorkType = HomeWorkTypes.WORK; 

           if (m.Groups["strAttr"].Value == "QUOTED-PRINTABLE") 
           { 
            address.POBox = QuotedPrintable.Decode(m.Groups["strPo"].Value); 
            address.Ext = QuotedPrintable.Decode(m.Groups["strBlock"].Value); 
            address.Street = QuotedPrintable.Decode(m.Groups["strStreet"].Value); 
            address.Locality = QuotedPrintable.Decode(m.Groups["strCity"].Value); 
            address.Region = QuotedPrintable.Decode(m.Groups["strRegion"].Value); 
            address.Postcode = QuotedPrintable.Decode(m.Groups["strPostcode"].Value); 
            address.Country = QuotedPrintable.Decode(m.Groups["strNation"].Value); 
           } 
           else 
           { 
            address.POBox = m.Groups["strPo"].Value; 
            address.Ext = m.Groups["strBlock"].Value; 
            address.Street = m.Groups["strStreet"].Value; 
            address.Locality = m.Groups["strCity"].Value; 
            address.Region = m.Groups["strRegion"].Value; 
            address.Postcode = m.Groups["strPostcode"].Value; 
            address.Country = m.Groups["strNation"].Value; 
           } 

          } 
         } 
         break; 
        case "NOTE": 
         regex = new Regex(regxNote, options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
         { 
          if (m.Groups["strAttr"].Value == "QUOTED-PRINTABLE") 
           v.Note = QuotedPrintable.Decode(m.Groups["strValue"].Value); 
          else 
           v.Note = m.Groups["strValue"].Value; 
         } 
         break; 
        case "URL": 
         regex = new Regex(@"((?<strElement>(URL)) (;*(?<strAttr>(HOME|WORK)))? (:(?<strValue>[^\n\r]*)))", options); 
         mc = regex.Matches(vCardLine); 
         if (mc.Count > 0) 
         { 
          for (int i = 0; i < mc.Count; i++) 
          { 
           URL url = new URL(); 
           v.URLs.Add(url); 
           m = mc[i]; 
           url.Address = m.Groups["strValue"].Value; 
           ss = m.Groups["strAttr"].Value; 
           if (ss == "HOME") 
            url.HomeWorkTypes = HomeWorkTypes.HOME; 
           else if (ss == "WORK") 
            url.HomeWorkTypes = HomeWorkTypes.WORK; 
          } 
         } 

         break; 
        case "ROLE": 
         regex = new Regex(regxRole, options); 
         m = regex.Match(vCardLine); 
         if (m.Success) 
          v.Role = m.Groups["strROLE"].Value; 
         break; 


       } 
      } 

      return v; 
     } 



    } 
} 

与此代码

using Microsoft.Phone.Controls; 
using Microsoft.Phone.Shell; 
using Microsoft.Phone.Tasks; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Navigation; 

namespace aaa 
{ 

    public partial class SaveContactPage : PhoneApplicationPage 
    { 
     string vcard = ""; 

     SaveContactTask saveContactTask = new SaveContactTask(); 

     public SaveContactPage() 
     { 
      InitializeComponent(); 
      saveContactTask.Completed += new EventHandler<SaveContactResult>(saveContactTask_Completed); 
     } 

     protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) 
     { 
      base.OnNavigatedTo(e); 
      if (NavigationContext.QueryString.TryGetValue("vcard", out vcard)) 
      { 

       TextBox.Text = ""; 
       VCard vc = VCardReader.ParseText(vcard); 

       saveContactTask.FirstName = vc.GivenName; 
       saveContactTask.LastName = vc.Surname; 

       TextBox.Text += "FullName: "; 
       TextBox.Text += saveContactTask.FirstName + saveContactTask.LastName; 
       TextBox.Text += Environment.NewLine; 

       for (int i = 0; i < vc.Phones.Count; i++) 
       { 
        //TextBox.Text += "Phone " + vc.Phones[i].PhoneTypes.ToString("G") + " " + vc.Phones[i].HomeWorkTypes.ToString() + (vc.Phones[i].Pref ? "Preferred" : "") + "=" + vc.Phones[i].Number + Environment.NewLine; 

        if (vc.Phones[i].HomeWorkTypes.ToString() == "None") 
        { 
         TextBox.Text += "Mobile Phone: "; 
         saveContactTask.MobilePhone = vc.Phones[i].Number; 
         TextBox.Text += saveContactTask.MobilePhone; 
         TextBox.Text += Environment.NewLine; 
        } 
        if (vc.Phones[i].HomeWorkTypes.ToString() == "WORK") 
        { 
         TextBox.Text += "Work Phone: "; 
         saveContactTask.WorkPhone = vc.Phones[i].Number; 
         TextBox.Text += saveContactTask.WorkPhone; 
         TextBox.Text += Environment.NewLine; 
        } 
        if (vc.Phones[i].HomeWorkTypes.ToString() == "HOME") 
        { 
         TextBox.Text += "Home Phone: "; 
         saveContactTask.HomePhone = vc.Phones[i].Number; 
         TextBox.Text += saveContactTask.HomePhone; 
         TextBox.Text += Environment.NewLine; 
        } 
       } 

       for (int i = 0; i < vc.Emails.Count; i++) 
       { 
        //TextBox.Text += "Email " + " " + (vc.Emails[i].Pref ? "Preferred" : "") + "=" + vc.Emails[i].Address + Environment.NewLine; 
        saveContactTask.PersonalEmail = vc.Emails[i].Address; 
        TextBox.Text += saveContactTask.PersonalEmail; 
        TextBox.Text += Environment.NewLine; 
       } 

       /* 
       if (!String.IsNullOrEmpty(vc.Prefix)) 
        TextBox.Text += "Prefix=" + vc.Prefix + Environment.NewLine; 
       if (!String.IsNullOrEmpty(vc.Prefix)) 
        TextBox.Text += "Suffix=" + vc.Suffix+ Environment.NewLine; 

       if (vc.Birthday > DateTime.MinValue) 
        TextBox.Text += "Birthday=" + vc.Birthday.ToLongDateString() + Environment.NewLine; 
       if (vc.Rev != null) 
        TextBox.Text += "Rev=" + vc.Rev.ToLongDateString()+" "+vc.Rev.ToLongTimeString() + Environment.NewLine; 

       if (!String.IsNullOrEmpty(vc.Org)) 
        TextBox.Text += "Org=" + vc.Org + Environment.NewLine;    

       for (int i = 0; i < vc.URLs.Count; i++) 
       { 
        TextBox.Text += "URL " + vc.URLs[i].HomeWorkTypes.ToString() + " " + "=" + vc.URLs[i].Address + Environment.NewLine; 
       } 

       for (int i = 0; i < vc.Addresses.Count; i++) 
       { 
        TextBox.Text += "Address " + vc.Addresses[i].HomeWorkType.ToString() + "=" + vc.Addresses[i].POBox + "," 
        + vc.Addresses[i].Ext + ", " 
        + vc.Addresses[i].Street + ", " 
        + vc.Addresses[i].Locality + ", " 
        + vc.Addresses[i].Region + ", " 
        + vc.Addresses[i].Postcode + ", " 
        + vc.Addresses[i].Country + Environment.NewLine; 
       } 

       if (!String.IsNullOrEmpty(vc.Note)) 
        TextBox.Text += "Note="+vc.Note; 


       TextBox.Text += "=============================" + Environment.NewLine; 
       */ 
       } 
      } 

     void saveContactTask_Completed(object sender, SaveContactResult e) 
     { 
      switch (e.TaskResult) 
      { 
       //Logic for when the contact was saved successfully 
       case TaskResult.OK: 
        MessageBox.Show("Contact saved."); 
        break; 

       //Logic for when the task was cancelled by the user 
       case TaskResult.Cancel: 
        MessageBox.Show("Save cancelled."); 
        break; 

       //Logic for when the contact could not be saved 
       case TaskResult.None: 
        MessageBox.Show("Contact could not be saved."); 
        break; 
      } 
     } 

     private void Button_Click_1(object sender, RoutedEventArgs e) 
     { 
      try 
      { 
       saveContactTask.Show(); 
      } 
      catch (System.InvalidOperationException ex) 
      { 
       MessageBox.Show("An error occurred."); 
      } 
     } 


    } 


} 

希望这有助于