.NET Discussion

.NET Issues, Problems, Code Samples, and Fixes

BlogEngine.NET: How To Customize Your Blog With New Class Objects

I’ve been working pretty extensively with BlogEngine.NET over the past few months and have learned a lot about its inner workings. My project (www.madcowultimate.com) has essentially used the BlogEngine.NET platform (connected to a MySQL database) as a base to create a full-fledged website. Of course, all of the customization I’ve done to the core would mean that I am stuck with this version (1.4.5.0) of the platform, but so far I am okay with that. It serves my purposes for the most part, and everything else I can make work to fit my needs.

One of the major parts of customizing the core to shape the BE.NET platform into your custom solution is creating your own business classes. For instance, in my site, I needed a way for my teammates to check the status of practice, since some of them come in from out of town and would probably prefer to know if practice is on or off for that day before driving in. Thus, I created the Practice class in the BlogEngine.Core namespace to populate a widget displaying the status.

How did I do this? Well, I wish it was as easy as 1, 2, 3, but this project is a little more complex than that. I have definitely learned a lot by wading through the code, but I have also made some mistakes and wasted some time trying things out that did not work. I will break it down for you into manageable chunks, but you will still need to know certain things, like SQL (or MySQL), data table architecture, how classes and objects fundamentally work, and a little bit about inheritance and abstraction.

The following will assume that you have successfully created your blog on your webserver and that you are hooked up to a database (I will use MySQL in this example). I would highly recommend you back up your entire project before embarking on any changes that may affect your blog (especially changes to the core).

First things first, open BE.NET in Visual Studios and expand BlogEngine.Core. You should see a list of familiar-looking classes like Post.cs, Page.cs, and Category.cs. To create your own class, you will essentially need to model your class after these. Right-click on BlogEngine.Core and go to Add > Class… and type the name for your new class. For the purposes of this article, we’ll call it MyObject.cs.

At the top where you import classes, you will need to add at least “using BlogEngine.Core.Providers”, in addition to any other classes you will need (you can, of course, add any you need later). This will make it easier to hook your object up to the data provider. Next, put your object in the “BlogEngine.Core” namespace and have your object inherit the BusinessBase, like so:

namespace BlogEngine.Core
{
public class MyObject: BusinessBase
{
}
}

Inheriting the BusinessBase will do a lot of your work for you when it comes to managing your object, like knowing which properties have been changed and saving your data. Next you’ll want to create your constructor. You won’t use this very frequently (more on that later), but you still need to have it:

public MyObject(int id)
{
base.Id = id;
}

After this, create whatever properties you need using the following template:

private bool _myproperty;
public bool MyProperty
{
get { return _myproperty; }
set
{
if (value != _myproperty) MarkChanged(“MyProperty”);
_myproperty= value;
}
}

This alerts the BusinessBase when something has been changed so that it may take the appropriate action when you need to save your data. You can (and should) also create a read-only ID property by just returning the base ID:

public int MyObjectID
{
get { return Id; }
}

Of course you may create your own methods if you would like, but they are not required. The last step in your basic class construction is to override the base methods for data retrieval/storage/deletion. These are abstract methods delineated by the BusinessBase you inherited, so they are required by your class. When you are done, they should look like this:

protected override void ValidationRules()
{
//nothing
}

protected override MyObject DataSelect(int id)
{
return BlogService.SelectMyObject(id);
}

protected override void DataUpdate()
{
BlogService.UpdateMyObject(this);
}

protected override void DataInsert()
{
if (IsNew)
BlogService.InsertMyObject(this);
}

protected override void DataDelete()
{
BlogService.DeleteMyObject(this);
}

You may have noticed at this point that your Intellisense isn’t coming up with the methods “SelectMyObject” or “UpdateMyObject” when you type in BlogService. This is because we need to add them to your BlogService class. This class is created to separate data access and business so any kind of data provider can be used without any change to how the class functions, therefore making it extremely flexible.

Before you modify your BlogService.cs class, you will need to add the abstract methods to your BlogProvider.cs class, which is in the “Providers” folder. This is where you create the outline for the methods you just outlined in your class. You probably can do this before the last step in your class construction (so that Intellisense will show up, thereby preventing any typos) but it’s not necessary so long as you’re keeping track of what you’re doing. Go ahead and add the following somewhere in that class file:

public abstract MyObject SelectMyObject(int id);
public abstract void InsertMyObject(MyObject obj);
public abstract void UpdateMyObject(MyObject obj);
public abstract void DeleteMyObject(MyObject obj);

This will create the framework for data access to your object that will be inherited by the respective providers.

Now go ahead and open your BlogService.cs class located in the “Providers” folder. Don’t worry too much about what is going on here, just know that a lot of work has been done on your behalf so that it is this simple (two lines of code!) to hook up your object to your data provider of choice per action required by your object. If you really want to look, expand the region in this file called “Provider Model” and look at the details. When you’re done adding your static methods for your object, it should look something like this:

public static MyObject SelectMyObject(int id)
{
LoadProviders();
return _provider.SelectMyObject(id);
}

