# Creating vCard with image in .Net

vCard is popular format for exchanging contacts. Besides e-mail clients also modern mobile phones are able to read and send contacts as vCard. This posting introduces same ideas how to implement vCard support in your applications and how to add images to vCards.

Our goal is make our system to output vCard like shown on image. We will write class for vCard and I give you some hints how to output those things in your web applications. These tips may be also useful for desktop applications.

I consider vCard as data transfer object(DTO). To make it simpler to use I use only properties of simple type so it is also possible to use them over web services. You can also use vCard as data contract between your application and domain model. How you implement vCard is up to you, I just help you get started.

### vCard class

My vCard class is simple. It contains some properties for vCard data and one method that outputs vCard in vCard format. I try to keep this code short, so forgive me father for all  documentation and other missing stuff and things implemented as dirty code.

public class VCard{    public string FirstName { get; set; }    public string LastName { get; set; }    public string Organization { get; set; }    public string JobTitle { get; set; }    public string StreetAddress { get; set; }    public string Zip { get; set; }    public string City { get; set; }    public string CountryName { get; set; }    public string Phone { get; set; }    public string Mobile { get; set; }    public string Email { get; set; }    public string HomePage { get; set; }    public byte[] Image { get; set; }    public override string ToString()    {        var builder = new StringBuilder();        builder.AppendLine("BEGIN:VCARD");        builder.AppendLine("VERSION:2.1");        // Name        builder.AppendLine("N:" + LastName + ";" + FirstName);        // Full name        builder.AppendLine("FN:" + FirstName + " " + LastName);        // Address        builder.Append("ADR;HOME;PREF:;;");        builder.Append(StreetAddress + ";");        builder.Append(City + ";;");        builder.Append(Zip + ";");        builder.AppendLine(CountryName);        // Other data        builder.AppendLine("ORG:" + Organization);        builder.AppendLine("TITLE:" + JobTitle);        builder.AppendLine("TEL;HOME;VOICE:" + Phone);        builder.AppendLine("TEL;CELL;VOICE:" + Mobile);        builder.AppendLine("URL;" + HomePage);        builder.AppendLine("EMAIL;PREF;INTERNET:" + Email);        builder.AppendLine("END:VCARD");        return builder.ToString();    }}

Using ToString() may be not a very good idea if you need to reserve default representation of vCard for user-interface output. Of course, there may be other considerations. You can rename this method to something else if you don’t want to use ToString() as name of method.

We have basic vCard now but we have no support for images. Let’s update VCard class so our friends can more easily match our name and face. It is specially useful for dudes who sit too much at computer and doesn’t meet their friends very often.

vCard may contain image in it. Of course, image must be encoded to text. Base64 encoding works well for us. I suppose you have code that outputs image as byte array. Of course, you can modify my code and use some other type to keep image data. I tried to keep VCard and its dependencies minimal.

// Add imagebuilder.AppendLine("PHOTO;ENCODING=BASE64;TYPE=JPEG:");builder.AppendLine(Convert.ToBase64String(Image));builder.AppendLine(string.Empty);

Add this code right before vCard line where VCARD:END is appended to builder. Note that after image we have to output two line breaks. Without them image is not shown.

### Testing output

Now let’s test VCard. We need to find out if it outputs data correctly or not. My test method is simple. I create new vCard, load image to it and then write it on my local hard disc. As a next thing I check out what Outlook thinks about my vCard.

public void Run(){    var myCard = new VCard    {        FirstName = "Gunnar",        LastName = "Peipman",        Organization = "Developers Team Ltd",        JobTitle = "n00b",        StreetAddress = "Tööstuse 48",        City = "Tallinn",        CountryName = "Estonia",        Phone = "343-23232",        Mobile = "232-67854",        Email = "gunnar@secret-address.com",        HomePage = "www.developers-team.com"    };    myCard.Image = File.ReadAllBytes("C:\\Images\\me.jpg");    using (var file = File.OpenWrite("C:\\Files\\me.vcf"))    using (var writer = new StreamWriter(file))    {        writer.Write(myCard.ToString());    }}

This time I am lucky. Okay, almost lucky. Outlook 2007 shows almost everything fine.The only exception is StreetAddress. We can see there characters that doesn’t match in UTF-8 and Windows-1257. But let’s solve this problem in next section.

Response.Clear();Response.ContentType = "text/vcard";var cardString = myCard.ToString();var inputEncoding = Encoding.Default;var outputEncoding = Encoding.GetEncoding("windows-1257");var cardBytes = inputEncoding.GetBytes(cardString);var outputBytes = Encoding.Convert(inputEncoding,                        outputEncoding, cardBytes);Response.OutputStream.Write(outputBytes, 0, outputBytes.Length);Response.End();

Before writing vCard to response stream we clean response buffer so it is empty and contains no surprises. We also convert card output to Windows-1257 character set so Outlook is able to understand it. We output vCard as byte array because in this case it is sure that web server cannot modify string encoding.

So, that’s it guys. Our vCards should work now as expected and if you move VCard class to some common library you are able to use it in more than one application.