Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Real - World ASP .NET—Building a Content Management System - StephenR. G. Fraser

.pdf
Скачиваний:
68
Добавлен:
24.05.2014
Размер:
4.59 Mб
Скачать

Figure 12-8: The AdmAcntView Web page

Summary

This chapter covered cookies, authentication, authorization, and encryption.

It started with a brief discussion of ASP.NET's security and then moved on to cover CMS.NET's security in a little more detail. Then it covered cookies and session objects and how to build and use them. Next, it described the method by which ASP.NET provides authentication and then went into detail on how CMS.NET does authentication. After this, it moved on to ASP.NET authorization and CMS.NET role-based authorization and why it was decided to not use ASP.NET authentication at all. This chapter briefly explored encryption and then ended by covering account management.

In the next chapter, you start to have some real fun—you get to start displaying content you have accumulated to the world.

Chapter 13: Displaying Dynamic Content

Overview

I've had enough of back-end administrative development, how about you? All the previous chapters were fun, but there's nothing like being able to display dynamic content and show off all your hard work. The average user will never see all the work you have put into the system so far. Not so with this chapter, however, because dynamic content display is all about strutting your stuff in front of users.

You will just use a standard display template for all users visiting the site. Believe it or not, even the simple display template provides a lot to the user. But, there is nothing stopping you from creating a much more elaborate template in your implementation of CMS.NET.

CMS.NET provides a home page, a way of dividing the content into as many domains and subdomains as you think necessary, and the capability to navigate in and out of all these domains, zones, and the home page. The content is divided into a header, source, teaser, body, and tagline, of which only the header and body are mandatory. As an added bonus, you have full HTML formatting capabilities within all the aforementioned sections.

Not too bad for one chapter.

But that's not all ... (I've always wanted to say that!) I'll throw in a content deployment system for free.

What Is Dynamic Content?

If you are like everyone else, your first attempts at building a Web site started with a tool such as Microsoft FrontPage. The first thought you probably had was "This isn't so hard." You created page after page. Soon, you began to realize all the pages were starting to look alike, except for this or that section of each page. After a while, the sheer number of pages you had to maintain became mind-boggling and you started to think "There has to be a better way." Fortunately, there is. It is called dynamic content.

As a concept, dynamic content is very easy. It is simply content created at the time it is needed rather than in advance. Basically, dynamic content is achieved by storing all the pieces of content that a user might want to view and then, when the user requests some

of this content, a Web page—specific to the request of the user—is built.

Dynamic content sounds easy enough, but until the writing this book, it cost hundreds of thousands of dollars to buy a system to implement. Yes, these systems provide many bells and whistles, but I ask you, hundreds of thousands of dollars worth?

Creating a static Web site using only HTML is really a thing of the past. Even the pages you create with FrontPage enable you to throw in dynamic components and controls.

In this chapter, the designer of CMS.NET defines the dynamic nature of the Web site. That designer is, of course, yours truly. When you combine dynamic content with personalization, the design enables the user to start taking some control of the dynamic nature of the site. You will see that you can achieve a truly unique experience for each user.

Three-Level Content Navigation

CMS.NET uses the very common three-level approach to content navigation. Take a quick peek around the Internet. You will find that it usually takes about three or four levels before you get to the story you are looking for on a given Web site. Most people do not want to go much deeper than four levels into a Web site, and most Web sites hover around three levels. Personalized sites will often shave one level off your navigation.

Why Three-Level Navigation?

It seems to be an unwritten industry standard. Having three levels just feels right. I find that two-level sites require a lot of scrolling to find what you are looking for. On the other hand, with a Web site that is four levels deep or more, you start to get the feeling of "Will I ever get there?"

CMS.NET doesn't force three levels, though. If you that find the story you want pops up while navigating, there is always a quick hyperlink to it. But, of course, this is only common sense.

So What Are the Three Levels of CMS.NET?

The top level is made up of one or more subject area domains. They can be almost any high-level abstraction of your content system. As you can see in Figure 13-1, this book's implementation of CMS.NET uses Developer Content and Management Content as domains, but any high-level abstraction could be used.

Figure 13-1: Developer Content domain zones

Inside each domain are subdomains, or what CMS.NET calls zones. Again, they could be almost any abstraction. As you can see in Figures 13-1 and 13-2, the domains are broken up as follows:

§Developer Content

o

e-Business

o

Development

o

Database

oBusiness Solutions

§Management Content

o

Technology

o

Professional

o

Managerial

Figure 13-2: Management Content domain zones

The third and final level of CMS.NE T is content grouped by story. The same piece of content can be used in different zones if it makes sense to do so. For example, if a story is about implementing a database in an e-business solution, it makes sense to include the story in both zones. As you can see in Figure 13-3, the data used is just test data, but obviously, you are going to want to implement your real content.

Figure 13-3: Managed C++ book story

Starting and Stopping the Web Site

There is no greater sin made by a Webmaster than allowing the "The page cannot be displayed" error (see Figure 13-4) to show up during a user's travels through the site. It is the kiss of death if it shows up just as someone is trying to access your Web site for the first time. Think of it from the perspective of the user.

Figure 13-4: "The page cannot be found" error

The first rule to remember about users is that they think there are probably a gazillion other Web sites on the Internet with content similar to yours. If yours isn't available, the user will go elsewhere. Only by showing the user that your site is the best thing since sliced bread will he likely return.

If you can't have your site up for some reason (and it had better be a good one), make sure you provide a Web page that tells the user that he got the right place and to please come back later. Heck, you might get lucky and the user will try back later. If the user

gets the "The page cannot be found" error page, however, the chances are nil to none that you will see either hide or hair of that user again.

There really is no excuse for the "The page cannot be found" error to show up. It is such an easy task to put up a dummy page (if the Web server is running) or to route the IP address to somewhere else while the Web server is being restarted. Figure 13-5 shows CMS.NET's friendly "I'm really here but come back later" page.

Figure 13-5: The "I'm changing" page

The Default.aspx Web Page

Chapter 10 covered all the code needed to handle shutting down and starting up the system. This time, instead of the Admin.aspx Web page checking for the setup

<appSettings> element, the Default.aspx Web site is looking for the ready

<appSettings> element. If Default.aspx finds the ready <appSettings> element value set to true in the web.config file, it knows that the system is running and can continue as normal. On the other hand, if the value returned is false or does not exist, the Web site knows it is shut down and, instead of redirecting to the home page, displays it own message asking the user to come back later. Listing 13-1 shows the Default.aspx Codebehind to handle this process.

Listing 13-1: The Default.aspx Codebehind

private void Page_Load(object sender, System.EventArgs e)

{

string ready = new AppEnv(Context).GetAppSetting("ready");

if(ready.Equals("true"))

{

Response.Redirect("CDA/HomePg.aspx");

}

}

The AdmShutdown Web Page

To give the Webmaster even less of an excuse, CMS.NET made the process of bringing the Web site up and down extremely easy. Whenever maintenance needs to be done on CMS.NET that does not require the Web server to be shut down, the Webmaster simply has to navigate to the AdmShutdown Web page and press the single button found on it. On the other hand, if you need to bring down the Web server for some reason along with the Web site, you need to reroute your host name to a new IP address. The procedure to do this differs with each host provider, but it should simply be, in most cases, a phone call telling the host provider of your intentions.

As you can see in Figure 13-6, the Web page to shut down and start the system consists of merely one heading, label, and button. If you can't create the ASP.NET design for this, you shouldn't be reading this book yet.

Figure 13-6: The AdmShutdown Web page

The AdmShutdown Codebehind

The Page_Load() method (see Listing 13-2) is a very simple procedure to dynamically place the appropriate label on the prompt and button. First, it gets the value of the ready

<appSettings> element. Then, if the value of ready is true, meaning the site is up, it prompts the Webmaster to shut the Web site down. On the other hand, if the value is anything but true, it prompts the Webmaster to bring the Web site up.

Listing 13-2: The AdmShutdown Page_Load Method

private void Page_Load(object sender, System.EventArgs e)

{

ready = appEnv.GetAppSetting("ready");

if (ready.Equals("true"))

{

lbPrompt.Text = "The site is currently up.";

bnStartStop.Text = "Bring site down?";

}

else

{

lbPrompt.Text = "The site is currently down.";

bnStartStop.Text = "Bring site up?";

}

}

The bnStartStop_Click() method (see Listing 13-3) is a little more elaborate, but you already have covered all the code in Chapter 10. All it does is simply toggle the ready <appSettings> element in the web.config file from true to false and back.

The first time the Web site is ever started up, the ready <appSettings> element is added to the web.config file. Finally, the prompt and button's text gets toggled to its opposite state.

Listing 13-3: The AdmShutdown bnStartStop_Click Method

private void bnStartStop_Click(object sender, System.EventArgs e)

{

bool isready = false;

XmlReader xtr =

new XmlTextReader(File.OpenRead(Server.MapPath("..\\..\\web.config")));

XmlDocument doc = new XmlDocument();

doc.Load(xtr);

xtr.Close();

XmlNodeList nodes =

doc.DocumentElement.GetElementsByTagName("appSettings");

for (int i = 0; i < nodes.Count; i++)

{

XmlNodeList appnodes = ((XmlElement)(nodes.Item(i))).GetElementsByTagName("add");

for (int j = 0; j < appnodes.Count; j++)

{

XmlAttributeCollection attrColl = appnodes.Item(j).Attributes; XmlAttribute tmpNode = (XmlAttribute)attrColl.GetNamedItem("key"); if (tmpNode.Value.Equals("ready"))

{

if (ready.Equals("true")) ((XmlAttribute)attrColl.GetNamedItem("value")).Value =

"false";

else ((XmlAttribute)attrColl.GetNamedItem("value")).Value =

"true"; isready = true;

}

}

if (!isready)

{

// if it gets here, it's the first time the site is started up XmlDocumentFragment newAppSetting = doc.CreateDocumentFragment();

newAppSetting.InnerXml=("<add key=\"ready\" value=\"true\" />\n"); ((XmlElement)(nodes.Item(i))).AppendChild(newAppSetting);

}

}

File.Delete(Server.MapPath("..\\..\\web.config"));

StreamWriter sr =

new StreamWriter(File.OpenWrite(Server.MapPath("..\\..\\web.config"))); doc.Save(sr);

sr.Close();

// Flip prompt

if (ready.Equals("true"))

{

lbPrompt.Text = "The site is currently down."; bnStartStop.Text = "Bring site up?";

}

else

{

lbPrompt.Text = "The site is currently up."; bnStartStop.Text = "Bring site down?";

}

}

Navigational Database Tables

As you might think, CMS.NET's three-level navigation requires three additional database tables to be added to the repository: Domain, Zone, and Distribution. All three correspond directly to the three-level navigational scheme of CMS.NET.

The Domain database table, as the name suggests, stores all the domain information for CMS.NET. As you can see in Table 13-1, there is not much to the table. The table is primarily used to dynamically build CMS.NET's NavBar. The DomainTitle is displayed on the NavBar, whereas the DomainType is used in building the NavBar hyperlinks.

 

Table 13-1: Domain Database Table Design

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

COLUMN NAME

 

DATA

 

 

LENGTH

 

KEY

 

DESCRIPTION

 

 

 

 

TYPE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Table 13-1: Domain Database Table Design

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

COLUMN NAME

 

DATA

 

 

LENGTH

 

KEY

 

DESCRIPTION

 

 

 

 

TYPE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DomainID

 

int

 

4

 

true

 

Domain ID for

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

this domain

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DomainType

 

char

 

32

 

false

 

Type of Web

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

page

 

 

 

 

 

 

 

 

 

 

 

associated

 

 

 

 

 

 

 

 

 

 

 

with this

 

 

 

 

 

 

 

 

 

 

 

domain

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Title

 

char

 

32

 

false

 

Title of the

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

domain

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Description

 

char

 

64

 

false

 

Brief

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

description of

 

 

 

 

 

 

 

 

 

 

 

the domain

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ModifiedDate

 

datetime

 

8

 

false

 

Date domain

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

was last

 

 

 

 

 

 

 

 

 

 

 

changed

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CreationDate

 

datetime

 

8

 

false

 

Date domain

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

was created

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 13-7 shows the contents of the Domain database used by CMS.NET. Each domain gets its own unique DomainID, which is used to create a one-to-many relationship with Zone. The NavBar uses DomainType to determine what type of Web page to display when a hyperlink is selected from it. In fact, we will be creating homepg.aspx and contentpg.aspx Web pages a little later on.

Figure 13-7: Domain database for CMS.NET

The Zone database table stores all the zone information of the Web site. As you can see in Table 13-2, this table is no more difficult than the Domain table. ContentPg.aspx primarily uses this table. This page's role is to display the lead story for each zone within a domain.

 

Table 13-2: Zone Database Table Design

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

COLUMN NAME

 

DATA

 

LENGTH

 

KEY

 

DESCRIPTION

 

 

 

 

TYPE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ZoneID

 

int

 

4

 

true

 

Zone ID for

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

this domain

 

 

 

 

 

 

 

 

 

 

 

 

 

Title

 

char

 

32

 

false

 

Title of the

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

zone

 

 

 

 

 

 

 

 

 

 

 

 

 

Description

 

char

 

64

 

false

 

Brief

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

description of

 

 

 

 

 

 

 

 

 

 

the zone

 

 

 

 

 

 

 

 

 

 

 

 

 

DomainID

 

int

 

4

 

false

 

The domain

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

with which this

 

 

 

 

 

 

 

 

 

 

zone is

 

 

 

 

 

 

 

 

 

 

associated

 

 

 

 

 

 

 

 

 

 

 

 

 

ModifiedDate

 

datetime

 

8

 

false

 

Date zone was

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

last changed

 

 

 

 

 

 

 

 

 

 

 

 

 

CreationDate

 

datetime

 

8

 

false

 

Date zone was

 

 

 

 

 

 

 

 

 

 

 

 

 

Table 13-2: Zone Database Table Design

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

COLUMN NAME

 

DATA

 

LENGTH

 

KEY

 

DESCRIPTION

 

 

 

 

TYPE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

created

 

 

 

 

 

 

 

 

 

 

 

 

Figure 13-8 shows the Zone database used by CMS.NET. Like the Domain database, each zone gets its own ZoneID, which is used by the Distribution database to distribute stories. The DomainID is used to create a relationship with a domain. A zone can only have a relationship with a single domain.

Figure 13-8: Zone database for CMS.NET

It is possible to simplify CMS.NET by restricting a piece of content to only a certain zone. However, this restriction would be a mistake because many pieces of content can and should be associated with many zones. Guess what this leads to? It leads to the dreaded many-to-many relationship, and as any database developer will tell you, you are going to need an intersection entity to resolve this type of relationship.

The Distribution database table (see Table 13-3) is this intersection entity. The database table contains a list of every zone with which each piece of content is associated. The table also has a ranking or weighting factor that determines the importance of a piece of content to a particular zone. You might notice that because this ranking is in the intersection entity, you are able to have different weightings for the same piece of content in different zones.

 

Table 13-3: Distribution Database Table Design

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

COLUMN NAME

 

DATA

 

LENGTH

 

KEY

 

DESCRIPTION

 

 

 

 

TYPE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ContentID

 

int

 

4

 

true

 

Content ID for this

 

 

 

 

 

 

 

 

 

ZoneID

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Version

 

int

 

4

 

true

 

Version for this

 

 

 

 

 

 

 

 

 

ZoneID

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ZoneID

 

int

 

4

 

true

 

Zone ID for this

 

 

 

 

 

 

 

 

 

ContentID/Vers

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ion pair

 

 

 

 

 

 

 

 

 

 

 

 

 

Ranking

 

int

 

4

 

false

 

The ranking of this

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

content for this

 

 

 

 

 

 

 

 

 

 

zone

 

 

 

 

 

 

 

 

 

 

 

 

 

ModifiedDate

 

datetime

 

8

 

false

 

Date distribution

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

was last changed

 

 

 

 

 

 

 

 

 

 

 

 

 

CreationDate

 

datetime

 

8

 

false

 

Date distribution

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

was created

 

 

 

 

 

 

 

 

 

 

 

 

Figure 13-9 shows the intersection data found in the Distribution database. Notice that a story with the same ContentID and Version can be related to multiple ZoneIDs. The Ranking column is used to sort content within a zone. Sorting will be done in descending order. Thus, a story with a ranking of 4 will be displayed before one with a ranking of 3.

Figure 13-9: Distribution database for CMS.NET

Соседние файлы в предмете Программирование