Creating a Blog in ASP.NET and C#


(This is an update of the Blog article from ASP.NET 1.0 to ASP.NET 2.0).  It also corrects the problem of displaying the most recent blog entry first)

Introduction

I still haven't gotten used to the name Blog. I can't even find it in the dictionary. For all I know its a coined word from the phrase "blind hog" or "blue fog". More likely it's coined from the words "bland pedagogue" or "blabbering monologue". If someone knows where this word originates, kindly add it to the blog you create from this article. Anyway, blogs seem to becoming pervasive and there is no end to people spilling their stream of consciousness onto the internet. This can make for some entertaining reading.  If you want to search for a blog in a particular area of interest, check out Google's new blog search

blog1.jpg

Figure 1 - ASP.NET Blog

Design

This is a very simple blog design consisting of two aspx web pages.  BlogList.aspx contains the blogs,  and BlogEntry.aspx allows you to enter your own blog comments. The blogs are persisted through a XML file which is read and written by a data set. Upon reading the data set,  the codebehind builds the blogs dynamically using a System.Web.UI.WebControls.Table.

bloguml.jpg

Figure 2 - UML Diagram of Blog Design Reverse Engineered using WithClass

Code

When the BlogList.aspx page starts, it calls the Page_Load method and initializes the page from the Comments.XML file and reads it into a data set.  The Session["Changed"] hash is used to track where the Page_Load originated from. If the Page_Load was triggered by a hyperlink, you don't need to append anything to the data set. If the Page_Load was triggered by a redirect from the BlogEntry.aspx page, then the data set will append the Session["Title"], Session["Blog"],  and Session["Name"] data to a new data set row.

Listing 1 - Upon initial entry into the BlogList.aspx page, load the Blog

        private void Page_Load(object sender, System.EventArgs e)
        {
           
// Put user code to initialize the page here
            if (IsPostBack)
            { 

            }
           
else
            {

                // initialize Blog and read it into a data set

                data set ds = ReadBlogIntoTable();

                 // if we created a new entry, append it to the BlogList
                // and save it to the xml file

                if ( (bool)Session["Changed"])
                {
                    AppendComments(ds);
                    WriteXmlComments(ds);
                    Session["Changed"] = false;
                }

 

                // Dynamically build the blog into a WebControls.Table

                RebuildTableView(ds);

            }

        }

The ReadBlogIntoTable method, reads the data set and data set structure from the Comments.Xml file.  If there is no file to read, then it simply constructs the data set structure. 

Our blog data set structure consists of 4 columns:  Name, Time, Title, and Blog.

Listing 2 - Reads the Blog into a DataSet or creates an empty DataSet structure if the File doesn't exist

private DataSet ReadBlogIntoTable()
        {
           
// construct the DataSet
            DataSet ds = new DataSet(); 

            // form the server path of the blog database
            string filename = Server.MapPath(".\\") + "comments.xml";

 

            // if the file exists, read  the blog database into the data set
            if (File.Exists(filename))
            {
                ds.ReadXml(filename);
            }
           
else
            {
               
// otherwise we need to create a new new in-memory
                // database table from scratch

                DataTable theTable = new DataTable("Comments");
                ds.Tables.Add(theTable);

                // add a name, time, title, and blog columns to our mock-up blog database

                theTable.Columns.Add("Name", Type.GetType("System.String"));
                theTable.Columns.Add("Time", Type.GetType("System.DateTime"));
                theTable.Columns.Add("Title", Type.GetType("System.String"));
                theTable.Columns.Add("Blog", Type.GetType("System.String"));
            } 

            return ds;

        }

If someone just entered a blog, we need to append it to the DataSet. This is accomplished by the AppendComments method. This method simply creates a new DataRow and assigns the new blog values to each column in the row. The row is then added into the DataSet. Finally the DataSet is written out to the Comments.XML file.

Listing 3 - Appending a Blog to the DataSet

       /// <summary>
        ///
  Append comments to xml file
        ///
</summary>
        ///
<param name="ds"></param>
        void AppendComments(DataSet ds)
        {
            // create a new DataRow

            DataRow dr = ds.Tables["Comments"].NewRow();

            // Populate the row from the text boxes filled by the user

            dr[0] = Session["Name"];
            dr[1] = DateTime.Now;
            dr[2] = Session["Title"];
            dr[3] = Session["Blog"];

            // add the row to the DataSet

            ds.Tables["Comments"].Rows.Add(dr);

          //  persist the blog in an xml file

            WriteXmlComments(ds);

        }

Once the data set is updated, we can render the contents of the data set onto the web page. We use the RebuildTableView method to create and populate the WebControls.Table dynamically from the data set. In this method, we loop through each row of the DataTable in the data set and create a new table row on the page. We can then copy the data row data into the individual cells of the web table row.

Listing 4 - Building the Blog on the Web Page

void RebuildTableView(DataSet ds)
        {
            string previousUser = ""; 
// track previous
 

            // loop through each row in the data set and create
            // the row on the web page in a web table

            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                   
// add title (use a single column)
                    TableRow tr = new TableRow();
                    tr.Cells.Add(new TableCell());

                     // change title color slightly
                    tr.Cells[0].ForeColor = Color.Navy;
                    tr.Cells[0].Width = 400;

                //  make the text title big and purple
                    tr.Cells[0].Text = "<FONT SIZE=5 COLOR=purple FACE=Rockwell><B>" + dr[2].ToString() + "</B></FONT>";
                    this.BlogTable.Rows.Add(tr);

                    // add blog in a single column and span 2 columns
                    tr = new TableRow();
                    tr.Cells.Add(new TableCell());
                    tr.Cells[0].Width = 550;
                    tr.Cells[0].ColumnSpan = 2;
                    tr.Cells[0].Text = dr[3].ToString();
                    this.BlogTable.Rows.Add(tr);

                    // add user who posted and date (use two columns in the row - one for poster, one for date)
                    tr = new TableRow();
                    tr.Height = 50;
                    tr.HorizontalAlign = HorizontalAlign.Left;
                    tr.VerticalAlign = VerticalAlign.Bottom;
                    tr.Cells.Add(new TableCell());
                    tr.Cells.Add(new TableCell());
                     tr.Cells[0].Text = "Posted by " + dr[0].ToString();

                    DateTime postTime = DateTime.Parse(dr[1].ToString());
                    tr.Cells[1].HorizontalAlign = HorizontalAlign.Right;
                    tr.Cells[1].Text = String.Format("<i>{0}</i>", postTime.ToString("MMM dd, 2005 @ hh:mm"));

                    this.BlogTable.Rows.Add(tr); 

                    // add separator graphic and span 2 columns

                    tr = new TableRow();
                    tr.Cells.Add(new TableCell());
                    tr.Cells.Add(new TableCell());
                    tr.Cells[0].ColumnSpan  = 2; 

                    this.BlogTable.Rows.Add(tr); 

                    string imageFile = this.ResolveUrl( @".\images\separator.jpg");
                    System.Web.UI.WebControls.Image separator = new System.Web.UI.WebControls.Image();

                    separator.ImageUrl = imageFile;
                    separator.Width = 600;
                    separator.Height = 32;
                    separator.Visible = true

                    tr.Cells[0].Controls.Add(separator);
                    tr.Cells[0].HorizontalAlign = HorizontalAlign.Center;

                }

        }

Blog Entry

Figure 3 illustrates the blog entry screen (BlogEntry.aspx) which is activated by hitting the Comments button on the BlogList.aspx web page. This allows the user to enter their blog and append it to the main blog page.

blogentry.jpg

Figure 3 - Blog Entry Web Page

Upon hitting the Submit button, the Session map is filled with the values entered and then we redirect the page to the BlogList.aspx page. We also set a Changed boolean flag in the Session to indicate that we came from the BlogList.aspx page rather than from some other page.

Listing 5 - Submitting your blog

private void btnSubmit_Click(object sender, System.EventArgs e)
        {
            // record the blog data in the Session State

            Session["Title"] = this.txtTitle.Text;
            Session["Blog"] = this.txtBlog.Text;
            Session["Name"] = this.txtName.Text;
            Session["Changed"] = true;

            // redirect back to the main blog page

            this.Response.Redirect("BlogList.aspx");
        }

Conclusion

Blogs are an interesting way to share your thoughts with the rest of the world. This blog application should get you started for your own web site in ASP.NET. One additional feature that you may want to add would be a user login page that allows someone to become a 'member' of your blog. Also, note that I turned off the validation request switch in this application so that you can post html tags to your blog. However, be forewarned that this may not be the most secure choice, so you can turn the validation back on by changing this line in the config file.

<pages validateRequest="false" />

to

<pages validateRequest="true" />

Enjoy creating your blogs, but don't get blogged down in the details, simply use this web application compliments of the power of ASP.NET!