views:

429

answers:

3

I'm building a webpage on which I display the n newest newsposts on the front page, and this is the method that gets the posts and returns them to the .aspx-file. I use a asp:substitution-control to insert the string into the webpage.

I think my way of doing this i kind of messy and ugly, and not very flexible if i want to do little changes on the template. Is there any way for me to achieve what i want while having the template itself in a separate .aspx or .ascx file? I've tried, but cant come up with a smart way of handing the data onto the template-file.

Plus, when (if?) i've put the template in a separate file - how do i repeat it within another .aspx-file (within a contentplaceholder, if that matters. The layout is controlled by a master-page) with different values for each instance?

public static string getShortPosts(int postNumber)
{
    DbConnection d = new DbConnection();
    DataTable tbl = d.selectQuery("SELECT TOP (" + postNumber + ") news.id, news.title, news.newsContent, news.excerpt, news.date, news.userid, news.urlTitle, " +
                                    "news.isPublished, users.firstName, users.lastName FROM news INNER JOIN users ON news.userid = users.userid " +
                                    "ORDER BY id DESC;");
    DataTableReader r = tbl.CreateDataReader();

    StringBuilder s = new StringBuilder("");

    while (r.Read())
    {
        /* THIS */ 
        s.Append(
            "<div class=\"newsBox\">" + System.Environment.NewLine +
            "<h2>" + r["title"]+ "</h2>" + System.Environment.NewLine +
            "<p>" + r["excerpt"] + "</p>" + System.Environment.NewLine +
            "</div>" +System.Environment.NewLine+System.Environment.NewLine
            );
    }

    return s.ToString();
}
+1  A: 

If it were me, I would create a user control dedicated to creating a single entry in the listing. The user control would only need one parameter (the post number it's responsible for). The page itself need only maintain an array (or list or whatever structure you would prefer) of these user controls and add them to whatever panel they need to be displayed in dynamically.

The user control would contain a panel with class "newsBox", a label for the title, and another panel (or possibly just a regular HTML paragraph) for the content, so its output would be the same as what you're building in your example. The difference is it would be created using ASP and HTML objects instead of a string.

Also, if it were me, I wouldn't have a user control responsible for querying its own data from the database. A DAL would really be beneficial here, as you could have a function "GetNewsDetails(int postNumber)" that could cache news posts if they've been queried recently and could be reused by other user controls if necessary.

Welbog
+1  A: 

Interesting question.

I think you can build and .xslt trasformation file, that applied to an xml source will generate the html you need.

So in your pages you must only have an asp:Xml control:

<asp:Xml ID="xmlMyControl" runat="server" />

In code behind you have to apply the transformation loading the proper xslt file:

XslTransform xslt = new XslTransform();
xslt.Load(Server.MapPath("~/myTransformationFile.xslt"));

xmlMyControl.Transform = xslt;

xmlMyControl.DocumentContent = myMethodToRetrieveXML(); // Your source data, return xml as a string
xmlMyControl.DataBind();

I see by your code you have a DataTable as data source, but i think it's no problem to convert it into xml string.

By this way you will have only one template (.xslt file), and all the changes you apply on it will automatically reflects everywhere you use it.

tanathos
Ah, nice idea. Might just look into it.
Arve Systad
+1  A: 

I would suggest templated user controls. There are plenty of tutorials online; here is a msdn article on the matter: http://msdn.microsoft.com/en-us/library/aa478964.aspx

In this article we examined how to create a non-databound custom ASP.NET server control that employed the use of a template. Realize that the control could be extended to provide multiple templates, much like how the DataList provides a multitude of templates. We added template support by tackling the following steps:

  • Creating a private member variable of type ITemplate in the DisplayStats control class.
  • Created a public read-write property statement for the template.
  • Created a class (StatsData) derived indirectly from the Control class that provided properties that we wanted to allow the page developer to access in the template via databinding syntax.
  • Overrode the CreateChildControls() method. This method cleared the Controls collection, created an instance of StatsData, then instantiated the StatsData instance in the template, and finally added the StatsData instance to the Controls collection.
  • Overrode the DataBind() method, which called the CreateChildControls() method.

With templated controls you can have your own setup similar to a repeater with repeater items. Where you can expose a DataItem and write all of the markup in the front end. It also is rather designer friendly. However, a huge cost is the increased complexity. I would definitely reserve it for important or highly re-usable controls.

ccook