How to create a vCard in .NET

Posted written by Paul Seal on November 10, 2021 .NET Framework

This is some sample code for you to adapt and make your own vcard.

In this example, we are calling a contact repository to load a contact model and we are using the properties of the contact to fill out the vcard.

We return the vCard bytes so they can be returned to the controller calling it for whichever purpose it needs.

    public static byte[] GetVCardBytes(string id, out string contactName)
    {
        contactName = "Unknown";
        var contact = new ContactsRepository().GetContact(id);
        if (contact == null) return null;
        contactName = contact.Name;
        var vCard = new StringBuilder();
        vCard.AppendLine("BEGIN:VCARD");
        vCard.AppendLine("VERSION:2.1");
        vCard.AppendLine($"N;LANGUAGE=en-gb:{contact.Name}");
        if (!string.IsNullOrWhiteSpace(contact.CompanyName))
        {
            vCard.AppendLine($"ORG:{contact.CompanyName}");
        }
        if (!string.IsNullOrWhiteSpace(contact.Title))
        {
            vCard.AppendLine($"TITLE:{contact.Title}");
        }
        if (!string.IsNullOrWhiteSpace(contact.Notes))
        {
            vCard.AppendLine($"NOTE:{contact.Notes}");
        }
        if (!string.IsNullOrWhiteSpace(contact.Mobile))
        {
            vCard.AppendLine($"TEL;CELL;VOICE:{contact.Mobile}");
        }
        vCard.AppendLine("X-MS-OL-DEFAULT-POSTAL-ADDRESS:0");
        if (!string.IsNullOrWhiteSpace(contact.Email))
        {
            vCard.AppendLine($"EMAIL;PREF;INTERNET:{contact.Email}");
        }
        vCard.AppendLine("END:VCARD");
        var vCardBytes = Encoding.UTF8.GetBytes(vCard.ToString());
        return vCardBytes;
    }

Next we have an ActionResult on a Surface Controller which calls the method and uses the bytes to return a file.

    public ActionResult DownloadVCard([FromUriAttribute] string id)
    {
        if (string.IsNullOrWhiteSpace(id)) return null;
        var vCardBytes = ContactsHandler.GetVCardBytes(id, out string contactName);
        if (vCardBytes == null || vCardBytes.Length == 0) return null;
        return File(vCardBytes, "text/calendar", contactName + ".vcf");
    }

And in the view we have a link like this:

    vCard: <a href="/umbraco/surface/ContactFinder/DownloadVCard/@item.AccountId">@item.Name</a>

I hope this helps you.