public static void InsertMyObject(MyObject obj)
{
LoadProviders();
_provider.InsertMyObject(obj);
}

public static void UpdateMyObject(MyObject obj)
{
LoadProviders();
_provider.UpdateMyObject(obj);
}
public static void DeleteMyObject(MyObject obj)
{
LoadProviders();
_provider.DeleteMyObject(obj);
}

Finally, once all your structures are completed, you’ll need to add the actual functionality to your data access. This is done in the DbBlogProvider.cs file, also located in the “Providers” folder. As you will see, because this class inherits the BlogProvider class, it is mandatory that it include (and provide the behavior for) the methods you just described in the BlogProvider.cs. This becomes most obvious when you start typing your methods and Intellisense finishes the rest of your method signature.

This is the point at which you should start creating your data tables that are going to be accessed and modified by your blog, as you will need to know what tables to access and what fields to call in your SQL string!

After you have created your tables, you should go back to the DbBlogProvider file and create a region for your object’s data access methods and start filling them in with the appropriate SQL. Since I don’t know what your objects requirements are, I can’t really help you any further than this, other than to tell you to take a look at how other objects’ data is being accessed for the same behavior (for example, look at how a post is selected, inserted, updated, and deleted) and model yours off of theirs. This part probably takes the longest, since you need to know what to get and how to get it, but if you follow the other objects’ examples, you’ll see that you can benefit from a lot of copy and paste action.

After you complete all of your data access functions, you’re pretty much done! Now, how do you get an instance of the object you just built? Not in the typical manner, which would be to use the “new” keyword, but rather using the BusinessBase’s static .Load() function, or MyObject.Load(id);. Of course, once you’re done modifying the core, don’t forget to build it (right-click on BlogEngine.Core > Build)! If you get any errors, be sure to fix them, as your project will not work until the Core can compile.

I’m somewhat certain this covers the basic complexity involved in the creation of a new, custom object. I hope this saves someone some time! I wish I had known this before going into this project, as I know it would have saved me a lot of time and figuring out. Good luck, and let me know if I forgot anything, as I will gladly add it.

kick it on DotNetKicks.com

Advertisements

September 30, 2008 Posted by | ASP.NET, BlogEngine.NET, C#, MySQL, Tips & Tricks, Visual Studio.NET | , , , , | 2 Comments

Google Chrome: First Bug

I like to be an early adopter of new technologies, so when Google Chrome came out, naturally I downloaded it.  There are many features I liked, including the quickness of loading and the ability to turn my Gmail into an application.  However, there are still some problems that need to be ironed out, and until they do, I will not be using this browser for anything at all, save development (yeah, thanks for another browser to check. Ugh).

First of all, Google Chrome isn’t actually a new rendering browser; it’s essentially Apple Safari re-branded. So if your pages work in Safari, typically they’ll work in Chrome. But I don’t use Safari, and now I know that if ever given the chance I wouldn’t. The way it handles things is so dumb compared to IE7. For instance, if I want to add a link in Gmail using IE7, I highlight the text I want to link, click the link button, enter my link, and hit enter, and the highlighted text is now a link.  In Chrome, I follow the same steps, except when I’m done, there’s an additional space after the word. At this point, you’re thinking, you nitpicky a-hole, but the problem with this is, let’s say I want to put a comma next to the linked text. If I try to do that (which I do whenever I process an order), Chrome assumes the comma is part of the link, and then any text following the comma that I type becomes the link. Now if I only linked to things in emails every once in a while, I could live with it, but this is something I do 20-30 times a day. It gets annoying.

There are a plethora of other weird (and admittedly nitpicky) differences. For instance, when holding Ctl and pressing an arrow key to highlight a word, it selects the word and the preceding space. Or when copying and pasting something with formatting, some of the formatting is stripped, some is kept, with no rhyme or reason as to what. Also try pasting anything copied from Excel. Gross.

While yes, these annoyances are small, remember that if I’m going to start using a new browser over one that I’m already comfortable with, it has to provide me with features the incumbent does not without pushing me out of my comfort zone. Even still, due to sheer geekdom and willingness to be on the “cutting edge”, I endured these minor hardships.

Until I started receiving reply emails from people wondering who the hell I was.

I have several email addresses that forward to my main (hub) Gmail account, and I have them set up as “Accounts” within Gmail so that I may send as that email address. I use this feature very frequently, as I like to keep certain emails separate during certain parts of the order lifecycle (ordering, processing, shipping, support, etc). However, I also run several other websites on which I have email accounts that I run into my Gmail account. In IE7, I choose which address I want to send out as and it works, no problem. In Chrome, I pick the one I want to send as, and it picks whichever one it wants, often resulting in a very incorrect FROM address.  Unfortunately, this is a dealbreaker.

So until Google Chrome undergoes some signficant changes (the last one being the most important), I will not be using this browser outside of the development arena (again, thanks for giving me another browser to check, Google).

Has anyone else experienced any other bugs in Chrome? Maybe in certain apps/sites?

September 10, 2008 Posted by | Bugs, Google Chrome, IE7 | Leave a comment