Handling Articles and Categories for an ASP.NET AJAX Client-Centric Wiki Application

In the first two articles in this series, we began building an ASP.NET client-centric wiki application. We left off with the user interface. In this article, the third one in a four-part series, we continue looking at the user interface, with a special focus on the article categories.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 3
October 15, 2007
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

A downloadable .rar file is available for this article.

Web Service and Database

First, let’s look at the definition of the Web Service—MyDataService:

  using System.Data;

   using System.Web.Script.Services;

   using Microsoft.Web.Preview.Services;

   using Demos.CategoryInfo;

…… (Omitted)

[ScriptService]

public class MyDataService : DataService{

[WebMethod]

[DataObjectMethod(DataObjectMethodType.Delete)]

public void DeleteRecord(CategoryInfo o){

  if (o.CategoryName == null)

    {throw new AccessViolationException();}

     new SqlTaskProvider().DeleteRecord(o);

}

[WebMethod]

[DataObjectMethod(DataObjectMethodType.Select)]

public List<CategoryInfo> GetAllRecords()

  { return new SqlTaskProvider().GetAllRecords();}

[WebMethod]

[DataObjectMethod(DataObjectMethodType.Insert)]

public void InsertRecord(CategoryInfo o) {

  if (o.CategoryName == null)

   { throw new AccessViolationException();}

    new SqlTaskProvider().InsertRecord(o);

}

[WebMethod]

[DataObjectMethod(DataObjectMethodType.Update)]

public void UpdateRecord(CategoryInfo o) {

  if (o.CategoryName == null) {

   throw new AccessViolationException();

}

  new SqlTaskProvider().UpdateRecord(o);

 }

}

First, as required by the framework, we must put the ScriptService attribute before the Web Service so that the MS AJAX JavaScript framework will call it correctly. Second, you may have noticed that this web service doesn’t expose web methods in a typical manner. In this case, the web service is derived from DataService which exposes two special types of web methods (GetData and SaveData, you can further study them by examining the assembly Microsoft.Web.Preview.dll using the .NET object browser and Lutz Roeder's.NET Reflector tool). The methods defined here are attributed using [DataObjectMethod]. These are used by the ObjectDataSource control to expose methods that are treated as Select, Insert, Update, or Delete.

Note here in each web method we use a helper class named SqlTaskProvider that is defined inside the ‘Demos.CategoryInfo’ namespace to make the design modular. And also, the parameter type CategoryInfo is a general C# class which acts as an OOP wrapper for a record in the CategoryInfo table.

Display the Article Categories

In fact, this part has already been shown at the right side of the homepage. And also, we know that when clicking an item under ‘Sections’ the user will be navigated to another page, namely ‘MsgList.aspx,’ which will show the more detailed article category information. In this section, we will continue to discuss it.

First, let’s take a quick look at the design-time snapshot, as is shown in the following Figure 10.

Figure 10—the design-time snapshot of page MsgList.aspx.

You can see that only a few controls are put on the page: two HTML <a> elements (with each containing an <img> element) at the top and bottom respectively for the writer’s convenience, a MS AJAX ListView control occupying the larger middle space, and a line or footnote at the far bottom of the page.

Note here that we have to combine the xml-script mode with the imperative JavaScript mode. There are two reasons for this. On the one hand, when the user clicks the hyperlink ‘Write a New Post’ we have to dynamically decide if he or she is a valid user so as to take the corresponding actions. On the other hand we have to dynamically load the DataSource that will be bound to the ListView control according to the different article category information the user has selected at the homepage.

Now, let’s see the related code snippet. First, at the end of the xml-script part we define the following:

<application load="onLoad">

</application>

Here we have not immediately called the load event of the data source ArtInfoDataSource when the application is loading but bound a client-side function onLoad to the load event of the Application object. A clever reader may have doped out that only in this way can we achieve our goal—dynamically loading the data source. The following gives the code for the onLoad function:

function onLoad(sender,args)

{

  g_ArtInfoDataSource= $find('ArtInfoDataSource');

   var paraCategoryID=getParm();

    if (paraCategoryID!=null) {

     g_ArtInfoDataSource.get_parameters()["CategoryID"] =paraCategoryID+1;

     g_ArtInfoDataSource.load();

 }

}

  function getParm()

{

  var url=this.location.href;

   var pageurl = url.substring(url.indexOf("=")+1);

  return parseInt(pageurl);

}

As you can see, we first ‘$find’ the data source control, then with a helper function named getParm we get the passed parameter (i.e. ‘CategoryID=x’) that is specified in the homepage, then we get and specify the exact value of the  CategoryID field of the data source, and at last we can succeed in loading our data source.

As for the ‘Write a New Post’ hyperlink, it’s pretty easy. When you click the hyperlink, it calls the following function:

function judge(){

var bAuthenticated = <%= Page.User.Identity.IsAuthenticated.ToString().ToLower() %>;

  if (bAuthenticated){

   window.location.href='SendMsg.aspx';

}

    else {window.location.href='login.aspx'; }

}

First, with the help of the special ASP.NET <% %> block, we can call the server-side method and get the related value to mark when the current user has been authenticated (note the current user related info is stored in the ASPNETDB.MDF database). If the user is a valid user, then we allow him to write a new post (i.e. article) by redirecting him to the SendMsg.aspx page; otherwise, we lead him back to the login page. 

In the next section, we will start to look into another more interesting and challenging topic—displaying an article asynchronously.

Display an Article Asynchronously

Click one of the hyperlinks that points to an article in the MsgList.aspx page, and you will be navigated to another web page named ContentList.aspx (Figure 11). For the sake of convenience, we’ve purposely pieced the top and bottom parts together into one picture since there will possibly be a good many comments added to this article.

Figure 11—display an article (the runtime snapshot of the ContentList.aspx page).

Now, let’s see the related code snippet in the MsgList.aspx file, as follows:

<HyperLink id="Title">

  <bindings>

<binding dataPath="FileName" property="navigateURL" transformerArgument="ContentList.aspx?PathName={0}" transform="ToString" />

  <binding dataPath="Title" property="text" />

</bindings>

</HyperLink>

Here, when we click a hyperlink that points to an article in the ListView control, the navigating URL becomes, for example, ‘http://localhost:1034/AjaxWiki/ContentList.aspx?PathName=1’. As is mentioned above, in this example, we’ve put all the article’s detailed information in ‘.xml’ files, and these files are all located under the root folder (i.e. AjaxWiki). Thus, the content of this article in Figure 11 is stored in the ‘1file.xml’ file.

Now, there appears a question: how can we display the content of the ‘.xml’ file? In fact, there are many solutions; using XMLDataSource in ASP.NET 2.0 is certainly okay, but we are discontented with this solution since it’s server-side based. Manually programming to fetch the xml data from the server side is quite a bother. In this case, MS AJAX has also brought its own solution: using the XsltView control along with XmlDataSource. As you’ve guessed, we are only interested in this third solution.

Since the ‘.xml’ file will be downloaded in a dynamic way, we’re going about this in a way that is quite similar to that adopted in the ‘MsgList.aspx’ file. First, please look at the related xml-script code:

<script type="text/xml-script">

<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">

  <components>

   <XmlDataSource id="xmlDataSource" />

   <xmlDataSource id="xsltSource" autoLoad="true" serviceURL="MyXSLTFile.xsl" />

   <XsltView id="dataContent">

<bindings>

<Binding property="document" dataContext="xmlDataSource" dataPath="document" />

<Binding property="transform" dataContext="xsltSource" dataPath="document" />

</bindings>

</xsltView>

………………… (Omitted)

</components>

</page>

</script>

Here, we first defined two XmlDataSource controls (different from those in ASP.NET 2.0). The first one has not been loaded, not to mention its serviceURL parameter. The second one, which is responsible for loading the server-side file ‘MyXSLTFile.xsl’ which defines the style in which the XML file will be rendered, was automatically loaded at the very beginning of downloading the page.

Next, we defined an MS AJAX client-side control named XsltView which is attached to the HTML <div> element with the id being ‘dataContent’. Then, within the sub section <bindings> we bound the property document to the datapath document of the ‘XmlDataSource’ control, and the transform property to the datapath document of the ‘XsltSource’ control.

Now, let’s see the JavaScript code that accomplished the dynamic assignment:

<script type="text/javascript">

  var g_xmlDataSource;

   function pageLoad(sender,args){

    g_xmlDataSource= $find('xmlDataSource');

    var categoryid = getParm();

    var myfullpathXML=categoryid+"file.xml";

    g_xmlDataSource.set_serviceURL(myfullpathXML);

    g_xmlDataSource.load();

}

First, we must point out that, in the lifetime of an MS AJAX client-centric page, the pageLoad function (unlike the event onload in DHTML) is executed after all the xml-script blocks have been resolved. The getParm method here is the same as that used above. Therefore, the value of the myfullpathXML variable, in this case, is equal to ‘1file.xml’. Next, we specified the serviceURL parameter of the  xmlDataSource control to ‘1file.xml’ by calling the set_serviceURL method. Finally, we loaded the ‘1file.xml’ file by invoking the load method of the xmlDataSource control.

So, does everything seem perfect? No, not quite.

Why is it More Challenging?

Here the "challenging" maybe only aims at me. Anyway, let me point out the challenge in dealing with the XML data.

The first challenge lies in the path. In my experiment, as you may expect, I created a folder under the App_Data folder to store all the .xml files and the .xsl template files, but I failed in rendering the XML data in the client side—nothing about the XML data appears. Why? Regrettably, it’s just for this reason that I had to put all the .xml and .xsl files under the root folder.

The second challenge lies in refreshing the XML data. When I clicked the Reply button to post comments to the current article I could not find the proper means to immediately refresh the posted data, provided that I used MS AJAX client-side controls XsltView and XmlDataSource. However, as far as I know, we can use ASP.NET 2.0 XML and XmlDataSource controls or leverage the "original" AJAX techniques to gain our ends. Thus, although I put a "refresh" link on the page, the refreshing could not happen, and so I commented out all the related code just for your reference.

Finally, as has been implemented before, when the user clicks the Reply button to add some comments to the current article he should be logged in, or else he will be sent back to the 'login.aspx’ page.

Write a New Article Using the Original AJAX Technique

At the top and bottom parts of the aforementioned MsgList.aspx page there have been put two ‘Write a New Post’ hyperlinks. When you click either hyperlink (in fact the two have exactly the same function for the users’ convenience) and you are a valid user, you will be navigated to the ‘SendMsg.aspx’ page where you can post your own new article. The following Figure 12 shows the design-time snapshot of this page.

Figure 12—the design-time snapshot for writing a new article.

Some readers may ask: why do you use the original AJAX technique to write a new article? The answer is that I have to. Unlike the MS AJAX client-side control DataSource that provides the load and save operation, the XMLDataSource control has supplied us with only a load method, which means we can only read the XML data from the client side. However, in this case, since we want to write the XML data back to the server side we have to fall back on the original AJAX technique—to manually send back the XML data to the server side still, but in the AJAX way. Next, we will delve into them from the client side and the server side, respectively.

Please check back tomorrow for the conclusion to this article.

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 2 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials