skip to Main Content

I have been asked to write a multi-tiered program that loads and parses 24 student grades from an xml file, and then display all grades, the lowest grade, the highest grade, and the average grade to the web form using graphical user interface form, not Console output. I am using textboxes to display the values on the web page, and my code executes successfully, however, it does not display any values in the textboxes when I run the program – they’re empty. How should I fix this/what am I doing wrong? I am very new to C# so any help would be greatly appreciated as I want to learn how to fix the problem for future programs. This program had to be done using the ASP.NET Web Application template in VS. Below is my webform.aspx file, aspx.cs file, StudentGrade.cs file, and xml file.

StudentGrade.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Web;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Linq;
using System.Text;
using System.IO;
using System.Net;

namespace WebApplication5
{
    class StudentGrade
    {
        public static TextBox AllGrades;
        public static TextBox AverageGrade;
        public static TextBox LowestGrade;
        public static TextBox HighestGrade;
        public static void LoadAndParseStudentGrades()
        {
            //Load XML doc
            XmlDocument doc = new XmlDocument();
            doc.Load("C:\Program Files (x86)\IIS Express\studentGrades.xml");

            //Display all grades
            XmlNodeList grades = doc.SelectNodes("Students/Student/Grade");
            foreach (XmlNode grade in grades)
            {
                 AllGrades.Text = grade.InnerText;

            }
        }

        public static void Average()
        {
            //Get directory and load xml document with XMLpath
            string XMLpath = Directory.GetCurrentDirectory() + @"studentGrades.xml";
            XDocument xmlDoc = XDocument.Load(XMLpath);

            IEnumerable<XElement> gradeElements = xmlDoc.Root.Descendants("Grade");

            //Set the count for grade elements
            int totalCount = gradeElements.Count();

            //Take all grade elements and take the average of them
            double averageGrade = gradeElements.Select(x => (double)x).Average();

            AverageGrade.Text = averageGrade.ToString();

        }

        public static void Lowest()
        {
            //Load XML doc to string
            var xmlString = File.ReadAllText("C:\Program Files (x86)\IIS Express\studentGrades.xml");
            var xDoc = XDocument.Parse(xmlString);
            var grade = xDoc.Descendants("Grade");

            decimal minGrade = decimal.MaxValue;

            //Loop to determine what grade has the lowest value
            for (int i = 0; i < grade.Count(); i++)
            {
                var gr = decimal.Parse(grade.ElementAt(i).Value);
                if (gr < minGrade)
                {
                    minGrade = gr;
                    LowestGrade.Text = gr.ToString();
                }
            }

        }

        public static void Highest()
        {
            //Load XML doc to string
            var xmlString = File.ReadAllText("C:\Program Files (x86)\IIS Express\studentGrades.xml");
            var xDoc = XDocument.Parse(xmlString);
            var grade = xDoc.Descendants("Grade");

            decimal maxGrade = decimal.MinValue;

            //Loop to determine what grade has the highest value
            for (int i = 0; i < grade.Count(); i++)
            {
                var gr = decimal.Parse(grade.ElementAt(i).Value);
                if (gr > maxGrade)
                {
                    maxGrade = gr;
                    HighestGrade.Text = gr.ToString();
                }

            }
        }
    }
}

Webform.aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace WebApplication5 {


    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            StudentGrade.AllGrades = new TextBox();
            StudentGrade.AverageGrade = new TextBox();
            StudentGrade.LowestGrade = new TextBox();    
            StudentGrade.HighestGrade = new TextBox();
        }
    }

}

Webform.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication5.WebForm1" %>
<%@ Import Namespace="WebApplication5" %>
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Student Grades</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label ID="Label1" runat="server" Text="All Grades: "></asp:Label>
            <asp:TextBox ID="AllGrades" runat="server"></asp:TextBox>
            <asp:Label ID="Label4" runat="server" Text="Highest Grade: "></asp:Label>
            <asp:TextBox ID="HighestGrade" runat="server"></asp:TextBox>
            <asp:Label ID="Label2" runat="server" Text="Lowest Grade: "></asp:Label>
            <asp:TextBox ID="LowestGrade" runat="server"></asp:TextBox>
            <asp:Label ID="Label3" runat="server" Text="Average Grade: "></asp:Label>
            <asp:TextBox ID="AverageGrade" runat="server"></asp:TextBox>
        </div>
    </form>
</body>
</html>

studentGrades.xml

<?xml version="1.0" encoding="utf-8"?>

<Students>
    <Student ID ="1">
        <Name>Will</Name>
        <Grade>100</Grade>
    </Student>
    <Student ID ="2">
        <Name>Kaylee</Name>
        <Grade>93</Grade>
    </Student>
    <Student ID ="3">
        <Name>Rick</Name>
        <Grade>77</Grade>
    </Student>
    <Student ID ="4">
        <Name>Carl</Name>
        <Grade>85</Grade>
    </Student>
    <Student ID ="5">
        <Name>Hannah</Name>
        <Grade>91</Grade>
    </Student>
    <Student ID ="6">
        <Name>Tyler</Name>
        <Grade>67</Grade>
    </Student>
    <Student ID ="7">
        <Name>Hunter</Name>
        <Grade>87</Grade>
    </Student>
    <Student ID ="8">
        <Name>Claude</Name>
        <Grade>96</Grade>
    </Student>
    <Student ID ="9">
        <Name>Taylor</Name>
        <Grade>99</Grade>
    </Student>
    <Student ID ="10">
        <Name>Anna</Name>
        <Grade>79</Grade>
    </Student>
    <Student ID ="11">
        <Name>Mike</Name>
        <Grade>82</Grade>
    </Student>
    <Student ID ="12">
        <Name>Jordan</Name>
        <Grade>60</Grade>
    </Student>
    <Student ID ="13">
        <Name>Cam</Name>
        <Grade>75</Grade>
    </Student>
    <Student ID ="14">
        <Name>Bob</Name>
        <Grade>95</Grade>
    </Student>
    <Student ID ="15">
        <Name>Evan</Name>
        <Grade>84</Grade>
    </Student>
    <Student ID ="16">
        <Name>Heather</Name>
        <Grade>88</Grade>
    </Student>
    <Student ID ="17">
        <Name>Kristen</Name>
        <Grade>82</Grade>
    </Student>
    <Student ID ="18">
        <Name>Monica</Name>
        <Grade>58</Grade>
    </Student>
    <Student ID ="19">
        <Name>Brad</Name>
        <Grade>76</Grade>
    </Student>
    <Student ID ="20">
        <Name>Carly</Name>
        <Grade>95</Grade>
    </Student>
    <Student ID ="21">
        <Name>Tom</Name>
        <Grade>69</Grade>
    </Student>
    <Student ID ="22">
        <Name>Marshall</Name>
        <Grade>89</Grade>
    </Student>
    <Student ID ="23">
        <Name>Jeff</Name>
        <Grade>82</Grade>
    </Student>
    <Student ID ="24">
        <Name>Sydney</Name>
        <Grade>91</Grade>
    </Student>
</Students> 

I tried using the textboxes to properly display their respective values, however there seems to be an error somewhere since the web form is not loading any values into the textboxes – just empty textboxes. I have researched online for countless hours and watched many videos yet to no avail. I am still learning C# so this has me a bit confused! What code would fix this issue of the textboxes displaying nothing?

2

