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
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone >

ASP.NET Web API: Query String-Based Content Formatting

Gunnar Peipman user avatar by
Gunnar Peipman
·
Apr. 24, 12 · · Interview
Like (0)
Save
Tweet
5.46K Views

Join the DZone community and get the full member experience.

Join For Free

My previous post about Web API content negotiation showed how to add support for new content formats. As our API may have consumers who prefer query for data using GET requests we have to offer something for these dudes too. In this post I will show you how to make life easier for our Web API consumers by using query string mappings.

I will use media type mapping and formatter from my previous posting Extending content negotiation with new formats. We have to modify code a little bit because we need also single vCard download.

Media type formatter

Here is my media type formatter for vCard. It supports vCard format for single and multiple results. Multiple results are given to write method as IEnumerable<ContactModel>.

public class vCardMediaTypeFormatter : MediaTypeFormatter
{
    public vCardMediaTypeFormatter()
    {
        SupportedMediaTypes.Clear();
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/x-vcard"));
    }
 
    protected override bool CanWriteType(Type type)
    {
        return type == typeof(IEnumerable<ContactModel>) ||
               type == typeof(ContactModel);
    }
 
    protected override Task OnWriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext, TransportContext transportContext)
    {
        return Task.Factory.StartNew(() =>
        {
            if (type == typeof(ContactModel))
                WriteVCard((ContactModel)value, stream);
            else
                WriteVCard((IEnumerable<ContactModel>)value, stream);
        });
    }
 
    private void WriteVCard(ContactModel model, Stream stream)
    {
        var buffer = new StringBuilder();
        buffer.AppendLine("BEGIN:VCARD");
        buffer.AppendLine("VERSION:2.1");
        buffer.AppendFormat("N:{0};{1}\r\n", model.LastName, model.FirstName);
        buffer.AppendFormat("FN:{0} {1}\r\n", model.FirstName, model.LastName);
        buffer.AppendLine("END:VCARD");
 
        using (var writer = new StreamWriter(stream))
        {
            writer.Write(buffer);
        }
    }
 
    private void WriteVCard(IEnumerable<ContactModel> contactModels, Stream stream)
    {
        var enumerator = contactModels.GetEnumerator();
        while (enumerator.MoveNext())
        {
            WriteVCard(enumerator.Current, stream);
        }
    }
}

Query string mapping

Now let’s say to our web application that contacts API support vCard also with GET requests. QueryStringMapping class will help us out. We just add correctly initialized query string mapping to vCard media type formatter.

var vcard = new vCardMediaTypeFormatter();
vcard.MediaTypeMappings.Add(new VCardMediaTypeMapping());
vcard.MediaTypeMappings.Add(new QueryStringMapping("format", "vcard", "text/x-vcard"));
 
GlobalConfiguration.Configuration.Formatters.Add(vcard);

One thing to notice – we made no changes to our API to add support for vCards and query string mappings. Our API provides only functionality and it doesn’t make any decision about output formatting.

Testing query string

Now it’s time to test our query string mapping. We don’t mess with AJAX-requests anymore because we can conveniently use out browser. If I want to download contact that has ID value 11 over Web API I have to use the following query string:

http://my-app/api/contacts/11/?format=vcard

I will also open IE developer tools to monitor traffic. This is what was returned to browser:

Single vCard response

But now something weird happens – browser asks if we want to open vCard we just requested. Let’s say yes. Here is what you should see on the screen:

vCard opened on desktop

This is good example about how we can use our API in “mixed” mode. We can exchange data between systems but we can also let user to handle some results directly.

Conclusion

Our API can be consumed by different AJAX-clients but now we also made our API easier to use for guys who can easily make GET-requests. By example, PHP guys can use fopen() to make GET-request to our API
Web API Database ASP.NET

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • What Is Lean Software Development?
  • Why I'm Choosing Pulumi Over Terraform
  • Servlets Listeners Introduction and Examples
  • After Inspection, Comes Adaptation: How to Do Action-Based Retrospectives Right

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo