How to Really write a Server Control in ASP.Net
- November 13, 2013
Find Missing Dependency DLLs on Win 7
- March 5, 2012
Nullable TryParse
- May 26, 2011
Diff SQL Server Stored Procedures, November 15, 2010
Reporting Services Extranet Access, March 16, 2010
Case of the missing WaitCursor, January 7, 2009
Simple Submit Button Disable, December 9, 2009
An Efficient Memory Stream, September 29, 2009
Approach Plate Download - May 14, 2009
WPF Binding - Async Web Services - April 10, 2009
Developing the Blog
- April 4, 2009
|
|
This is the first time I have used a Master Page on a web application. It is quite simple, and the behavior is
predictable. I have to say it is a long time coming. I wrote a templating
language for HTML in Java right before they released ASP, and it had master
pages. Almost an identical implementation, too. I think I will have
to reformat the Flying Club's web site to use it.
While trying to merge my code into my original web site, written in JScript, I got a strange error. I added a link from
this new blog's Nav Bar (on the left) to the index.asp page, and when I ran the debugger I received:
Server Error in '/' Application.
This type of page is not served.
Description: The type of page you have requested is not served because it
has been explicitly forbidden. The extension '.asp' may be incorrect. Please
review the URL below and make sure that it is spelled correctly.
Requested URL: /index.asp
Further investigation into the error shows that you cannot run the Visual Studio web server and navigate to an .asp page.
When I tested this on the IIS server normally, it linked as expected. My guess is that there is no way to configure VS to
work around this (and a search on the net tends to confirm this).
I needed a list placeholder for the list of blogs on the left hand side. Then I would write a piece of code in the load of the
master page which would iterate over the files in this folder and find all the files with a date as the file name, look at
the header tag inside the file, and create a URL to add to the list.
First stop, the Bulleted List:
<asp
:
BulletedList
runat="server"
ID="BlogList"
DisplayMode="HyperLink"
/>
As there are always many ways to skin this cat, I decided to first try the brute force, all in the code behind. In the Page Load code
for the master page, I added the following:
ListItem a_newItem =
new ListItem("April 4, 2009 - Developing a .Net Blog",
"20090404.aspx");
BlogList.Items.Add(a_newItem);
So far, so good. I don't really like the bullet, so I look for just a generic list. I want something which I can later bind to,
if I ever want to move away from populating the list from the code behind. Let's now try out the Repeater:
<asp:Repeater
runat="server"
ID="BlogListRepeater">
<ItemTemplate>
<asp:HyperLink
runat="server"
NavigateUrl='<%# Eval("Value")
%>' Text='<%# Eval("Text")
%>' ></asp:HyperLink>
</ItemTemplate>
</asp:Repeater>
Now, of course, I need a new list to be a data source to the repeater. I like the ListItems object, so lets stick with that.
ArrayList a_array =
new ArrayList();
ListItem a_newItem =
new ListItem("April 4, 2009 - Developing a .Net Blog",
"20090404.aspx");
a_array.Add(a_newItem);
BlogListRepeater.DataSource = a_array;
BlogListRepeater.DataBind();
Last thing to do is Figure out the real list of items from a directory listing:
protected void
Page_Load(object sender,
EventArgs e)
{
// create the data source
ArrayList a_array =
new ArrayList();
// find any aspx files in the current directory
FileInfo [] a_fileInfos = (new DirectoryInfo(Server.MapPath(".")).GetFiles("*.aspx"));
foreach (FileInfo
a_fileInfo in a_fileInfos)
{
// blog files have the date, in yyyymmdd format
as the file name
string a_name =
a_fileInfo.Name.Substring(0, a_fileInfo.Name.IndexOf('.'));
if (a_name.Length == 8)
{
string a_year = a_name.Substring(0, 4);
string a_month = a_name.Substring(4, 2);
string a_day = a_name.Substring(6, 2);
string a_formattedDate = a_month +
"/" + a_day + "/"
+ a_year;
DateTime a_result;
if (DateTime.TryParse(a_formattedDate,
out a_result))
{
// looks like a blog file
string a_fileLink = a_fileInfo.Name;
// default a string in case there is no <title> tag in the file
string a_linkText = "Entry on " + a_formattedDate;
using (StreamReader a_sr = new
StreamReader(a_fileInfo.FullName))
{
// ok, find the Title
string a_file = a_sr.ReadToEnd();
const string
a_titleString = "<title>";
int a_ix, a_ix2;
if ((a_ix = a_file.IndexOf(a_titleString,
StringComparison.CurrentCultureIgnoreCase)) >
-1 &&
(a_ix2 = a_file.IndexOf("</title>",
StringComparison.CurrentCultureIgnoreCase)) >
-1)
{
// found it.
Extract everything between the tags
a_ix += a_titleString.Length;
a_linkText = a_file.Substring(a_ix, a_ix2 - a_ix);
}
}
// add the found blog to the list of blogs
ListItem a_newItem = new
ListItem(a_linkText, a_fileLink);
a_array.Insert(0, a_newItem);
}
}
}
// assign the source to the repeater, and we're
off to the races
BlogListRepeater.DataSource = a_array;
BlogListRepeater.DataBind();
}
The rest is the job of the eye candy specialists... Lacking that, perhaps I will mess with the colors a bit.
One thing I could actually do would be to save the array of blog entries into a Context. But file operations are so fast these days,
I wouldn't bother considering it (unless of course this blog starts to get a million hits a day!)
|