administration mode
Pssst...Ferdy is the creator of JungleDragon, an awesome wildlife community. Visit JungleDragon


Article: The making of Blogo.NET »

FERDY CHRISTANT - APR 4, 2008 (12:51:01 PM)

This article explains into detail how I developed Blogo.NET, which is an n-tiered internet blog application based upon .NET 3.5. The article really is many articles into one, as it explains the full process of development, including architecture, database design/access (LINQ), UI design, security and much more.

Due to its size (43 pages), the article is provided as a downloadable PDF:

The making of Blogo.NET v1.00 - PDF (2,186 KB)

If you chose to link to this article, please link to this page, not the download link. You can provide feedback and comments below, I welcome everyone to do this. Thanks everyone for taking the time to read the article!

Share |

Comments: 26
Reviews: 5
Average rating: rating
Highest rating: 5
Lowest rating: 5


APR 10, 2008 - 07:47:48

comment » Ferdy you have done it again!

A great piece of work.

Do you see many changes to get your reference architecture to work with a winforms application? «


APR 10, 2008 - 03:30:09 PM

comment » hi Mark,

Thank you. In fact no, due to this architecture, you only have to change the View layer in order to make it work with Winforms, everything else is completely decoupled. «

COMMENT: ROMAN KOPAC emailhomepage

APR 11, 2008 - 16:37:53

comment » Ferdy, thank you for ruining my weekend. Instead of going out I'll have to read your article ;-) I can see you really put a lot of work into it. «


APR 11, 2008 - 09:45:19 PM

comment » Roman,

You're welcome, looks like I just saved you some money. I hope you like the article. «


MAY 1, 2008 - 03:27:33

comment » Thank you very much for sharing this! I had lots of fun reading your article, really made my day.

I've shed a few tears recently trying to figure out a solid .net architecture that looks good from A-Z. I'm no expert but your architecture looks really maintainable, scalable, readable, fast and each layer is friendly to use. I'm thinking about alot of things after reading(skimmed through some parts, saving the full read untill a long flight later in the week :) your article, as I say'd I'm just a beginner so hopefully you will bear with me if my questions are silly. I'm wondering about the Linq to Sql part, is that inhibiting you in any way? compared to using in the data layer, and the linq objects, always transforming them to custom objects how is that effecting performance, wouldt it be faster with using a datareader? And using dumb classes, that couples the data access layer to the domain model alot, agen passing a .net framework class(datareader) from the DAL to the BLL would maybe be better? Also with this architecture, with the GetList() method for need one gridview and one ObjectDataSource and one page for each *Manager class, to display all your lists. If you have 100 lists this might be bad practice? Is there a way(inheritance/polimorphism/factory pattern) to be able to only use one gridview and one ODS in one page to display all the lists. If you know from a value on the page which *Manager GetList() method to use.

Since this is not a support forum I've said more then anough already :) Thank you agen for this excelent article.

Nuwanda «


MAY 8, 2008 - 03:39:14 PM

comment » Nuwanda,

Thanks for your compliments and detailed response. Hereby a few answers from my side:

- concerning the conversion of LINQ object to custom data objects: There are different ways to do this, for example you can directly bind from controls to LINQ classes, or you can define an intermediate layer like I did. The advantage of an intermediate layer of objects is that you have a neutral layer, the disadvantage is that it requires some manual steps to keep them in sync. There is no single best practice, you have to make this choice yourself.

- I have not tested the performance difference between data readers and LINQ data access, but in many modern applications, the difference is probably so tiny that nobody would notice.

- It is true that in my architecture the Data Access layer has to know about the dumb Business Objects, but the same applies if we would not have these dumb objects. In that case, the business layer would talk directly to the LINQ classes, and would have to know about those too. What if the data access layer changes? «


JUN 3, 2008 - 01:26:25 PM

comment » Excellent supplement to Amir's example walk-through!

question - yes, there seems to be much work in coding what's "proper" behind the scenes. With the addition of LINQ and the capability of VS to generate a dbml file, much work is alleviated from the DAL.

However, as you pointed out, there is still much to be done in the BAL - creating the "dumb" objects and their respective managers. It appears most of this code is redundant and similar all the way through the entire database.

