C# .NET Web Developer''''s Guide phần 10 pptx

79 255 0
C# .NET Web Developer''''s Guide phần 10 pptx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

716 Chapter 12 • Building a Jokes Web Services /// moderators in the database. /// </summary> /// <remarks> /// Author: Adrian Turtschi; aturtschi@hotmail.com; Sept 2001 /// </remarks> [WebServiceAttribute(Description="The userAdmin web service " + "provides methods to manage users and moderators in the database", Namespace="urn:schemas-syngress-com-soap")] public class userAdmin : System.Web.Services.WebService { // SOAP error handling return document structure /// <value>error document thrown by SOAP exception</value> public XmlDocument soapErrorDoc; /// <value>text node with user-friendly error message</value> public XmlNode xmlFailReasonNode; /// <summary> /// Public class constructor. /// </summary> public userAdmin() { InitializeComponent(); // initialize SOAP error handling return document soapErrorDoc = new System.Xml.XmlDocument(); xmlFailReasonNode = soapErrorDoc.CreateNode(XmlNodeType.Element, "failReason", ""); } } } The code for the addUser() method that adds a new user to the database is shown in Figure 12.22. www.syngress.com Figure 12.21 Continued Building a Jokes Web Services • Chapter 12 717 Figure 12.22 addUser Web Method (userAdmin.asmx.cs) 01: /// <summary> 02: /// The addUser method adds a new user to the database 03: /// </summary> 04: /// <param name='userName' 05: /// type='string' 06: /// desc='name of new user'> 07: /// </param> 08: /// <param name='password' 09: /// type='string' 10: /// desc='password of new user'> 11: /// </param> 12: /// <returns>nothing</returns> 13: [SoapDocumentMethodAttribute(Action="addUser", 14: RequestNamespace="urn:schemas-syngress-com-soap:userAdmin", 15: RequestElementName="addUser", 16: ResponseNamespace="urn:schemas-syngress-com-soap:userAdmin", 17: ResponseElementName="addUserResponse")] 18: [WebMethod(Description="The addUser method adds a new user to " + 19: "the database")] 20: public void addUser(string userName, string password) { 21: userAdminImplement userAdminObj = new userAdminImplement(); 22: try { 23: userAdminObj.addUser(userName, password); 24: // catch jokeExceptions 25: } catch (jokeException e) { 26: throwFault("Fault occurred", e.failReason, userName); 27: } 28: // then, catch general System Exceptions 29: catch (Exception e) { 30 throwFault(e.Message, "F_System", userName); 31: } 32: } www.syngress.com 718 Chapter 12 • Building a Jokes Web Services Note how simple things suddenly become once you have set the stage cor- rectly:You need just two lines to add a new user to the system. Note two things in Figure 12.22: ■ First, some decorations were added to the Web method (which Microsoft calls metadata).They specify the namespaces (lines 14 and 16) and element names (lines 15 and 17) used by the SOAP protocol, as described in Chapter 11. ■ Second, if an exception occurs, you call a custom error handler that returns extended error information as part of a SOAP fault (lines 25 and 26). Error Handling for the Public Web Methods If you look at the code that adds users to the system, you’ll see that throwFault (Figure 12.22, lines 26 and 30) is the name of the method that actually throws a SOAP fault and ends execution of the Web Service method. But it does a whole lot more: ■ The (internal) error code is replaced by a user-friendly error message. ■ A log entry is written to the Application event log. ■ The standard SOAP fault XML document is appended with a custom element, called failReason, where client applications can find the error message to display to users. The details of the throwFault method are shown in Figure 12.23. Figure 12.23 throwFault Method (userAdmin.asmx.cs) /// <summary> /// The throwFault method throws a SOAP fault and ends /// execution of the Web Service method /// </summary> /// <param name='message' /// type='string' /// desc='start of text node of faultstring element in /// SOAP fault message'> /// </param> /// <param name='failReason' www.syngress.com Continued Building a Jokes Web Services • Chapter 12 719 /// type='string' /// desc='text node for custom failReason element in SOAP /// fault message'> /// </param> /// <param name='userName' /// type='string' /// desc='name of registered user'> /// </param> /// <returns>nothing</returns> private void throwFault(string message, string failReason, string userName) { xmlFailReasonNode.AppendChild(soapErrorDoc.CreateTextNode( jokeException.getNiceErrorMessage(failReason))); jokeException.writeEventLogEntry(userName, failReason); throw new SoapException(message, SoapException.ServerFaultCode, Context.Request.Url.AbsoluteUri,null, new System.Xml.XmlNode[]{xmlFailReasonNode}); } For instance, if you try to add a user who is already registered, a SOAP fault will be returned, as pictured in Figure 12.24. www.syngress.com Figure 12.23 Continued Figure 12.24 A SOAP Fault Extended by a Custom XML Element 720 Chapter 12 • Building a Jokes Web Services Creating the Public Web Methods—Administrators The two other public Web methods of the userAdmin Web Service are very sim- ilar in their structure to the addUser Web method; they are the Web method addModerator(), which adds a new moderator to the database, and the Web method checkUser(), which checks if a user or moderator is already defined in the database. Those two methods are presented in Figures 12.25 and 12.26, respectively. Figure 12.25 addModerator Web Method (userAdmin.asmx.cs) /// <summary> /// The addModerator method adds a new moderator to the database /// </summary> /// <param name='userName' /// type='string' /// desc='name of moderator'> /// </param> /// <param name='password' /// type='string' /// desc='password of moderator'> /// </param> /// <param name='newModerator' /// type='string' /// desc='user name of user who will become a moderator'> /// </param> /// <returns>nothing</returns> [SoapDocumentMethodAttribute(Action="addModerator", RequestNamespace="urn:schemas-syngress-com-soap:userAdmin", RequestElementName="addModerator", ResponseNamespace="urn:schemas-syngress-com-soap:userAdmin", ResponseElementName="addModeratorResponse")] [WebMethod(Description="The addModerator method adds a new " + "moderator to the database")] public void addModerator( string userName, string password, string newModerator) { userAdminImplement userAdminObj = new userAdminImplement(); try { www.syngress.com Continued Building a Jokes Web Services • Chapter 12 721 userAdminObj.addModerator(userName, password, newModerator); // catch jokeExceptions } catch (jokeException e) { throwFault("Fault occurred", e.failReason, userName); } // then, catch general System Exceptions catch (Exception e) { throwFault(e.Message, "F_System", userName); } } Figure 12.26 checkUser Web Method (userAdmin.asmx.cs) /// <summary> /// The checkUser method checks if a user or moderator is /// already defined in the database /// </summary> /// <param name='userName' /// type='string' /// desc='name of user or moderator'> /// </param> /// <param name='password' /// type='string' /// desc='password of user or moderator'> /// </param> /// <param name='isModerator' /// type='bool' /// desc='check for moderator status (if false, we do /// not check)'> /// </param> /// <returns>nothing</returns> [SoapDocumentMethodAttribute(Action="checkUser", RequestNamespace="urn:schemas-syngress-com-soap:userAdmin", www.syngress.com Figure 12.25 Continued Continued 722 Chapter 12 • Building a Jokes Web Services RequestElementName="checkUser", ResponseNamespace="urn:schemas-syngress-com-soap:userAdmin", ResponseElementName="checkUserResponse")] [WebMethod(Description="The checkUser method checks if a user " + "or moderator is already defined in the database")] public void checkUser( string userName, string password, bool isModerator) { userAdminImplement userAdminObj = new userAdminImplement(); try { userAdminObj.checkUser(userName, password, isModerator); // catch jokeExceptions } catch (jokeException e) { throwFault("Fault occurred", e.failReason, userName); } // then, catch general System Exceptions catch (Exception e) { throwFault(e.Message, "F_System", userName); } } Et voilà! You’re done with your first “real”Web Service: the userAdmin We b Service, which is the user administration module for the Jokes application. Testing the Public Web Methods You can immediately check if things work properly by calling it from a Visual Basic script, as described in Chapter 11.The VBS script shown in Figure 12.27 will add a new user. Figure 12.27 A Simple Visual Basic Script to Test Adding a New User to the Database myWebService = "http://localhost/Jokes1/userAdmin.asmx" myMethod = "addUser" '** create the SOAP envelope with the request www.syngress.com Figure 12.26 Continued Continued Building a Jokes Web Services • Chapter 12 723 myData = "" myData = myData & "<?xml version=""1.0"" encoding=""utf-8""?>" myData = myData & "<soap:Envelope xmlns:soap=""http://schemas." myData = myData & "xmlsoap.org/soap/envelope/"">" myData = myData & " <soap:Body>" myData = myData & " <addUser xmlns=""urn:schemas-syngress-" myData = myData & "com-soap:userAdmin"">" myData = myData & " <userName>newUser</userName>" myData = myData & " <password>newPassword</password>" myData = myData & " </addUser>" myData = myData & " </soap:Body>" myData = myData & "</soap:Envelope>" msgbox(myData) set requestHTTP = CreateObject("Microsoft.XMLHTTP") msgbox("xmlhttp object created") requestHTTP.open "POST", myWebService, false requestHTTP.setrequestheader "Content-Type", "text/xml" requestHTTP.setrequestheader "SOAPAction", myMethod requestHTTP.Send myData msgbox("request sent") set responseDocument = requestHTTP.responseXML msgbox(requestHTTP.status) msgbox(responseDocument.xml) If things go right, a new user should be added to the database, and a message box depicting a SOAP return envelope should appear, as shown in Figure 12.28. www.syngress.com Figure 12.27 Continued 724 Chapter 12 • Building a Jokes Web Services Developing the Jokes Service The second Web Service to develop is the jokes Web Service.The main feature of this Web Service is that it lets registered users retrieve jokes.Additionally, it con- tains methods to administer jokes, such as adding and removing jokes, approving jokes submitted by users to be visible to other users, and giving users a way to rate existing jokes. In many respects, things are set up in parallel from what you have already seen in the userAdmin Web Service, which is the Web Service to manage user information. Best Practices for Returning Highly Structured Data Compared with the userAdmin Web Service you have just developed, the jokes Web Service has one key additional difficulty: how to return joke data.The requirements are as follows: ■ Return anywhere from 1 to 10 jokes. ■ Along with each joke, return its average user rating and the joke identi- fier (for future reference, if for example a user wants to rate that joke). From the stored procedure sp_getJokes, you can get a SQL record set. One possibility, then, is to simply return the jokes as “record sets” (the correct term here is objects of type System.Data.DataSet).This magic works because the .NET SOAP serializer, which is the piece of code that puts the data in XML format to be sent back inside a SOAP return envelope, can indeed serialize that kind of data out of the box. However, as we discussed in Chapter 11, returning serialized DataSets may often not be a good idea because in practice it pretty much forces your clients to run on a Microsoft .NET platform, counter to the idea of Web Services to be an open standard. www.syngress.com Figure 12.28 A Successful Call to Add a New Registered User Building a Jokes Web Services • Chapter 12 725 What alternatives do you have? Again, our advice is to use a simple structure adapted to the problem at hand. If you want your clients to validate the XML against a DTD or an XML Schema, you can always pass that information as a URL (maybe to another Web Service!), but don’t pass that information by default with every call to the client. In your case, you simply pass a structure that looks essentially like everything above starting from the NewDataSet element; that is, you want an XML element delineating rows of data, and additional XML ele- ments delineating the fields of data within each row of data. This is done very simply by creating a custom C# class, the xmlJokesReturn class, which is designed to hold a single row of data, as shown in Figure 12.29. Of course, if you prefer, you could achieve the same thing by using a structure. Figure 12.29 The xmlJokesReturn Class That Holds the Jokes (xmlJokesReturn.cs) using System; namespace jokesService { /// <summary> /// The xmlJokesReturn class is the return type of all public /// methods returning joke data. /// </summary> /// <remarks> /// Author: Adrian Turtschi; aturtschi@hotmail.com; Sept 2001 /// </remarks> public class xmlJokesReturn { /// <value>ID of joke returned</value> public string jokeID; /// <value>the actual joke</value> public string joke; /// <value>average rating of the joke (can be empty)</value> public string rating; /// <summary> /// Public class constructor. www.syngress.com Continued [...]... Jokes Web Services Figure 12.40 Continued if(rowCount > 0) { return myJokes; } else { throw new jokeException("F_noJokes"); } // catch problems with the database } catch (Exception e) { throw e; } } Creating the Public Web Methods You are now finished with the internal methods, and you can now go about implementing the public Web methods for the jokes Web Service Remember that you put all of those Web. .. moderator if (retCode != "S_OK") { Continued www.syngress.com Building a Jokes Web Services • Chapter 12 Figure 12.40 Continued sqlCommand.Connection.Close(); throw new jokeException(retCode); } // retrieve the first unmoderated jokes // maximum is 10 jokes if((howMany < 1) || (howMany > 10) ) { throw new jokeException("F_10JokesMax"); } sqlCommand.Parameters.Clear(); createSqlReturnJokes( howMany.ToString(),... Chapter 12 • Building a Jokes Web Services Figure 12.29 Continued /// public xmlJokesReturn() { } } } Because you may return more than one row of data, of course, you can simply set up the getJokes Web method to return an array of objects of type xmlJokesReturn.The SOAP serializer does the rest automatically In Figure 12.30, you can see the definition of the getJokes Web method (note that we haven’t... // exit, if user not registered if (retCode != "S_OK") { sqlCommand.Connection.Close(); throw new jokeException(retCode); } // retrieve a random joke // maximum is 10 jokes if((howMany < 1) || (howMany > 10) ) { throw new jokeException("F_10JokesMax"); } sqlCommand.Parameters.Clear(); createSqlReturnJokes( howMany.ToString(), "true", "true", sqlCommand); sqlCommand.ExecuteNonQuery(); sqlCommand.Connection.Close();... automatically In Figure 12.30, you can see the definition of the getJokes Web method (note that we haven’t talked about the corresponding implementation method yet) Figure 12.30 getJokes Web method (jokes.asmx.cs) [WebMethod] public xmlJokesReturn[] getJokes( string userName, string password, int howMany) { jokesImplement jokesObj = new jokesImplement(); try { xmlJokesReturn[] myJokes = jokesObj.getJokes(userName,... the jokes Web Service Remember that you put all of those Web methods in the jokes class (the file on the CD is jokes.asmx.cs) Figures 12.41 through 12.46 detail the code for those public Web methods Figure 12.41 addJoke Web Method (jokes.asmx.cs) /// /// The addJoke method adds a new joke to the database /// /// /// Continued www.syngress.com Building a Jokes Web Services • Chapter 12 Figure 12.34 Continued /// /// /// the prepared SQL command object . a Jokes Web Services Creating the Public Web Methods—Administrators The two other public Web methods of the userAdmin Web Service are very sim- ilar in their structure to the addUser Web method;. Continued 724 Chapter 12 • Building a Jokes Web Services Developing the Jokes Service The second Web Service to develop is the jokes Web Service.The main feature of this Web Service is that it lets registered. seen in the userAdmin Web Service, which is the Web Service to manage user information. Best Practices for Returning Highly Structured Data Compared with the userAdmin Web Service you have just

Ngày đăng: 12/08/2014, 12:20

Tài liệu cùng người dùng

Tài liệu liên quan