8 min read

Problem

This article, as stated in Introduction, is all about adding the Blogging feature to our site. This will handle creating and managing a post. It will also handle sending alerts to your friends’ filter page. And finally we will handle creating a friendly URL for your blog posts. Here we are making our first post to our blog:

ASP.NET Social Networks—Blogs in Fisharoo

Once our post is created, we will then see it on the Blogs homepage and the My Posts section. From here we can edit the post or delete it. Also, we can click into the post to view what we have seen so far.

ASP.NET Social Networks—Blogs in Fisharoo

The following screenshot shows what one will see when he/she clicks on the post:

ASP.NET Social Networks—Blogs in Fisharoo

I have the blog post set up to show the poster’s avatar. This is a feature that you can easily add to or remove. Most of your users want to be able to see who the author is that they are currently reading!

Also, we will add a friendly URL to our blog post’s pages.

ASP.NET Social Networks—Blogs in Fisharoo

Design

The design of this application is actually quite simple. We will only need one table to hold our blog posts. After that we need to hook our blog system into our existing infrastructure.

Blogs

In order for us to store our blog, we will need one simple table. This table will handle all the standard attributes of a normal blog post to include the title, subject, page name, and the post itself. It has only one relationship out to the Accounts table so that we know who owns the post down the road. That’s it!

ASP.NET Social Networks—Blogs in Fisharoo

Solution

Let’s take a look at the solution for these set of features.

Implementing the database

Let’s take a look at the tables required by our solution.

Blogs

The blogs table is super simple. We discussed most of this under the Blogs section.

ASP.NET Social Networks—Blogs in Fisharoo

The one thing that is interesting here is the Post column. Notice that I have this set to a varchar(MAX) field. This may be too big for your community, so feel free to change it down the road. For my community I am not overly worried. I can always add a UI restriction down the road without impacting my database design using a validation control. After that we will look at the IsPublished flag. This flag tells the system whether or not to show the post in the public domain. Next to that we will also be interested in the PageName column. This column is what we will display in the browser’s address bar. As it will be displayed in the address bar, we need to make sure that the input is clean so that we don’t have parsing issues (responsible for causing data type exceptions) down the road. We will handle that on the input side in our presenter later.

Creating the relationships

Once all the tables are created, we can then create all the relationships. For this set of tables we have relationships between the following tables:

  • Blogs and Accounts

Setting up the data access layer

To set up the data access layer follow the steps mentioned next:

  • Open the Fisharoo.dbml file.
  • Open up your Server Explorer window.
  • Expand your Fisharoo connection.
  • Expand your tables. If you don’t see your new tables try hitting the Refresh icon or right-clicking on tables and clicking Refresh.
  • Then drag your new tables onto the design surface.
  • Hit Save and you should now have the following domain objects to work with!

ASP.NET Social Networks—Blogs in Fisharoo

Keep in mind that we are not letting LINQ track our relationships, so go ahead and delete them from the design surface. Your design surface should have all the same items as you see in the screenshot (though perhaps in a different arrangement!).

Building repositories

With the addition of new tables will come the addition of new repositories so that we can get at the data stored in those tables. We will be creating the following repository to support our needs.

  • BlogRepository

Our repository will generally have a method for select by ID, select all by parent ID, save, and delete. We will start with a method that will allow us to get at a blog by its page name that we can capture from the browser’s address bar.

public Blog GetBlogByPageName(string PageName, Int32 AccountID)
{
Blog result = new Blog();
using(FisharooDataContext dc = _conn.GetContext())
{
result = dc.Blogs.Where(b => b.PageName == PageName &&
b.AccountID == AccountID).FirstOrDefault();
}
return result;
}

Notice that for this system to work we can only have one blog with one unique page name. If we forced our entire community to use unique page names across the community, we would eventually have some upset users. We want to make sure to enforce unique page names across users only for this purpose. To do this, we require that an AccountID be passed in with the page name, which gives our users more flexibility with their page name overlaps! I will show you how we get the AccountID later. Other than that we are performing a simple lambda expression to select the appropriate blog out of the collection of blogs in the data context.

Next, we will discuss a method to get all the latest blog posts via the GetLatestBlogs() method. This method will also get and attach the appropriate Account for each blog. Before we dive into this method, we will need to extend the Blog class to have an Account property.

To extend the Blog class we will need to create a public partial class in the Domain folder.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fisharoo.FisharooCore.Core.Domain
{
public partial class Blog
{
public Account Account { get; set; }
}
}

Now we can look at the GetLatestBlogs() method.

public List<Blog> GetLatestBlogs()
{
List<Blog> result = new List<Blog>();
using(FisharooDataContext dc = _conn.GetContext())
{
IEnumerable<Blog> blogs = (from b in dc.Blogs
where b.IsPublished
orderby b.UpdateDate descending
select b).Take(30);
IEnumerable<Account> accounts =
dc.Accounts.Where(a => blogs.Select(b =>
b.AccountID).Distinct().Contains(a.AccountID));
foreach (Blog blog in blogs)
{
blog.Account = accounts.Where(a => a.AccountID ==
blog.AccountID).FirstOrDefault();
}
result = blogs.ToList();
result.Reverse();
}
return result;
}

The first expression in this method gets the top N blogs ordered by their UpdateDate in descending order. This gets us the newest entries. We then add a where clause looking for only blogs that are published.

We then move to getting a list of Accounts that are associated with our previously selected blogs. We do this by selecting a list of AccountIDs from our blog list and then doing a Contains search against our Accounts table. This gives us a list of accounts that belong to all the blogs that we have in hand.

With these two collections in hand we can iterate through our list of blogs and attach the appropriate Account to each blog. This gives us a full listing of blogs with accounts.

As we discussed earlier, it is very important for us to make sure that we keep the page names unique on a per user basis. To do this we need to have a method that allows our UI to determine if a page name is unique or not. To do this we will have the CheckPageNameIsUnique() method.

public bool CheckPageNameIsUnique(Blog blog)
{
blog = CleanPageName(blog);
bool result = true;
using(FisharooDataContext dc = _conn.GetContext())
{
int count = dc.Blogs.Where(b => b.PageName == blog.PageName
&& b.AccountID == blog.AccountID).Count();
if(count > 0)
result = false;
}
return result;
}

This method looks at all the blog entries except itself to determine if there are other blog posts with the same page name that are also by the same Account. This allows us to effectively lock down our users from creating duplicate page names. This will be important down the road when we start to discuss our pretty URLs.

Next, we will look at a private method that will help us clean up these page name inputs. Keep in mind that these page names will be displayed in the browser’s address bar and therefore need not have any characters in them that the browser would want to encode. While we can decode the URL easily, this conversation is more about keeping the URL pretty so that the user and search engine spiders can easily read where they are at. When we have characters in the URL that are encoded, we will end up with something like %20 where %20 is the equivalent to a space. But to read my%20blog%20post is not that easy. It is much easier to ready my-blog-post. So we will strip out all of our so called special characters and replace all spaces with hyphens. This method will be the CleanPageName() method.

private Blog CleanPageName(Blog blog)
{
blog.PageName = blog.PageName.Replace(" ", "-").Replace("!", "")
.Replace("&", "").Replace("?", "").Replace(",", "");
return blog;
}

You can add to this as many filters as you like. For the time being I am replacing the handful of special characters that we have just seen in the code. Next, we will get into the service layers that we will use to handle our interactions with the system.

LEAVE A REPLY

Please enter your comment!
Please enter your name here