Answers


  1. There are several common approaches to dealing with xml data.

    You can consider creating a "class" that represents the data in that xml.

    Or, you can use a dataset, and the so called built-in xml reader.

    So, say we up-loaded the file to the web site, saved the xml in a folder called UpLoadFiles, and as students.xml.

    Now, to display that data, we need some markup on the page – somthing that can display repeating rows of data. A grid view would work quite nice.

    So, say this markup:

            <asp:GridView ID="GridView1" runat="server" CssClass="table table-hover"
                width="20%" >
    
            </asp:GridView>
    

    And our code behind to read the xml could be this:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                LoadData();
            }
        }
    
        void LoadData()
        {
            string sFile = Server.MapPath("~/UpLoadFiles/students.xml");
    
            DataSet ds = new DataSet();
            ds.ReadXml(sFile);
            DataTable dt = ds.Tables[0];    
            GridView1.DataSource = dt;
            GridView1.DataBind();
        }
    

    And the result is this:

    enter image description here

    so, how to deal with such xml really depends on what you want to do here.

    Perhaps the end goal is to place that data into a database (maybe sql server).

    However, as a basic start, the above gives some ideas as to how one can read such data into a dataset, (using the built in xml reader).

    From that dataset, your xml does result in a nice table, and thus we send that table directly to the gridview for display.

    Edit: Display max grade, and min grade

    So, right before we display the data, we can have some controls for min grade, and the max grade.

    Say like this:

            <h3>Lowest Grade</h3>            
            ID:<asp:Label ID="lblLoID" runat="server" Text=""></asp:Label> <br />
            Name:<asp:Label ID="lblLoName" runat="server" Text=""></asp:Label> <br />
            Grade:<asp:Label ID="lblLoGrade" runat="server" Text=""></asp:Label> <br />
            <br />
    
            <h3>Highest Grade</h3>            
            ID:<asp:Label ID="lblHiID" runat="server" Text=""></asp:Label> <br />
            Name:<asp:Label ID="lblHiName" runat="server" Text=""></asp:Label> <br />
            Grade:<asp:Label ID="lblHiGrade" runat="server" Text=""></asp:Label> <br />
    
            <h3>Data</h3>
    
            <asp:GridView ID="GridView1" runat="server" CssClass="table table-hover"
     etc. etc. etc.
    

    so, now, our code to get/fetch the min and max values?

    Well, that grade colum is appearin as text, and to sort, then we need a integer value for that.

    So, this code would work:

            GridView1.DataSource = dt;
            GridView1.DataBind();
    
            // to get max or min value, we need integer value, 
            // not a string
            dt.Columns.Add("iGrade", typeof(int));
            foreach (DataRow dr in dt.Rows)
                dr["iGrade"] = Convert.ToInt32(dr["Grade"]);
    
    
            // fill out lowest grade information
            DataRow[] LowGrade = dt.Select("iGrade = min(iGrade)");
    
            lblLoName.Text = LowGrade[0]["Name"].ToString();
            lblLoGrade.Text = LowGrade[0]["Grade"].ToString();
            lblLoID.Text = LowGrade[0]["ID"].ToString();
    
    
            // fill out highest grade information
            DataRow[] HiGrade = dt.Select("iGrade = max(iGrade)");
    
            lblHiName.Text  = HiGrade[0]["Name"].ToString();
            lblHiGrade.Text = HiGrade[0]["Grade"].ToString();
            lblHiID.Text    = HiGrade[0]["ID"].ToString();
    

    And now we see/get this:

    enter image description here

    Login or Signup to reply.
  2. In addition to the answer Albert provided, there was a wrong approach in the codes you have written.

    Basically, you should not put any textbox instances in the StudentGrade class. When you define a class, you need to follow the Separation of Concern rule; therefore in the class StudentGrade, instead of having TextBoxes for AllGrades, AverageGrade, LowestGrade, and HighestGrade, you need to define numeric variables to hold the calculations. then later in your webform, you should use and bind these calculations to the controls you have put in the webform.

    StudentGrade:

    class StudentGrade
        {
            public static float AllGrades;
            public static float AverageGrade;
            public static float LowestGrade;
            public static float HighestGrade;
    
            public static void LoadAndParseStudentGrades()
            {
                //Load XML doc
                XmlDocument doc = new XmlDocument();
                doc.Load("C:\Program Files (x86)\IIS Express\studentGrades.xml");
    
                //Display all grades
                XmlNodeList grades = doc.SelectNodes("Students/Student/Grade");
                foreach (XmlNode grade in grades)
                {
                    AllGrades = float.Parse(grade.InnerText);
    
                }
            }
    
            public static void Average()
            {
                //Get directory and load xml document with XMLpath
                string XMLpath = Directory.GetCurrentDirectory() + @"studentGrades.xml";
                XDocument xmlDoc = XDocument.Load(XMLpath);
    
                IEnumerable<XElement> gradeElements = xmlDoc.Root.Descendants("Grade");
    
                //Set the count for grade elements
                int totalCount = gradeElements.Count();
    
                //Take all grade elements and take the average of them
                double averageGrade = gradeElements.Select(x => (double)x).Average();
    
                AverageGrade = float.Parse(averageGrade.ToString());
    
            }
    
            public static void Lowest()
            {
                //Load XML doc to string
                var xmlString = File.ReadAllText("C:\Program Files (x86)\IIS Express\studentGrades.xml");
                var xDoc = XDocument.Parse(xmlString);
                var grade = xDoc.Descendants("Grade");
    
                decimal minGrade = decimal.MaxValue;
    
                //Loop to determine what grade has the lowest value
                for (int i = 0; i < grade.Count(); i++)
                {
                    var gr = decimal.Parse(grade.ElementAt(i).Value);
                    if (gr < minGrade)
                    {
                        minGrade = gr;
                        LowestGrade = float.Parse(gr.ToString());
                    }
                }
    
            }
    
            public static void Highest()
            {
                //Load XML doc to string
                var xmlString = File.ReadAllText("C:\Program Files (x86)\IIS Express\studentGrades.xml");
                var xDoc = XDocument.Parse(xmlString);
                var grade = xDoc.Descendants("Grade");
    
                decimal maxGrade = decimal.MinValue;
    
                //Loop to determine what grade has the highest value
                for (int i = 0; i < grade.Count(); i++)
                {
                    var gr = decimal.Parse(grade.ElementAt(i).Value);
                    if (gr > maxGrade)
                    {
                        maxGrade = gr;
                        HighestGrade = float.Parse(gr.ToString());
                    }
    
                }
            }
        }
    

    WebForm1

    public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                StudentGrade.LoadAndParseStudentGrades();
                StudentGrade.Average();
                StudentGrade.Lowest();
                StudentGrade.Highest();
    
                AllGrades.Text = StudentGrade.AllGrades.ToString();
                AverageGrade.Text = StudentGrade.AverageGrade.ToString();
                LowestGrade.Text = StudentGrade.LowestGrade.ToString();
                HighestGrade.Text = StudentGrade.HighestGrade.ToString();
            }
        }
    

    Although the class you defined is fine, there is a better approach to implement your situation. I prefer to implement the StudentGrade in a way that your methods return the calculation results instead of setting them to public static values.

    public class StudentGrade
    {
        public float Average()
        {
            //Get directory and load xml document with XMLpath
            string XMLpath = Directory.GetCurrentDirectory() + @"studentGrades.xml";
            XDocument xmlDoc = XDocument.Load(XMLpath);
    
            IEnumerable<XElement> gradeElements = xmlDoc.Root.Descendants("Grade");
    
            //Set the count for grade elements
            int totalCount = gradeElements.Count();
    
            //Take all grade elements and take the average of them
            double averageGrade = gradeElements.Select(x => (double)x).Average();
    
            return float.Parse(averageGrade.ToString());
        }
     }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search