Knowledge is power. We love to share it.

News related to Mono products, services and latest developments in our community.

mzilic

Using the BlogSpot API in ASP.NET

09/08/2012Categories: MonoX, ASP.NET

Introduction

Recently I was asked to extend the default MonoX functionality by pushing blogs posts from a MonoX-based project to BlogSpot.

Blogger is a free tool that allows you to create personal blogs. These blogs are hosted for free on blogspot.com. BlogSpot has a basic WYSIWYG editor and a rudimantary support for tags. MonoX, on the other hand, supports categories, multiple blogs, has a feature rich WYSIWYG editor, and more.

Since MonoX has more features than BlogSpot, we could only push the blog title, content and the tags into it.

Using the API

You need to download the Google Data API from here. Please make sure that you have the version 2.1 version or later. Older versions have a bug related to tags which in turn does not allow you to properly sync tags.

When you install the Google Data API you can find your references in the X:\Program Files\Google\Google Data API SDK directory. You will need the Google.GData.Client.dll, Google.GData.Extensions.dll and Google.GData.Blogger.dll.

Authorization

There are a couple of ways to connect with someone’s BlogSpot account. You can ask the user for his username and password, or use OAuth 2.0. In this sample we're going to use the simple username and password approach. I highly recommend that you use the OAuth 2.0 approach in the real-world scenarios. My colleagues explained this procedure in more depth so you can read their posts for more information: Using Google Photos API in ASP.NET and Using Google Docs API in ASP.NET.

Using the API

Pushing or updating a blog post

For my implementation I've created a simple data transfer object (DTO) to handle the Blogger data. Here is how it looks:

public string BlogSelfUrl { get; private set; }
public string Title { get; set; }
public string Content { get; set; }
public List<string> Tags { get; set; }
public bool IsPublished { get; set; }
 
public BlogPostDTO()
    : this(string.Empty)
{
 
}
public BlogPostDTO(string blogId)
{
    this.BlogSelfUrl = blogId;
}

Please note the BlogSelfUrl, which is basically a BlogId. Using it, you can fetch an existing blog entry or delete a blog entry. Now let's take a look at the actual method which posts or updates a blog post:

public bool PostOrUpdateBlogPost(BlogPostDTO blog, bool isUpdate)
{
    if (blog != null)
    {
        var service = new Google.GData.Client.Service(blogKeyName, this.BlogName);
        service.Credentials = new GDataCredentials(this.Username, this.Password);
        AtomEntry newPost = null;
        if (isUpdate)
        {
            try
            {
                newPost = service.Get(blog.BlogSelfUrl);
                newPost.Categories.Clear();
            }
            catch (Exception ex)
            {
                // error handling goes here
                return false;
            }
        }
        else
        {
            newPost = new AtomEntry();
        }
        newPost.IsDraft = !blog.IsPublished;
        if (blog.Tags != null && blog.Tags.Count > 0)
        {
            foreach (var tag in blog.Tags)
            {
                AtomCategory atomCategory = new AtomCategory();
                atomCategory.Scheme = blogTagScheme;
                atomCategory.Term = tag;
                newPost.Categories.Add(atomCategory);
            }
        }
        newPost.Title.Text = blog.Title;
        newPost.Content = new AtomContent();
        newPost.Content.Content = blog.Content;
        newPost.Content.Type = blogHTMLType;
        try
        {
            if (!isUpdate)
            {
                Uri blogPostUri = this.SelectUserBlog(service);
                newPost = service.Insert(blogPostUri, newPost);
            }
            else
            {
                newPost = newPost.Update();
            }
            return newPost != null;
        }
        catch (Exception ex)
        {
            // error handling goes here                   
        }
    }
    return false;
}
Deleting a blog post

Deleting a blog post requires you to store the BlogSelfUrl for later usage as we can use it as a BlogId. Deleting a blog is also a very straightforward process; here is how you can do that:

public bool DeleteBlogPost(string blogId)
{
    var service = new Google.GData.Client.Service(blogKeyName, this.BlogName);
    service.Credentials = new GDataCredentials(this.Username, this.Password);
    bool isDeleted = false;
    if (!string.IsNullOrWhiteSpace(blogId))
    {
        try
        {
            Uri uri = new Uri(blogId);
            service.Delete(uri);
            isDeleted = true;
        }
        catch (Exception ex)
        {
            // error handling goes here
            isDeleted = false;
        }
    }
    return isDeleted;
}
Fetching a list of blog posts

We can also fetch a list of blog posts. The BloggerAgent which you can download at the bottom of this post allows you to specify the amount of blog posts you want to fetch from the BlogSpot. Here is the code which fetches a list of blog posts:

public List<BlogPostDTO> GetBlogList()
{
    var service = new Google.GData.Client.Service(blogKeyName, this.BlogName);
    service.Credentials = new GDataCredentials(this.Username, this.Password);
    Uri blogPostUri = null;
    try
    {
        blogPostUri = this.SelectUserBlog(service);
    }
    catch (Exception ex)
    {
        // error handling goes here               
        return new List<BlogPostDTO>();
    }
    List<BlogPostDTO> blogs = new List<BlogPostDTO>();
    FeedQuery query = new FeedQuery();
    query.Uri = blogPostUri;           
    query.NumberToRetrieve = this.NumberOfBlogsToShow;
    AtomFeed feed = null;
    try
    {
        feed = service.Query(query);
    }
    catch (Exception ex)
    {
        // error handling goes here
        return new List<BlogPostDTO>();
    }           
    foreach (AtomEntry entry in feed.Entries)
    {
        BlogPostDTO blog = new BlogPostDTO(entry.SelfUri.Content);
        if (entry.Categories != null && entry.Categories.Count > 0)
        {
            blog.Tags = new List<string>();
            foreach (var item in entry.Categories)
            {
                blog.Tags.Add(item.Term);
            }
        }
        blog.Title = entry.Title.Text;
        blog.Content = entry.Content.Content;
        blog.IsPublished = !entry.IsDraft;
        blogs.Add(blog);
    }
    return blogs;
}

MonoX implementation

Let's see what would be required to push blogs posted from the MonoX platform into the BlogSpot. The following scenario applies to projects which are built on top of MonoX. To push a blog post to the BlogSpot we need to override several MonoX controls and listen for the BlogPostEdit control's BlogPostSaved event. From this point on, it will be very easy to adapt the code explained previously in your custom MonoX projects.

1. You need to inherit the BlogContainer.ascx Web part and copy its markup; we also need to listen for the BlogPostSaved event. Here is how we can do that:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    blogPostEdit.BlogPostSaved += new EventHandler(blogPostEdit_BlogPostSaved);
}
 
void blogPostEdit_BlogPostSaved(object sender, EventArgs e)
{
    var postedBlog = MonoSoftware.MonoX.Repositories.BlogRepository.GetInstance().GetBlogPost(blogPostEdit.IdentityId);
    // insert logic to push to BlogSpot here using the approach we described previously
}

2. You need to inherit the Blog.aspx and copy its markup. Remember to change the path in the Blog.aspx to point towards your custom BlogContainer.ascx control.

3. Change the web.config URL rewriting rules to point towards your custom Blog page.

Conclusion

This article demonstrated you how you can post, update or delete a blog post on the BlogSpot service. It also shows how to fetch a list of blog posts from BlogSpot and integrate it with your custom MonoX projects.

I am attaching a sample project which demonstrates the techniques described in this article.

Rated 4.00, 6 vote(s).