DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

SBOMs are essential to circumventing software supply chain attacks, and they provide visibility into various software components.

Related

  • GDPR Compliance With .NET: Securing Data the Right Way
  • How to Enhance the Performance of .NET Core Applications for Large Responses
  • Developing Minimal APIs Quickly With Open Source ASP.NET Core
  • Revolutionizing Content Management

Trending

  • Top Load Balancing Algorithms: Choosing the Right Strategy
  • Breaking Free from ZooKeeper: Why Kafka’s KRaft Mode Matters
  • Are Traditional Data Warehouses Being Devoured by Agentic AI?
  • The Agile Paradox
  1. DZone
  2. Coding
  3. Frameworks
  4. Creating vCard in ASP.NET Core

Creating vCard in ASP.NET Core

Create vCards in ASP.NET CORE for Outlook.

By 
Gunnar Peipman user avatar
Gunnar Peipman
·
Aug. 08, 19 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
11.7K Views

Join the DZone community and get the full member experience.

Join For Free

It’s time to get back to the old era of this blog and bring my vCard action result to today’s ASP.NET Core world. There’s support for images, so we can provide really good looking vCards from ASP.NET Core applications. This blog post gives a good base for custom vCard solutions in ASP.NET Core.

vCard Class

Previously, I built a vCard class to be a simple DTO-style class with a ToString() method that builds up a string output of vCard.

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 string GetFullName()    {        
    return FirstName + LastName;    }     
  
  public override string ToString()    {        
    var builder = new StringBuilder();        
    builder.AppendLine("BEGIN:VCARD");       
    builder.AppendLine("VERSION:2.1");         
    
    // Name        
    builder.Append("N:").Append(LastName)               
      .Append(";").AppendLine(FirstName);         
    
    // Full name        
    builder.Append("FN:").Append(FirstName)               
      .Append(" ").AppendLine(LastName);         
    
    // Address        
    builder.Append("ADR;HOME;PREF:;;").Append(StreetAddress)               
      .Append(";").Append(City).Append(";")               
      .Append(Zip).Append(";").AppendLine(CountryName);         
    
    // Other data        
    builder.Append("ORG:").AppendLine(Organization);        
    builder.Append("TITLE:").AppendLine(JobTitle);        
    builder.Append("TEL;WORK;VOICE:").AppendLine(Phone);        
    builder.Append("TEL;CELL;VOICE:").AppendLine(Mobile);        
    builder.Append("URL:").AppendLine(HomePage);        
    builder.Append("EMAIL;PREF;INTERNET:").AppendLine(Email);         
    
    // Image        
    if(Image != null) {           
      builder.AppendLine("PHOTO;ENCODING=BASE64;TYPE=JPEG:");            
      builder.AppendLine(Convert.ToBase64String(Image));            
      builder.AppendLine(string.Empty);        
    }         
    
    builder.AppendLine("END:VCARD");         
    return builder.ToString();    
  }
}


There are more attributes that vCard supports, but my code focuses on the most important ones. I left out others, as I have not needed these is practice over last 10 years. Those who need more attributes can take my code and add the ones they need.

vCard Action Result

Creating an action result for vCard is simple. Most of the dirty work is done in the ToString() method of vCard. Our action result must set response headers and write vCard to response stream.

public class vCardActionResult : IActionResult {    
  private readonly VCard _vCard;     
  
  public vCardActionResult(VCard vCard)    {        
    _vCard = vCard;    
  }     
  
  public async Task ExecuteResultAsync(ActionContext context)    {        
    var fileName = _vCard.GetFullName() + ".vcf";       
    var disposition = "attachment; filename=" + fileName;         
    var response = context.HttpContext.Response;        
    
    response.ContentType = "text/vcard";        
    response.Headers.Add("Content-disposition", disposition);         
    
    var bytes = Encoding.UTF8.GetBytes(_vCard.ToString());         
    await response.Body.WriteAsync(bytes, 0, bytes.Length);    
  }
}


Here is my sample controller action to download vCard.

public async Task<IActionResult> vCard() {    
  var vcard = new VCard();    
  vcard.FirstName = "Gunnar";    
  vcard.LastName = "Peipman";    
  vcard.Email = "[email protected]";    
  vcard.City = "Tallinn";    
  vcard.CountryName = "Estonia";    
  vcard.Phone = "00-12345";    
  vcard.Mobile = "00-10101";    
  vcard.Organization = "Freelancer";    
  vcard.JobTitle = "Chief Everything Office";     
  vcard.Image = await System.IO.File.ReadAllBytesAsync("gunnar300.jpg");     
  
  return new vCardActionResult(vcard);
}