My question is this... now that I have a good representation of how to architect an ASP.NET app (or other), what can I do to reduce my development time at least as far as the "plumbing" code?

You mentioned "generating" my code. Might you have insight on a recommended code generator? I've seen on the web, but am not familiar with CODESMITH, MYGENERATION, ENTITYSPACES (?), etc.

Please let me know what you can about these and others including which direction you would recommend for me. I would welcome your input!

Thanks so much for this and especially your article. What a generous and helpful contribution to the community. It's very inspiring!

Donna «


JUN 3, 2008 - 03:26:37 PM

comment » hi Donna,

Thanks for the compliments, I'm glad you liked the article. As for code generators, I have little experience in the .NET world. At work we are using DSL technology, which is extremely powerful, but a bit hard to comprehend. SQLMetal is a more light weight option that is more related to LINQ. I suggest Googling around a bit, as I am not an expert on this matter. «

COMMENT: DONNA emailrating

JUN 4, 2008 - 08:01:33 AM

comment » Fair enough; thanks for the candor!

Again, great material; thanks so much for sharing!

Donna «


JUN 4, 2008 - 08:31:17 AM

comment » Just thought of a clarification I'd like to run by you...

In your article, you mention that the business rules would be placed in the "manager" classes. Got it.

What about any global variables like for storing info for user sessions? How do you recommend establishing / managing global vars, specifically for individual user sessions (e.g. session variables, etc.)?

Thanks for any input!

Donna «


JUN 26, 2008 - 07:51:52 AM

comment » Ferdy,

You may be aware, but I found a glitch in Blogo.NET. The "author" name does not get filled-in when anonymous users enter a "comment".

The line is in BlogEntry.aspx.cs, line 27. It checks if the user is authenticated and sets to it if so, but then it erroneously blanks the user's name if it's not authenticated.

I corrected as:

if (User.Identity.IsAuthenticated)

CommentName.Text = User.Identity.Name;

Again, if you were already aware, please ignore. Otherwise, I hope this helps everyone!

Donna «


JUN 26, 2008 - 02:43:25 PM

comment » Thanks for pointing this out, but I do not see this as a bug. The point is, most commenters will not be authenticated ever. As with most blogs, comments are anonymous. The only reason why the check is in there is that authenticated users (as in blog admins) should also be able to comment. Makes sense? «


JUN 27, 2008 - 10:17:58 PM

comment » Hey Ferdy! Let me try to explain again because the way the original code is, unless I'm missing something, it doesn't operate as expected.

There's a required field in the comments section for the visitor to enter his/her name.

Any person making a comment will either be:

1) an admin person logged-in, or

2) a non-admin person (or an admin person not logged-in which is the same).

