September 28, 2012

Publishing content with AtomPub and ASP.NET Web API - Part 2

This is part 2 of a series of posts covering adding AtomPub support to ASP.NET Web API. You can read part 1 here.

In this post I cover how to publish content to the server using an AtomPub capable client.

You’ll find the example project on GitHub.

Publishing with Fude

The first client I want to cover is Fude. Since it follows the AtomPub specification to the letter and provides comprehensive error and HTTP logs, it was invaluable during testing.

To create an account in Fude you just need to specify a name, your Service Document Uri and authentication details.

Fude - Adding an Account

Fude will list the collections exposed by your service document. You can download and edit existing entries and of course create new entries:

Fude - POSTing a new entry

Fude also provides support for media and category resources (although my implementation doesn’t currently support them).

Publishing with Windows Live Writer

Of course the client you probably care about is Windows Live Writer. In my opinion, this is the best desktop blogging client available on Windows.

Unfortunately Windows Live Writer doesn’t quite follow the AtomPub specification to the letter. Specifically, it doesn’t send a valid media type when making requests to the AtomPub server. What it does send is the name of the client in the UserAgent header. I therefore created a simple message handler that checks to see if a request is from Windows Live Writer and sets the correct media type:

public class WLWMessageHandler : DelegatingHandler
{
    private const string WLWUserAgent = "Windows Live Writer 1.0";

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Headers.UserAgent != null &&
            request.Headers.UserAgent.Any(a => a.Comment != null && a.Comment.Contains(WLWUserAgent)))
        {
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/atom+xml"));
        }

        return base.SendAsync(request, cancellationToken);
    }
}

We can now work with our AtomPub server using Windows Live Writer. I think this is a better solution than including the format in the url (either by querystring or extension).

Windows Live Writer supports automatic discovery by including a link to your service document in the <head> of your page:

<link rel="service" 
	  type="application/atomsvc+xml" 
	  href="http://localhost:56592/api/services" 
	  class="preferred" />

The images below cover the process of connecting Windows Live Writer to the AtomPub server:

Creating your Account

Creating your Account

If you’re not using authentication (like the example project) just enter anything here.

Creating your Account

Now let’s open an existing post on the server and make some changes.

Updating a post

Updating a post

After publishing, I can verify the changes by navigating to the API directly (JSON):

{
    "Title": "My Post Feed",
    "Author": "John Doe",
    "Posts": [
        {
            "Id": 1,
            "Title": "Hello AtomPub!",
            "Slug": "hello-atom",
            "Summary": "",
            "ContentType": "html",
            "Content": "<p>Hello there!</p> <p>Hi, I’m WLWing all the things.</p> ",
            "Tags": [
                "AtomPub",
                "ASP.NET Web API"
            ],
            "PublishDate": "2012-09-28T11:44:00Z",
            "LastUpdated": "2012-09-28T10:13:04.3778013Z",
            "Links": [
                {
                    "Rel": "self",
                    "Href": "http://localhost:56592/api/posts/1",
                    "Title": null
                },
                {
                    "Rel": "edit",
                    "Href": "http://localhost:56592/api/posts/1",
                    "Title": null
                }
            ]
        }
    ]
}

So there you have it, you can now publish to your ASP.NET Web API using your favourite blogging client. Lovely.

© 2022 Ben Foster