- Same Old Data
- The Basic Edit Example
- Putting It Together
- Example Web Interface
Example Web Interface
A library is never complete until it is actually used by an interface. Listing 3 gives the C# code to exercise the new features added to ContactManager. Save this code to a default.aspx file under the working Webroot you've been using to work through the code. If everything is compiled and set up correctly, this code should work immediately on first request. Otherwise, verify that contacts.xml exists under the Webroot (or modify the LoadMgr with the proper path) and that the test namespace has successfully recompiled. Refer to the .NET documentation for any other problems.
Listing 3: Using the API
<%@Page language="C#" %> <%@Import Namespace="test" %> <html> <script runat="server"> void Submit_Delete_Click(Object sender, EventArgs e) { String szFile = Server.MapPath("contacts.xml"); ContactManager oMgr = LoadMgr(szFile); if (oMgr != null) { int iCtr = Convert.ToInt32(Request.Form["entryctr"]); for(int x = 0; x < iCtr; x++) { String szId = Convert.ToString(x); if (Request.Form["delete_" + szId] == "1") { if (oMgr.DeleteContact(szId)) { msg.InnerHtml += "Deleted " + [ccc] szId + "<b>"; } else { msg.InnerHtml += "Delete of " + szId + [ccc] failed<br>"; } } } oMgr.Flush(); } } void Submit_Add_Click(Object sender, EventArgs e) { if (Request.Form["action"] == "save") // save the contact { String szFile = Server.MapPath("contacts.xml"); ContactManager oMgr = LoadMgr(szFile); if (oMgr != null) { Contact oSave = new Contact(); oSave.szFirstName = Request.Form["firstname"]; oSave.szMiddleName = Request.Form["middlename"]; oSave.szLastName = Request.Form["lastname"]; oSave.szGender = Request.Form["gender"]; String szInit = String.Empty; szInit = oSave.szFirstName.Substring(0, 1); szInit += oSave.szMiddleName.Substring(0, 1); szInit += oSave.szLastName.Substring(0, 1); oSave.szInitials = szInit; oMgr.AddContact(oSave); // Done saving the contact. // Redirect to view changes. Response.Redirect("/default.aspx"); } } else { // otherwise display a form for a new contact. action.Value = "save"; HtmlTableCell oTdHd1 = new HtmlTableCell(); HtmlTableCell oTdHd2 = new HtmlTableCell(); HtmlTableCell oTdHd3 = new HtmlTableCell(); HtmlTableCell oTdTxt1 = new HtmlTableCell(); HtmlTableCell oTdTxt2 = new HtmlTableCell(); HtmlTableCell oTdTxt3 = new HtmlTableCell(); TextBox oFirst = new TextBox(); oFirst.ID = "firstname"; TextBox oMiddle = new TextBox(); oMiddle.ID = "middlename"; TextBox oLast = new TextBox(); oLast.ID = "lastname"; oTdTxt1.Controls.Add(oFirst); oTdTxt2.Controls.Add(oMiddle); oTdTxt3.Controls.Add(oLast); HtmlTableRow oTrHd = new HtmlTableRow(); oTdHd1.InnerHtml = "<b>First</b>"; oTdHd2.InnerHtml = "<b>Middle</b>"; oTdHd3.InnerHtml = "<b>Last</b>"; HtmlTableRow oTr2 = new HtmlTableRow(); HtmlTableCell oTdGenders = new HtmlTableCell(); HtmlSelect oGenders = new HtmlSelect(); oGenders.Items.Add("Female"); oGenders.Items.Add("Male"); oGenders.ID = "gender"; oTdGenders.Controls.Add(oGenders); oTr2.Cells.Add(oTdGenders); oTrHd.Cells.Add(oTdHd1); oTrHd.Cells.Add(oTdHd2); oTrHd.Cells.Add(oTdHd3); HtmlTableRow oTr = new HtmlTableRow(); oTr.Cells.Add(oTdTxt1); oTr.Cells.Add(oTdTxt2); oTr.Cells.Add(oTdTxt3); oTable.Rows.Add(oTrHd); oTable.Rows.Add(oTr); oTable.Rows.Add(oTr2); } } void Page_Load(Object sender, EventArgs e) { if (!IsPostBack) { String szFile = Server.MapPath("contacts.xml"); ContactManager oMgr = LoadMgr(szFile); if (oMgr != null) { int iCtr = oMgr.Count(); Trace.Write("Page_Load", "Contact Count = " + [ccc] Convert.ToString(iCtr)); entryctr.Value = Convert.ToString(iCtr); for(int x = 0; x < iCtr; x++) { Contact pTemp = oMgr.GetContact(x); HtmlTableCell oTd1 = new HtmlTableCell(); HtmlTableCell oTd2 = new HtmlTableCell(); HtmlInputCheckBox oCheck = new HtmlInputCheckBox(); oCheck.ID = "delete_" + Convert.ToString(x); oCheck.Value = "1"; oTd1.Controls.Add(oCheck); oTd2.InnerHtml = pTemp.szFirstName + " " + [ccc] pTemp.szMiddleName + " " + [ccc] pTemp.szLastName + "<br>"; HtmlTableRow oTr = new HtmlTableRow(); oTr.Cells.Add(oTd1); oTr.Cells.Add(oTd2); oTable.Rows.Add(oTr); } } } } private ContactManager LoadMgr(String szFile) { ContactManager oMgr = (ContactManager) Application["CM"]; if (oMgr == null) { oMgr = new ContactManager(szFile, Trace); Application["CM"] = oMgr; } return oMgr; } </script> <body> <table id="oTable" runat="server" /> <input type="submit" value="Delete" name="Delete" runat="server"[ccc] OnServerClick="Submit_Delete_Click"> <input type="submit" value="Add" name="Add" runat="server"[ccc] OnServerClick="Submit_Add_Click"> <input type="hidden" value="display" id="action" runat="server" /> <input type="hidden" value="0" id="entryctr" runat="server" /> </form> <span id="msg" runat="server"></span> <a href="/default.aspx">Home</a> </body> </html>
Once again, the System.Web.UI classes are heavily utilized for their server-side control and state capabilities. Without getting into the intricacies of Web forms, let's view the actual usage. Deletes happen by matching up the entry ID with the user-selected contact to delete. After all deletes are completed, the Flush() method is called. This allows the application to process all the deletes and save them to disk at one time rather than a doing a save for every delete call.
The interface for additions requires a bit of code to represent the editable fields to a user. In Submit_Add_Click (a server-side button click event), an action query-string parameter is used to help determine whether the empty form should be displayed or whether a contact should be saved to disk. When a save actually occurs, the developer has to worry about only creating an instance of Contact, filling it with the necessary data, and finally invoking AddContact on the instance of ContactManager. This technique saves XML coding to create all the required nodes, obeying appropriate rules (business or technical) as they may apply.
As evidenced, deleting is always easier than adding to data. Other areas that a developer may investigate for improvements to the Web contacts application are numerous, but a few are listed below:
Add support for editing phone numbers and addresses.
Build in a copy contact feature. This should be easily accomplished with the AddContact method.
Make the ContactManager class actually support changes. The example currently supports only adds and deletes.
This version takes no initiative to encode the data by XML standards. That would need to be fixed for a fully functional editor.
This concludes the series on basic XML functionality of .NET beta 2. These last two articles do not sum up the other ways to use XML and .NET for an application. As always, use the solution that best fits your needs. At this stage, keep any references handy and watch for newer .NET betas.