My controller action works. When opening a downloaded vCard with Outlook, it shows a nice business card.

vCard open in Outlook

vCard open in Outlook


We have a working vCard solution, but it’s not yet very convenient to use.

Using vCard Action Result in Practice

The first annoying thing for me is creating a new instance of vCardActionResult in the controller action. ASP.NET Core action results can be often called by a special method. To follow the same pattern, I created my own base class for controllers.

public class BaseController : Controller {    
  public IActionResult VCard(VCard vCard)    {        
    return new vCardActionResult(vCard);    
  }
}


It’s simple, it’s primitive but it makes writing of vCard returning actions more intuitive.

public async Task<IActionResult> Download() {    
  var vcard = new VCard();    
  vcard.FirstName = "Gunnar";    
  vcard.LastName = "Peipman";    
  vcard.Email = "[email protected]";    
  vcard.City = "Tallinn";    
  vcard.CountryName = "Estonia";    
  vcard.Phone = "00-12345";    
  vcard.Mobile = "00-10101";    
  vcard.Organization = "Freelancer";    
  vcard.JobTitle = "Chief Everything Office";     
  vcard.Image = await System.IO.File.ReadAllBytesAsync("gunnar300.jpg");    
  
  return VCard(vcard);
}


The second annoying thing for me is the code that creates a VCard instance. It can be there in the controller, but I prefer to keep it somewhere else for reusability. Usually, vCard data comes from Customer, Person or Company classes. Let’s write a simple Customer class.

public class Customer {    
  public string FirstName { get; set; }    
  public string LastName { get; set; }    
  public string City { get; set; }    
  public string Country { get; set; }    
  public string Email { get; set; }    
  public string Mobile { get; set; }}


It’s up to the concrete solution to keep the following extension method that takes customer infomation and writes it to a vCard, but here’s the code.

public static class VCardExtensions {    
  public static VCard ToVCard(this Customer customer)    {        
    var vCard = new VCard();        
    vCard.City = customer.City;        
    vCard.CountryName = customer.Country;        
    vCard.Email = customer.Email;        
    vCard.Mobile = customer.Mobile;       
    vCard.FirstName = customer.FirstName;        
    vCard.LastName = customer.LastName;         
    
    return vCard;    
  }
}


Let’s rewrite the vCard controller action, so it uses the Customer class to get a step closer to real a scenario.

public async Task<IActionResult> vCard() {    
  var customer = new Customer    {        
    FirstName = "Gunnar",        
    LastName = "Peipman",        
    Email = "[email protected]",        
    Mobile = "0012345",        
    City = "Tallinn",        
    Country = "Estonia"    };     
  
  var vcard = customer.ToVCard();    
  vcard.Image = await System.IO.File.ReadAllBytesAsync("gunnar300.jpg");     
  
  return VCard(vcard);
}


This is how our vCard controller action looks in practice.

public async Task<IActionResult> Download(int id) {    
  var customer = await _dataContext.Customers                                     .FirstOrDefaultAsync(c => c.Id == id);     if(customer == null)    {        return NotFound();    }     var vcard = customer.ToVCard();    vcard.Image = await System.IO.File.ReadAllBytesAsync("gunnar300.jpg");     return VCard(vcard);}

About using base controller. Don’t create base controller only to have nice VCard() method. If your application already uses base controller then it’s safe to add vCard() method there. If you don’t have base controller and you don’t plan to use it then just create new instance of vCardActionResult in actions that return vCard.

Wrapping Up

It wasn't hard to take an old vCard action result and update it. We added a VCard() method to the base controller to make it more intuitive for other developers to return vCard from controller actions. To better support real scenarios, we created the ToVCard() extension method that converts our Customer domain class to vCard. This blog post is a good starting point for your own vCard solution in .NET Core.

The post Creating vCard in ASP.NET Core appeared first on Gunnar Peipman - Programming Blog.

ASP.NET ASP.NET Core

Published at DZone with permission of Gunnar Peipman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • GDPR Compliance With .NET: Securing Data the Right Way
  • How to Enhance the Performance of .NET Core Applications for Large Responses
  • Developing Minimal APIs Quickly With Open Source ASP.NET Core
  • Revolutionizing Content Management

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: