JavaScript appears to be disabled. We recommend you enable JavaScript while visiting this site.

(All original content on this site is licensed under the Creative Commons License Attribution-Noncommercial-No Derivative Works 3.0.)

Installing WordPress 2.9.2 on Windows Server 2003 using Microsoft's Web Platform Installer

I recently had need to install and test WordPress for some possible work. While I was tempted to go the Linux route, shortly after the OS was setup I decided to skip that and stick with Windows. Since Microsoft has released a platform that supposedly makes it easy to install Web-related applications, I decided to give it a try to determine just how simple it was.

What follows is an overview of the setup process to install WordPress 2.9.2 on Windows Server 2003, using Microsoft's Web Platform Installer.

Web Platform Installer

The Microsoft Web Platform Installer can be downloaded from Microsoft.com and acts as middle-ground between all of the various applications that it covers, which is fairly robust (a full listing is available).

As you can see in Figure 1, WordPress is available along with a handful of other blogging applications. Upon selecting this and pressing Install, you're presented with the listing of dependencies and other applications that may be required (Figures 2, 3, and 4).

While I was going to install MySQL on a dedicated virtual machine, and was able to deselect that, for ease I've kept in selected here. At this time I'm not sure (yet) of how that would impact the installation process.

Since MySQL was being installed, I was prompted, right away before anything was downloaded, for an administrator password, as seen in Figure 5. Even though I thought I had everything installed for IIS, I was also prompted, as shown in Figure 6, for a Windows Server 2003 disc.

Figure 7 alludes to the fact that the individual requirements are downloaded and installed, moving right into the setup of any Web sites as required, as seen in Figure 8. In this case I kept the defaults. Additional WordPress setups are shown in Figures 9, 10, 11, and 12, where the database is setup. It's been a while since I've installed MySQL, so how this relates to that installation is unknown.

Once all components have been installed, you're presented with a nice little screen, like Figure 13. You can then launch WordPress and go through the setups necessary (Figures 14 and 15), log in (Figure 16) and view the administrative interface (Figure 17) and home page (Figure 18).

Thoughts on the Platform Installer

While I initially didn't think much of the installer, having actually used it, I'm pleasantly surprised. It's an extremely simple process, similar to how one might install applications through, say, Ubuntu.

It takes a lot of the guess-work out of the process, which is rather nice. On the other hand, while I can get going with WordPress at this point (and I was able to do my testing fairly quickly), the disadvantage of this is that I don't know any of the complexities of the setup process. I haven't installed WordPress (or PHP, or MySQL), but rather an installer has. But, I like the challenge of figuring things out on my own.

Which is why while I like the Installer, and will definitely use it when I need to quickly test something, for the most part I'll probably stick with old-fashioned methods of installation.

(All original content on this site is licensed under the Creative Commons License Attribution-Noncommercial-No Derivative Works 3.0.)

Connection String encryption (connectionString element) in ASP.NET

From what I've been able to determine, setting up an ODBC connection in Windows and using that for ASP.NET generally seems to be frowned upon. Instead, ASP.NET uses a Web.config file to store a number of settings, including all the connection strings you'll be using (whether you're using Windows authentication or user names and passwords).

For example:

<?xml version="1.0"?>
<configuration>
	<appSettings/>
	<connectionStrings>
		<add name="TestDatabase001Reader" connectionString="Data Source=192.168.56.102,1433;Initial Catalog=TestingDatabase001;User Id=DataReader;Password=DataReader" providerName="System.Data.SqlClient"/>
	</connectionStrings>
	<system.web>
		...
	</system.web>
</configuration>

However, it's also possible to store the connection strings in a completely different file by tweaking the connectionString in Web.config like so:

<connectionStrings configSource="ConnectionStrings.config">
</connectionStrings>

Then ConnectionStrings.config would be created and consist of the following:

<?xml version="1.0"?>
<connectionStrings>
	<add name="TestDatabase001Reader" connectionString="Data Source=192.168.56.102,1433;Initial Catalog=TestingDatabase001;User Id=DataReader;Password=DataReader" providerName="System.Data.SqlClient"/>
</connectionStrings>

The problem arises when the Web.config file is compromised, either by pushing it without a .config extension, sending it to someone else, or someone having browse access your Web site's directory. How do you encrypt these connection strings, and can you do so if you decide to store them in a separate file?

The following is how to verify that either way works just fine.

SqlConnectionEncryption.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SqlConnectionEncryption.aspx.cs" Inherits="WebApplication1.SqlConnectionEncryption" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>SQL Connection Encryption example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
		<asp:GridView ID="GridView1" runat="server">
		</asp:GridView>
		<div id="Options" runat="server"></div>
    </div>
    </form>
</body>
</html>

SqlConnectionEncryption.aspx.cs

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
using System.Web.Configuration;

namespace WebApplication1 {
	public partial class SqlConnectionEncryption : System.Web.UI.Page {
		protected void Page_Load(object sender, EventArgs e) {

			string action = Request.QueryString["action"];

			Options.InnerHtml = "";

			DataTable results = new DataTable();

			using (SqlConnection connection = new SqlConnection()) {
				connection.ConnectionString = ConfigurationManager.ConnectionStrings["TestDatabase001Reader"].ToString();
				SqlCommand command = new SqlCommand();
				command.Connection = connection;
				command.CommandText = "SELECT * FROM NameTable";
				command.CommandType = CommandType.Text;

				connection.Open();
				results.Load(command.ExecuteReader());
				connection.Close();
			}

			if (results.Rows.Count > 0) {
				GridView1.DataSource = results;
				GridView1.DataBind();
			}

			Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
			ConfigurationSection configSection = config.GetSection("connectionStrings");

			if (!configSection.SectionInformation.IsProtected) {
				configSection.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
				config.Save();
				Options.InnerHtml += "Configuration encrypted.<br />";
			} else {
				//configSection.SectionInformation.UnprotectSection();
				//config.Save();
				//Options.InnerHtml += "Configuration unencrypted.<br />";
				Options.InnerHtml += "Configuration already encrypted.<br />";
			}

			Options.InnerHtml += "Web configuration path: " + config.FilePath + "<br />";
			Options.InnerHtml += "Section path: " + configSection.ElementInformation.Source + "<br />";
			Options.InnerHtml += "<br />";
		}
	}
}

Depending upon your Web.config setup, you'll either see Web.config for both, or Web.config for one and ConnectionStrings.config for the other.

Tags:

Categories: tutorials/guides

(All original content on this site is licensed under the Creative Commons License Attribution-Noncommercial-No Derivative Works 3.0.)

Determine BlogEngine.NET comments that haven't been published - with LINQPad

At the beginning of the month I wrote a post on how to find BlogEngine.NET comments that had not yet been published/approved.

Having purchased a copy of LINQPad a short while ago (autocompletion costs, the program with all other functionality does not; give it a try if you develop in .NET - it's very cool), and having got slammed this morning with some spammer who had an hour to kill, I decided to adapt my code for LINQPad.

string postsDirectory = @"C:\posts";

string[] postFiles = System.IO.Directory.GetFiles(postsDirectory);

DataTable comments = new DataTable();
	comments.Columns.Add("Post");
	comments.Columns.Add("CommentApproved");
	comments.Columns.Add("FileId");
	comments.Columns.Add("IpAddress");

XDocument postXml;

foreach (string postFile in postFiles) {
	postXml = XDocument.Load(postFile);

	var posts = from postData in postXml.Descendants("post")
		select new {
			Title = postData.Element("title").Value,
			CommentItems = (from commentItems in postData.Element("comments").Elements("comment")
				select commentItems).ToList()
		};

	foreach (var post in posts) {
		if (post.CommentItems.Count > 0) {
			foreach (var commentItem in post.CommentItems) {
				if (commentItem.Attribute("approved") != null && commentItem.Attribute("approved").Value == "False") {
					DataRow comment = comments.NewRow();
					comment["Post"] = post.Title;
					comment["CommentApproved"] = commentItem.Attribute("approved").Value;
					comment["IpAddress"] = commentItem.Element("ip").Value;
					comment["FileId"] = "/post.aspx?id=" + System.IO.Path.GetFileNameWithoutExtension(postFile);
					comments.Rows.Add(comment);
				}
			}

		}
	}
}

postXml = null;

comments.Dump();

You'll want to change postsDirectory accordingly.

This will output all unapproved comments, the post they are associated with, the post GUID, and the commentor's IP address.

It's relatively easy to expand this to display more or less information, as desired. For example, website and author can be swapped in in place of ip in the last foreach.

Comments/questions/etcetera welcome and appreciated.