In either case, the value that is in the textbox for the name field when the comment is saved is not used. Instead, the value is either pulled from the admin record (for case #1), or is blanked-out (in case #2). Both cases ignore/overwrite what was entered.

Does this make better sense?

When I stated "bug" I meant of the "logic" type, not "code". But like I said, I might be missing something. Is this the behavior you intended? If so, could you elaborate? «


JUN 27, 2008 - 10:56:19 PM

comment » Ferdy,

Off of the last topic, in your "making of" PDF, on page 10, there's a link to "example queries" for LINQ. The PDF doesn't have the link as clickable. Can you share the URL to that?

Thanks for any assistance,

Donna «


JUN 30, 2008 - 08:02:46 AM

comment » hi Donna, thanks for reporting the bug. Unfortunately, Blogo.NET was a one-time effort, and is not a supported application. Therefore, if you discover a bug, you will have to fix it yourself. I hope you understand.

The link for the LINQ examples is: «


JUL 1, 2008 - 03:03:23 AM

comment » Hey Ferdy! I understand; wasn't actually seeking support, but was trying to help others who download your project.

Out of the "box", it runs quite smoothly, but it doesn't take long to discover that the "name" field isn't getting retained (saved to DB) during user comments unless it's an admin person and even then, it ignores what's typed/edited and uses the entry from the admin table.

Let me be clear though -- I LOVE the project you did. I think it's great and I truly appreciate people like you out there taking the time to create such a thorough tool, which I know takes valuable time, and then offer it free to the community. It deserves much respect.

Got the link -- thanks so much!

Donna «

COMMENT: JEFF emailrating

DEC 14, 2008 - 02:48:29 AM

comment » Hey Ferdy! Dude! 01 Thanks for the article,the source code, and that bodacious link to the LINQ samples! I can't wait to dig into this project and get to tinkering in the code.


Jeff 07 «


FEB 5, 2009 - 05:05:31 PM

comment » Ferdy,

I implemented Imar Spaanjaars' architecture for my last project, but followed your design closer on this project due to the fact you used LINQ. I've spent quite a bit of time going through your write up and code. It takes balls that clank to put your source code out for scrutinizing. Ok, now for my question:

So blog_tags in a mapping object and not a business object. That makes sense in your architecture to not have a business object for each mapping table in the database. Due to the fact that its not a business object, its parent B.O. (in this case BlogEntry) must handle the creating and deletion of the mapping objects.

So my question is on update of the parent object you blow away the mapping object and recreate it. So in your example, if you update the title of a blog entry your must recreate the mapping for no apparent reason. Is there a good reason for this? Seems like for a high traffic site you could eat through mapping ID's in the db. «


FEB 5, 2009 - 07:17:28 PM

comment » Tim,

Thank you for taking the time to go through the article and source code, as always, every kind of feedback is welcome here.

Is is a good question you have. It is a design decision, really. Deleting and recreating the mappings for each edit/save is the easiest way to implement. A more complex way is to do it, is to go through all existing mappings for the entry and then compare them to the tags in the form. Next, add the new ones, and/or delete the ones that were removed. In both cases you will be touching the database quite a lot, so I went for the easiest solution.

I do not suspect this choice to become a problem for a blog application, SQL can handle millions if not billions of entries. A high traffic site has little to do with this, as the creation of ids is related to edits, not traffic. Should this design choice really be a problem though, feel free to improve the source code 18 «


MAR 24, 2009 - 10:25:46 PM

comment » Ferdy,

After implementing this architecture, I ran into one issue which wasn't easy to track down. Thought I would comment here in case someone else has the same problem. The root of the problem is that the connection is created within each static class and shared within its methods. If too many connections are open its possible to receive the error "Executereader requires an open and available connection". One solution would be to open a connection in each method wrapped in a using statement to insure the DataContext was properly disposed. Like:

public static int Count()


using (BlogoMapDataContext db = new BlogoMapDataContext())


return db.blogentries.Count();


} «

COMMENT: AUTO CARE emailhomepage

JAN 31, 2013 - 05:35:56 AM

comment » Even I am preparing for zend certification and trying to create a blog with some important information about the preparation. take a look at my blog. «


JAN 31, 2013 - 05:36:09 AM

comment » i like to move it «

COMMENT: CAR REPAIRS emailhomepage

JAN 31, 2013 - 05:36:21 AM

comment » i like to move it «


JUL 29, 2013 - 08:05:48 AM

comment » After implementing this architecture, I found a problem that was not easy to locate. I thought I would comment here in case someone else has the same problem. The root of the problem is that the connection is created within each class static and shared within their methods. «


JAN 30, 2014 - 08:24:50 AM

comment » Great blog here! Also your site loads up very fast! What host are you using? Can I get your affiliate link to your host? I wish my site loaded up as fast as yours lol. «

COMMENT: MARKO emailhomepagerating

FEB 26, 2014 - 02:24:07 AM

comment » Thanks for the helpful content. It is also my opinion that mesothelioma has an incredibly long latency time, which means that the signs of the disease might not exactly emerge till 30 to 50 years after the first exposure to asbestos. Pleural mesothelioma, that is the most common sort and impacts the area within the lungs, might cause shortness of breath, chest pains, including a persistent cough, which may produce coughing up bloodstream. «

Was this document useful to you?
rating Awesome
rating Good
rating Average
rating Poor
rating Useless
required field
required field HTML is not allowed. Hyperlinks will automatically be converted.