Calling Methods in Another Web Form

Problem: You wrote a function in a Web Form that reads a directory and returns a list of subfolders and files in that directory as an ArrayList of Directoryinfo and Fileinfo objects; now you want to use it in another Web Form. Can you call it from the original Web Form or must you move it to a class?

This will be a short section, because it requires only a twist in your point of view. Typically, you work with Web Forms individually. The framework defaults to posting data for a specific form back to the same Web Form, so you can handle control events and user input. But that also tends to coerce people to write code in event handlers—and that leads to problems with code reuse. Here's the twist. A Web Form is nothing but a class, so you can instantiate one the same way that you instantiate any other class: by calling the class constructor.

The question isn't so much whether you can call functions or raise events in another Web Form; it's whether you should. There's a significant overhead involved with creating a Web Form instance as opposed to creating a class instance that doesn't interact with the ASP.NET runtime, which doesn't have to raise all the Web Form events and create the child controls. Therefore, you'll have to decide if the performance hit is more important to you than keeping the code in the original Web Form. If you decide you want to do this, here's an example you can refer to.

The Web Form ch11-4.aspx contains a getFiles function that accepts a path. If the path exists, the function returns an ArrayList filled with Directoryinfo and Fileinfo objects bound to the subdirectories and files in the specified path.

public ArrayList getFiles(String rootpath) { ArrayList files;

Directoryinfo diRoot = new Directorylnfo(rootpath); if (diRoot.Exists) {

// get the subfolders and files files = new ArrayList();

files.AddRange(diRoot.GetFileSysteminfos()); return (files);

throw (new DirectoryNotFoundException());

After obtaining the ArrayList, the ch11-4.aspx Web Form displays the name of each file or directory in the list by wrapping each item in a <span> tag. It formats directories in bold text and all other files in normal text.

private void Page Load(object sender, System.EventArgs e) { ArrayList files = getFiles(MapPath(".")); foreach (Object o in files) {

if ((o.GetType()).Name == "Directoryinfo") {

Response.Write("<span class=\"smallfont\" " + "style=\"font-weight:bold\">" +

((Directoryinfo) o).Name + "</span><br>"); }

Response.Write("<span class=\"smallfont\" " + "style=\"font-weight:normal\">" +

((Fileinfo) o).Name + "</span><br>"); }

The Web Form ch11-5.aspx does exactly the same thing but uses the method from the Web Form ch11-4.aspx. Note that the class name is not the same as the filename—Visual Studio automatically changes the dashes in the filenames to underscores, so the class name for the Web Form ch11-4.aspx is ch11_4.

private void Page Load(object sender, System.EventArgs e) {

ch11 4 otherWebForm = new ch11 4(); System.Web.HttpResponse resp =

System.Web.HttpContext.Current.Response; ArrayList files = otherWebForm.getFiles(MapPath(".")); foreach(object o in files) {

if (o.GetType() == typeof(System.IO.DirectoryInfo)) { Response.Write("<span class=\"smallfont\" " + "style=\"font-weight:bold\">" +

((System.IO.DirectoryInfo) o).Name + "</span><br>");

else if (o.GetType() == typeof(System.IO.FileInfo)) { Response.Write("<span class=\"smallfont\" " + "style=\"font-weight:normal\">" + ((System.IO.FileInfo) o).Name + "</span><br>");

The only difference between the Page_Load event code for the two Web Forms is that the ch11-5.aspx version creates a new ch11_4 class instance and assigns it to a variable called otherWebForm. The ch11-5 Web Form uses that instance to access the getFiles function. Other than that, the display code is identical. If you run the two Web Forms, you'll see that they produce identical results (see Figures 11.8 and 11.9).

Figure 11.8: Output from the ch11-4.aspx Web Form

Figure 11.9: Output from the ch11-5.aspx Web Form using the getFiles method from the class ch11 4

Figure 11.9: Output from the ch11-5.aspx Web Form using the getFiles method from the class ch11 4

The question that may come to your mind when you see code like this is: Why didn't the programmer wrap the code that displays the lists in a method? Good question! You should try it. Write a subroutine to display an ArrayList populated with Filelnfo and Directorylnfo objects in ch11-4.aspx. You could call the subroutine showFiles:

public void showFiles(ArrayList files) { foreach (Object o in files) {

if (o.GetType().Name == "Directorylnfo") {

Response.Write("<span class=\"smallfont\" " + "style=\"font-weight:bold\">" +

((Directorylnfo) o).Name + "</span><br>"); }

else if (o.GetType().Name == "Filelnfo") {

Response.Write("<span class=\"smallfont\" " + "style=\"font-weight:normal\">" +

((Filelnfo) o).Name + "</span><br>"); }

Note The preceding subroutine exists in the CSharpASP project—it's just an example.

That does clarify things. You could simplify the Page_Load event for ch11-4 so it looks like this:

// Simplified Page Load method for the ch11-4 Web Form private void Page Load(object sender, System.EventArgs e) { ArrayList files = getFiles(MapPath(".")); showFiles(files);

That's certainly easier to read. Now you can also eliminate the display code in the Web Form ch11-5

Page_Load:

// Simplified Page Load method for the ch11-5 Web Form private void Page Load(object sender, System.EventArgs e) {

ch11 4 otherWebForm = new ch11 4();

ArrayList files = otherWebForm.getFiles(MapPath(".")); otherWebForm.showFiles(files);

If you enter this code and then compile and run the altered project, you'll get a null reference error because the ch11-4 Web Form doesn't have an instance of the Response object. This is an important point. Instantiating a Web Form using the New constructor does not follow the normal ASP.NET initialization procedure.

That's easy to fix. You could rewrite the ch11-4.aspx method showFiles to accept a Response object as a parameter:

public void showFiles(ArrayList files, HttpResponse resp) { // code here;

You would then call the method by passing the Response object: otherWebForm.showFiles(files, Response);

Alternatively, you could rewrite the method to retrieve the Response object from the current context:

public void showFiles(ArrayList files) { System.Web.HttpReponse resp =

System.Web.HttpContext.Current.Response foreach (Object o in files) {

if (o.GetType().Name == "Directorylnfo") {

resp.Write("<span class=\"smallfont\" " + "style=\"font-weight:bold\">" + ((Directorylnfo) o).Name + "</span><br>");

else if (o.GetType().Name == "FileInfo") {

resp.Write("<span class=\"smallfont\" " + "style=\"font-weight:normal\">" +

((FileInfo) o).Name + "</span><br>"); }

Using either alternative, you can now use the method from another Web Form. But once more, you have to ask yourself if it's worthwhile to alter the method in the Web Form as opposed to creating a separate class.

Was this article helpful?

0 0

Post a comment