public void ReadProperty_String_QuotedPrintable() { const string encodedValue = "LABEL;" + "HOME;" + "ENCODING=QUOTED-PRINTABLE:" + "129 15th Street #3=0D=0A" + "Minneapolis, MN 55403=0D=0A" + "United States of America"; const string decodedValue = "129 15th Street #3\r\n" + "Minneapolis, MN 55403\r\n" + "United States of America"; vCardStandardReader reader = new vCardStandardReader(); // Read the property string. It should // be decoded by the reader. vCardProperty property = reader.ReadProperty(encodedValue); Assert.AreEqual( "LABEL", property.Name, "The name of the property should be LABEL."); Assert.IsTrue( property.Subproperties.Contains("HOME"), "The property should have a subproperty called HOME."); // Now for the big test. The loaded property // value should be decoded. It should not have the // quoted-printable escape sequences. Assert.AreEqual( decodedValue, property.ToString()); }
public void CanReadXmlvCard() { string xml = @"<?xml version=""1.0"" encoding=""utf-8""?> <vcards xmlns=""urn:ietf:params:xml:ns:vcard-4.0""> <vcard> <fn> <text>John Doe</text> </fn> <n> <surname><text>Doe</text></surname> <given><text>J.</text></given> </n> <email><text>[email protected]</text></email> <name><text>JohnDoe</text></name> <source><uri>http://www.somewhere.com</uri></source> <ex:why xmlns:ex=""http://here.net"">It is red</ex:why> <ex:where xmlns:ex=""http://here.net""> <uri>ldap://somefellow</uri> </ex:where> </vcard> </vcards>"; using (StringReader r = new StringReader(xml)) { vCardXmlReader reader = new vCardXmlReader(); vCard c = reader.Read(r, ParseExtensions); Assert.IsNotNull(c); Assert.AreEqual("John Doe", c.Fn.Default.Value); Assert.AreEqual("*****@*****.**", c.EMail.Default.Value); Assert.AreEqual("JohnDoe", c.Name); Assert.AreEqual("Doe", c.N.FamilyName); Assert.AreEqual("J.", c.N.GivenNames); Assert.AreEqual("http://www.somewhere.com", c.Source.Default.Value); vCardProperty p = c.GetExtendedProperty("why", "http://here.net"); Assert.IsNotNull(p); Assert.AreEqual("It is red", p.ToString()); } }
/// <summary> /// Reads the X-WAB-GENDER property. /// </summary> private void ReadInto_X_WAB_GENDER(vCard card, vCardProperty property) { // The X-WAB-GENDER property is a custom property generated by // Microsoft Outlook 2003. It contains the value 1 for females // or 2 for males. It is not known if other PIM clients // recognize this value. int genderId; if (int.TryParse(property.ToString(), out genderId)) { switch (genderId) { case 1: card.Gender = vCardGender.Female; break; case 2: card.Gender = vCardGender.Male; break; } } }
/// <summary> /// Reads the URL property. /// </summary> private void ReadInto_URL(vCard card, vCardProperty property) { vCardWebsite webSite = new vCardWebsite(); webSite.Url = property.ToString(); if (property.Subproperties.Contains("HOME")) webSite.IsPersonalSite = true; if (property.Subproperties.Contains("WORK")) webSite.IsWorkSite = true; card.Websites.Add(webSite); }
/// <summary> /// Reads the UID property. /// </summary> private void ReadInto_UID(vCard card, vCardProperty property) { card.UniqueId = property.ToString(); }
/// <summary> /// Reads a TZ property. /// </summary> private void ReadInto_TZ(vCard card, vCardProperty property) { card.TimeZone = property.ToString(); }
/// <summary> /// Reads the TITLE property. /// </summary> private void ReadInto_TITLE(vCard card, vCardProperty property) { // The TITLE property defines the job title of the // person. This should not be confused by the name // prefix (e.g. "Mr"), which is called "Title" in // some vCard-compatible software like Outlook. card.Title = property.ToString(); }
/// <summary> /// Reads the TEL property. /// </summary> private void ReadInto_TEL(vCard card, vCardProperty property) { vCardPhone phone = new vCardPhone(); // The full telephone number is stored as the // value of the property. Currently no formatted // rules are applied since the vCard specification // is somewhat confusing on this matter. phone.FullNumber = property.ToString(); if (string.IsNullOrEmpty(phone.FullNumber)) return; foreach (vCardSubproperty sub in property.Subproperties) { // If this subproperty is a TYPE subproperty // and it has a value, then it is expected // to contain a comma-delimited list of phone types. if ( (string.Compare(sub.Name, "TYPE", StringComparison.OrdinalIgnoreCase) == 0) && (!string.IsNullOrEmpty(sub.Value))) { // This is a vCard 3.0 subproperty. It defines the // the list of phone types in a comma-delimited list. // Note that the vCard specification allows for // multiple TYPE subproperties (why ?!). phone.PhoneType |= ParsePhoneType(sub.Value.Split(new char[] { ',' })); } else { // The other subproperties in a TEL property // define the phone type. The only exception // are meta fields like ENCODING, CHARSET, etc, // but these are probably rare with TEL. phone.PhoneType |= ParsePhoneType(sub.Name); } } card.Phones.Add(phone); }
/// <summary> /// Reads the PRODID property. /// </summary> private void ReadInto_PRODID(vCard card, vCardProperty property) { // The PRODID property contains the name of the // software that generated the vCard. This is not // a common property. Also note: this library // does not automatically generate a PRODID when // creating a vCard file. The developer can set // the PRODID (via the ProductId parameter) to // anything desired. card.ProductId = property.ToString(); }
/// <summary> /// Reads the PHOTO property. /// </summary> private void ReadInto_PHOTO(vCard card, vCardProperty property) { // The PHOTO property contains an embedded (encoded) image // or a link to an image. A URL (linked) image is supposed // to be indicated with the VALUE=URI subproperty. string valueType = property.Subproperties.GetValue("VALUE"); if (string.Compare(valueType, "URI", StringComparison.OrdinalIgnoreCase) == 0) { // This image has been defined as a URI/URL link, // rather than being encoded directly in the vCard. card.Photos.Add( new vCardPhoto(new Uri(property.ToString()))); } else { card.Photos.Add(new vCardPhoto((byte[])property.Value)); } }
/// <summary> /// Reads the NAME property. /// </summary> private void ReadInto_NAME(vCard card, vCardProperty property) { // The NAME property is used to define the displayable // name of the vCard. Because it is intended for display // purposes, any whitespace at the beginning or end of // the name is trimmed. card.DisplayName = property.ToString().Trim(); }
/// <summary> /// Reads the N property. /// </summary> private void ReadInto_N(vCard card, vCardProperty property) { // The N property defines the name of the person. The // propery value has several components, such as the // given name, family name, and suffix. This is a // core field found in almost all vCards. // // Each component is supposed to be separated with // a semicolon. However, some vCard writers do not // write out training semicolons. For example, the // last two components are the prefix (e.g. Mr.) // and suffix (e.g. Jr) of the name. The semicolons // will be missing in some vCards if these components // are blank. string[] names = property.ToString().Split(';'); // The first value is the family (last) name. card.FamilyName = names[0]; if (names.Length == 1) return; // The next value is the given (first) name. card.GivenName = names[1]; if (names.Length == 2) return; // The next value contains the middle name. card.AdditionalNames = names[2]; if (names.Length == 3) return; // The next value contains the prefix, e.g. Mr. card.NamePrefix = names[3]; if (names.Length == 4) return; // The last value contains the suffix, e.g. Jr. card.NameSuffix = names[4]; }
/// <summary> /// Reads the CLASS property. /// </summary> private void ReadInto_CLASS(vCard card, vCardProperty property) { if (property.Value == null) return; switch (property.ToString().ToUpperInvariant()) { case "PUBLIC": card.AccessClassification = vCardAccessClassification.Public; break; case "PRIVATE": card.AccessClassification = vCardAccessClassification.Private; break; case "CONFIDENTIAL": card.AccessClassification = vCardAccessClassification.Confidential; break; } }
/// <summary> /// Reads the CATEGORIES property. /// </summary> private void ReadInto_CATEGORIES(vCard card, vCardProperty property) { // The CATEGORIES value is expected to be a comma-delimited list. string[] cats = property.ToString().Split(new char[] { ',' }); // Add each non-blank line to the categories collection. foreach (string cat in cats) { if (cat.Length > 0) card.Categories.Add(cat); } }
/// <summary> /// Reads the BDAY property. /// </summary> private void ReadInto_BDAY(vCard card, vCardProperty property) { DateTime bday; if (DateTime.TryParse(property.ToString(), out bday)) { card.BirthDate = bday; } else { // Microsoft Outlook writes the birthdate in YYYYMMDD, e.g. 20091015 // for October 15, 2009. if (DateTime.TryParseExact( property.ToString(), "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out bday)) { card.BirthDate = bday; } else { card.BirthDate = null; } } }