1 / 37

Dr. Rathindra Sarathy

MSIS 5133 Advanced MIS - E-Commerce Spring 2003 Lecture 4: DotNet Technologies - Part 5 Developing Applications – Part 1. Dr. Rathindra Sarathy. Application Level Considerations. Applications and sessions State Maintenance Configuring Applications Tracing and Debugging Error-handling

lieu
Download Presentation

Dr. Rathindra Sarathy

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. MSIS 5133 Advanced MIS - E-CommerceSpring 2003Lecture 4: DotNet Technologies - Part 5Developing Applications – Part 1 Dr. Rathindra Sarathy

  2. Application Level Considerations • Applications and sessions • State Maintenance • Configuring Applications • Tracing and Debugging • Error-handling • Caching • Authentication

  3. Web Application Benefits • A Web application is a group of files and folders (including virtual folders) located under the Web applications root directory • Create application-level and session-level variables that are available to all pages within the Web application • A Web application runs in its own memory space, so that an error in one Web application does not bring down the rest of the Web applications on your server • Maintains information about your session, such as your IP address, what pages you clicked and when, when you visited the site, what browser you are using, and your preferences • Maintains information across the entire Web application with the application object

  4. ASP.Net Application • ASP.NET Framework applications consist of everything under one virtual directory of the Web server. You create an ASP.NET Framework application by adding files to a virtual directory on the Web server. • ASP.NET maintains a pool of HttpApplication instances over the course of a Web application's lifetime. ASP.NET automatically assigns one of these instances to process each incoming HTTP request that is received by the application. • An ASP.NET Framework application is created the first time a request is made to the server; before that, no ASP.NET code executes. When the first request is made, a pool of HttpApplication instances is created and the Application_Start event is raised. The HttpApplication instances process this and subsequent requests, until the last instance exits and the Application_End event is raised. • Use application state variables to store data that is modified infrequently but used often

  5. Using Application Settings in web.config Configuration files are perfectly suited for storing custom application settings, such as database connection strings, file paths, or remote XML Web service URLs. The default configuration sections (defined in the machine.config file) include an <appSettings> section that may be used to store these settings as name/value pairs. <configuration> <appSettings> <add key="pubs" value="server=(local)\NetSDK;database=pubs;Trusted_Connection=yes" /> <add key="northwind" value="server=(local)\NetSDK;database=northwind;Trusted_Connection=yes" /> </appSettings> </configuration> The ConfigurationSettings object exposes a special AppSettings property that can be used to retrieve these settings:

  6. Using the web.config in application code <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <%@ Import Namespace="System.Configuration" %> <html> <script language="VB" runat="server"> Sub Page_Load(Src As Object, E As EventArgs) Dim dsn As String = ConfigurationSettings.AppSettings("pubs") Dim MyConnection As SqlConnection Dim MyCommand As SqlDataAdapter MyConnection = New SqlConnection(DSN) MyCommand = New SqlDataAdapter("select * from Authors", MyConnection) Dim DS As New DataSet MyCommand.Fill(DS, "Authors") MyDataGrid.DataSource= New DataView(DS.Tables(0)) MyDataGrid.DataBind() End Sub </script>

  7. Maintaining State • Can be configured within controls themselves using hidden fields - This means that the controls automatically retain their state between page postbacks without any programming intervention • Additionally, ASP.NET provides three types of state to Web applications: application, session, and user. • All the state management services are implemented as HTTP modules • Application state, as in ASP, is specific to an application instance and is not persisted. • Session state is specific to a user session with the application. • User state resembles session state, but generally does not time out and is persisted. Thus user state is useful for storing user preferences and other personalization information. The Programmable Web Web Services Provides Building Blocks for the Microsoft .NET Framework -- MSDN Magazine, September 2000

  8. Maintaining State in an ASP.NET Application • Three methods that use a unique identifier to recognize the client across Web pages: • ASP.NET uses Application and Session objects - store data and require session support • Client-side cookies - small files stored on the client’s system • Cookieless applications – applications do not require the user to support client-side or server-side cookies as the identification data is passed with the URL. Stores the data with the request

  9. Sample Global.asax file • Global.asax contains information on what happens when applications, sessions (& requests) start and end. • Global.asax itself compiled into .NET assembly. Can use code inside <script language="VB" runat="server"> Sub Application_Start(Sender As Object, E As EventArgs) ' Do application startup code here End Sub Sub Application_End(Sender As Object, E As EventArgs) ' Clean up application resources here End Sub Sub Session_Start(Sender As Object, E As EventArgs) Response.Write("Session is Starting...<br>") End Sub Sub Session_End(Sender As Object, E As EventArgs) ' Clean up session resources here End Sub Sub Application_BeginRequest(Sender As Object, E As EventArgs) Response.Write("<h3><font face='Verdana'>Using the Global.asax File</font></h3>") Response.Write("Request is Starting...<br>") End Sub Sub Application_EndRequest(Sender As Object, E As EventArgs) Response.Write("Request is Ending...<br>") End Sub Sub Application_Error(Sender As Object, E As EventArgs) Context.ClearError() Response.Redirect("errorpage.htm") End Sub </script>

  10. Creating Reusable Data in Global.asax <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.IO" %> <script language="VB" runat="server"> Sub Application_Start(Sender As Object, E As EventArgs) Dim DS As New DataSet Dim FS As FileStream FS = New FileStream(Server.MapPath("schemadata.xml"),FileMode.Open,FileAccess.Read) Dim Reader As StreamReader Reader = New StreamReader(FS) DS.ReadXml(Reader) FS.Close() Dim View As DataView View = New DataView(ds.Tables(0)) Application("Source") = View End Sub </script> Sub Page_Load(Src As Object, E As EventArgs) Dim Source As DataView = Application("Source") MySpan.Controls.Add(New LiteralControl(Source.Table.TableName)) MyDataGrid.DataSource = Source MyDataGrid.DataBind() End Sub

  11. Session state • In the machine.config and the web.config files, the sessionState node allows you to configure the session management • Storing session data in the Web Server memory results in the best performance • The mode property is used to identify which storage method to use to store session data • Off - turns off session management • InProc - the data is stored in process with the Web Server • StateServer - stores the data with a Windows service called StateServer • To provide individual data for a user during a session, data can be stored with session scope • Configuring session state: Session state features can be configured via the <sessionState> section in a web.config file. To double the default timeout of 20 minutes, you can add the following to the web.config file of an application: <sessionState timeout="40“ /> • If cookies are not available, a session can be tracked by adding a session identifier to the URL. This can be enabled by setting the following: <sessionState cookieless="true“ /> • Use session state variables to store data that is specific to one session or user. The data is stored entirely on the server. Use it for short-lived, bulky, or sensitive data. • Use the Class: System.Web.SessionState.HttpSessionState

  12. Storing and Using Session Data • Session data can be stored in databases and used for data mining • SessionID, a unique identifier that identifies each session • You need only one identifier such as login ID or IP address - then all previous session data can be retrieved • UsersTable - UserID and password fields • SessionDataTable - information gathered from each session • UserIDfield - links between the tables

  13. Client-side and HTTP Cookies • Client-side cookies use the browser document object manipulated by client-side code such as javascript • HTTP cookies are written by the server. They still use the browser document object to eventually write/read cookie.

  14. HTTP Cookies • HTTP cookies are cookies created by the Web server rather than the browser • The SessionID is the value of the HTTP cookie that identifies the client’s session • This SessionID is used to identify a Session object on the server • Retrieve a cookie from the HTTP header using the server variable HTTP_COOKIE from a Web page using the server variables that has Trace enabled • The HttpCookieCollection object represents the cookie variables • One type of cookie collection contains cookies that have been generated on the server and transmitted to the client in the Set-Cookie header • The Response.Cookies method actually sends the cookie to the browser, which in turn writes the cookie to the client’s file system • The named group of cookies is also referred to as a dictionary cookie, and the individual cookies within it are sometimes referred to as cookie keys • Internet Explorer 5 - users can disable client side cookies, and still allow HTTP cookies. • Internet Explorer 6 - the cookie settings have been moved from the Security settings to a Privacy Settings

  15. HTTP Cookies • Storing cookies on the client is one of the methods that ASP.NET's session state uses to associate requests with sessions. Cookies can also be used directly to persist data between requests, but the data is then stored on the client and sent to the server with every request. Browsers place limits on the size of a cookie; therefore, only a maximum of 4096 bytes is guaranteed to be acceptable. • To make a cookie persistent between sessions, the Expires property on the HttpCookie class has to be set to a date in the future. Protected Sub Submit_Click(sender As Object, e As EventArgs) Dim cookie As New HttpCookie("preferences2") cookie.Values.Add("ForeColor",ForeColor.Value) ... cookie.Expires = DateTime.MaxValue ' Never Expires Response.AppendCookie(cookie) Response.Redirect(State("Referer").ToString()) End Sub • Store small amounts of volatile data in a nonpersistent cookie. The data is stored on the client, sent to the server on each request, and expires when the client ends execution. • Store small amounts of non-volatile data in a persistent cookie. The data is stored on the client until it expires and is sent to the server on each request.

  16. Retrieving HTTP Cookies with ASP.NET • Retrieve a cookie’s value—whether from a simple cookie or from a group of cookies—using the Request object <% Request.Cookies(“CookieName”) %> • To retrieve the value of a single cookie from a group of cookies, you must identify the name of the cookie group as well as the name of the individual cookie <% Request.Cookies("GroupID")(“CookieName_n”) %> • You can add additional cookies to the HTTP cookies Dim MyCookie As New HttpCookie("CookieEmail") MyCookie.Value = txtEmail.Value Response.Cookies.Add(MyCookie)

  17. Maintaining State Without HTTP Cookies • HTTP cookies were used to link the client’s session to the Session object using the SessionID • The Session timeout property specifies when the session ends if no activity occurs • The default value for the session timeout is 20 minutes • The process of creating a cookieless application is known as cookie munging • The cookieless property in the sessionState node in the web.config file is used to determine if the session key should require cookies • The Web Server appends any requested URL with the Session ID

  18. The ViewState Property of Server Controls • ASP.NET provides the server-side notion of a view state for each control. • A control can save its internal state between requests using the ViewState property on an instance of the class StateBag. • The StateBag class provides a dictionary-like interface to store objects associated with a string key. • Occasionally your pages will contain UI state values that aren't stored by a control. You can track values in ViewState using a programming syntax is similar to that for Session and Cache: ' save in ViewState ViewState("SortOrder") = "DESC" ' read from ViewState Dim SortOrder As String = CStr(ViewState("SortOrder")) • Store small amounts of request-specific data in the view state. The data is sent from the server to the client and back.

  19. Web Server Configuration Files • XML-based • Global machine-level configuration file - named machine.cfg located in C:\WINNT\Microsoft.NET\Framework\v1.0. 3705\CONFIG\machine.config • Application configuration files - named Web.config • About thirty configuration settings configured as a node, and may include nested child nodes • root node - of the file is <configuration> • ConfigSections node - is used to identify the configuration sections and section groups • system.web section group - delineates Web configuration settings • Sample Tags • <sessionState> - Responsible for configuring the session state HTTP module. • <globalization> - Responsible for configuring the globalization settings of an application. • <compilation> - Responsible for all compilation settings used by ASP.NET. • <trace> - Responsible for configuring the ASP.NET trace service. • <browserCaps> - Responsible for controlling the settings of the browser capabilities component.

  20. BrowserCaps (can also be in Machine.config) <%@ Page Language="VB" %> <html> <body style="font: 10pt verdana"> <h3>Retrieving Browser Capabilities</h3> Boolean ActiveXControls = <%=Request.Browser.ActiveXControls.ToString()%><br> Boolean BackgroundSounds = <%=Request.Browser.BackgroundSounds.ToString()%><br> Boolean Beta = <%=Request.Browser.Beta.ToString()%><br> String Browser = <%=Request.Browser.Browser%><br> Boolean CDF = <%=Request.Browser.CDF.ToString()%><br> Boolean Cookies = <%=Request.Browser.Cookies.ToString()%><br> Boolean Frames = <%=Request.Browser.Frames.ToString()%><br> Boolean JavaApplets = <%=Request.Browser.JavaApplets.ToString()%><br> Boolean JavaScript = <%=Request.Browser.JavaScript.ToString()%><br> Int32 MajorVersion = <%=Request.Browser.MajorVersion.ToString()%><br> Double MinorVersion = <%=Request.Browser.MinorVersion.ToString()%><br> String Platform = <%=Request.Browser.Platform%><br> Boolean Tables = <%=Request.Browser.Tables.ToString()%><br> String Type = <%=Request.Browser.Type%><br> Boolean VBScript = <%=Request.Browser.VBScript.ToString()%><br> String Version = <%=Request.Browser.Version%><br> </body> </html> <!-- For updates to this browser data visit cyScape, Inc. at http://www.cyscape.com/browsercaps --> <browserCaps> <result type="System.Web.HttpBrowserCapabilities" /> <use var="HTTP_USER_AGENT" /> browser=Unknown version=0.0 majorversion=0 minorversion=0 frames=false tables=false cookies=false backgroundsounds=false vbscript=false javascript=false javaapplets=false activexcontrols=false … xml=false

  21. Pages Configuration Node • Allows you to configure settings that control how content is delivered to the Web page • Bufferis an area in memory on the server • enableSessionState allows you to use the Session capabilities of ASP.NET • enableViewState is used to store data in the _VIEWSTATE hidden form field in the Web page • enableViewStateMac is used to validate data using a one-way authentication code based on the MAC address of the server • autoEventWireup allows you to override the Page_OnLoad event The httpRuntime Configuration Node • Properties: • executionTimeout is the time that a resource is allowed to execute before the request times out • maxRequestLength is the number of kilobytes that can be accepted from an HTTP request • UseFullyQualifiedRedirectURL property is used to fully qualify the URL when the client has been redirected to a new page

  22. The AppSettings Configuration Node (also see earlier) • To configure custom key/value pairs known as application variables <appSettings> <add key="SN" value="Tara Store" /> <add key="CS" value="Provider=Microsoft.Jet.OLEDB.4.0; Password=''; User ID=Admin; Data Source= C:\Inetpub\wwwroot\Ch8\TS.mdb;" /> </appSettings>

  23. Compiler Node Configuration • Settings related to the language compilers use to build the application • defaultLanguage property changes the default compiler from Visual Basic .NET <%@ Page Language="vb"> • debug property is used to configure the application to show the source code files when you are debugging the application • explicit property requires you to declare your variables before they are used • strict property requires you to declare the data type of a variable before it is used

  24. Trace Node Configuration • Identify the data sent during a request or response. • Enable Tracing for a specific page <%@ Page trace=true Language="vb" AutoEventWireup="false" Codebehind="Write_Trace_Info.aspx.vb" Inherits="Opt_Monitor.Write_Trace_Info"%> • enabled property - allows the application to turn tracing on. Tracing information will be stored. Information can be accessed through http://site/trace.axd • localOnly property - results are only displayed to the localhost at http://localhost/. • traceMode property - allows you to sort trace results based on time using SortByTime or by category using SortByCategory • pageOutput property - allows you to display the trace results at the bottom of Web page • trace utility program - access the tracing data stored in memory using TraceTool • requestLimit property - number of trace results stored • Configuration Setting: <trace enabled=“true" requestLimit="10" pageOutput=“true" traceMode="SortByTime" />

  25. Debugging using TRACE • Page and Application tracing • Easy to include “debug” statements • Add trace directive at top of page - <%@ Page Trace=“True”%> • Trace.write • to write data to the trace stack • trace.write("CategoryName", "Value") method • CategoryName - a string that contains the text label to be displayed in the trace output • value - a string that contains the data and appears in the Message column • Add trace calls throughout page • Trace.Write(“MyApp”, “Button Clicked”) • Trace.Warn(“MyApp”, “Value: “ + value) • Collect request details • Server control tree • Server variables, headers, cookies • Form/Querystring parameters • Access page from browser • Access tracing URL within app • http://localhost/approot/Trace.axd orat localhost/Configuration/Tracing/TraceTool/trace.axd

  26. Using the Exception Classes to Identify Errors • .NET System class contains an Exception class that is base class for all exceptions • An exception is an object that is thrown when a predefined error occurs • The SystemException class is the base class for all predefined exceptions • The ApplicationException class provides a base class to create user-defined exception objects • Common exceptions that are handled with the Try-Catch-Finally statement include the SqlException, OleDbException, NullReferenceException, and IndexOutOfRangeException exceptions • SqlException is thrown when an error occurs from the SQL Server DataAdapter • This exception is often thrown when the database server does not exist • The OleDbException is thrown when an error occurs from the OleDbDataAdapter • The NullReferenceException is thrown when null object is referenced • The IndexOutOfRangeException is thrown when an Array object is improperly indexed • The ExternalException class allows other classes to indirectly inherit from the SystemException class • When the Exception object is created from the SystemEXception class, several properties and methods are exposed that can help identify the source of the error • Properties are exposed from objects derived from the SystemException class • The Message property (returns error message) - TargetSite property (method name that threw error) • Helplink property (helpfile name) - StackTrace property (location in stack) • InnerException property (first exception in stack) - ToString method

  27. Application-level Error Handling • You can retrieve information about an exception that was thrown from the HttpContext class • The ToString method provides the details of the exception object • To retrieve the last exception thrown by the application, you can use the GetLastError method from the HttpServerUtility class • You can clear all errors from the application using the ClearError method from the HttpContext class • You can redirect the client to a new URL when a general exception occurs by using the Error property of the HttpContext class Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) ' Fires when an error occurs Context.ClearError() Dim EM As String = Server.GetLastError.Message() Dim EHL As String = Server.GetLastError.HelpLink() Dim AST As String = Server.GetLastError.StackTrace() Dim ETS As String = Server.GetLastError.ToString() Context.ClearError() Response.Redirect("CustomError.aspx?" & _ "EM=" & Server.UrlEncode(EM) & _ "&EHL=" & Server.UrlEncode(EHL) & _ "&AST=" & Server.UrlEncode(AST) & _ "&ETS=" & Server.UrlEncode(ETS)) End Sub In Global.asax.vb

  28. Using the Try-Catch-Finally to Handle Specific Errors • The Try-Catch-Finally statement allows you to attempt to run a block of code that detects when an error has occurred • The goal of the Try-Catch-Finally statement is to gracefully recover when an exception occurs • The Try statement attempts to run a block of code • If there is an error, an exception object is created • The Catch statement catches the error as an exception object • You can use the Catch statement multiple times to catch multiple types of errors • The Finally statement allows you to execute a block of code

  29. Caching • Page Output Caching: • Pages That Don’t Change Frequently • Dramatic Performance Increase <%@ OutputCache Duration= "500" %> • Fragment Caching • Dynamic Portions of a Page - Data That Doesn’t Change Frequently • User Control <%@ OutputCache Duration=“60" %> • Programmatically Cache Data Cache.Insert( Key, Value, CacheDependency, _ AbsoluteExpiration, SlidingExpiration, Priority, PriorityDecay, Callback) Key = String used to look up the cached item Value = Item or object to store in the cache CacheDependency = Cache item can automatically expire when a file, directory, or other cache item changes AbsoluteExpiration = Cache item can expire at some fixed time (midnight, for example) SlidingExpiration = Cache item can expire after a certain amount of inactivity Priority = When forcing items from the cache, which items should go first PriorityDecay = Within a given priority range, does this item expire fast or slow

  30. Page Output Caching • Page Output Caching - technique of caching ASP.NET pages on Web server • When a Web page is compiled, the page is stored on the server in the cache, When another request is made for the same page, the page from the cache is returned to the client • Storing Web pages in cache increases performance of Web application • Configure Page Output Cache in Web page by using OutPutCache directive • Parameters that configure Page Output Cache include Duration & VaryByParam • The Duration identifies how long the document is left in cache (in seconds) • Use VaryByParam property to cache parameters passed with page request • There are additional techniques that allow you to control how page is cached • The VaryByCustom attribute allows you to create custom strings to determine if a page should be cached • The VaryByHeader attribute allows you to control the cached settings based on the HTTP header that is sent with the request • You can also use fragment caching to cache one or more user controls on the Web page with the VaryByControl attribute

  31. Overview of ASP.NET Security Methods • Authentication is the process of validating the identity of the request • Authentication mode property can be set to Windows, Passport Forms, or None. If the mode is set to None you can setup your own custom authentication • Define the authentication method used with the Internet Service Manager • Anonymous - default anonymous user IUSR_MachineName • Basic authentication, the username and password are sent as clear text over the Internet, unless you encrypt the login with SSL encryption • WithWindows authentication, the username and password are not sent over the Internet • Passport is a single sign-on passport identity system created by Microsoft • Passport service authenticates the user, sends a cookie back • The benefit to the user is that they only have to login once to access multiple resources and services • Passport at http://www.passport.com/ • The redirectURL property is the URL to redirect the user to when the request is not authenticated such as login page

  32. Forms-based Authentication • Forms Authentication is a cookie-based authentication method • When you log in using an ASP.NET form, the Web Server checks the IP address and domain in the host header of the request • The user may be validated using the credential list within the configuration files, or the request may be validated against an XML file, a database, an in-memory structure, an LDAP directory, or even a Web service • ASP.NET determines if an authentication cookie is present in the TCP/IP header packet • If there is no cookie, the client is redirected to the login page • Once the user has been authenticated, a cookie is added to the header packet to identify future requests • There is no username or password stored in the HTTP cookie. The HTTP cookie merely identifies the client • The first time the user sends a username and password, the cookie has not been created • Therefore, you must use SSL to encrypt the login information until the HTTP cookie is generated

  33. Authorization Node Configuration • Authorization is the process of ensuring that you only have access to resources that are granted by the system administrators • Windows NTFS file system - allows you to set permissions on individual files and folders using an access control list (ACL) • The Identity node is used to identify which resources can be accessed after the user is authenticated • The Impersonate property is used to indicate if impersonation is allowed • identity node - used to impersonate a Windows user account • impersonate property is used to indicate if impersonation is allowed • allow node - is used to configure users that are allowed to access the application • deny node - is used to configure users that are not allowed to access the application • users property - is used to identify the user • roles property - is used to identify a group of users • wildcard * - used to identify all users • wildcard ? - used to identify the anonymous user

  34. Forms Node Configuration • When the authentication mode is set to Forms, the child node forms configure the HTTP cookie • Name property - identify the cookie that contains the ID of the user, default name is .ASPXAUTH. • Path property - is the server path that is valid for the cookie. The default path property is “/” to access the cookie from any directory. • Timeout - is the valid duration of the cookie. The default timeout value is 30 minutes. • loginUrl - is the page to redirect the user if they have not been authenticated. The default is “login.aspx”. • Protection - to protect the data in the HTTP cookie. Possible values are All, None, Encryption, or Validation. MachineKey Node Configuration • The machineKey node is used to identify a value and method to encrypt data on the server • The validationKey is used as part of the hash algorithm, so only ASP.NET applications that have the validationKey can use the data • The decryptionKey is used to guarantee that nontrusted sources can’t read the text

  35. Credentials Node Configuration • The credentials node is an optional child node of the Forms node to provide the credentials for users that may access the application resources • passwordformat property - to specify the encryption method used to encrypt the credentials. The possible values are Clear, SHA1, and MD5. SHA1 and MD5 store the password as a hash value • user node is a child node of the credentials node to identify users • name property identifies the username • password identifies the user’s password • Once the user is validated, you can access that user’s identity information • The following sample code displays the user’s name and the authentication method used in the Web page If User.identity.IsAuthenticated then Message.Text = "Welcome Member: " & _ user.identity.name & _ ". You were authenticated using: " & _ User.identity.AuthenticationType & "." Else Message.Text = "Welcome Stranger!" End if

  36. Validating User Credentials • A Users Credentials File is an XML file to store user information such as e-mail and password • The general process is to retrieve the user login information, retrieve the XML data, and locate the user within the XML file • Then, if the user appears, validate the user • If the user is not validated, they are redirected by the Web configuration file to the login page • In the following exercises, you will import login.aspx, home.aspx and XMLUsers.xml. Then, you will change the configuration files to reflect the new user authentication model • Create a new WebForm named default.aspx • In the Page_Load procedure enter • Import the login.aspx, home.aspx, and XMLUsers.xml • In XMLUsers.xml add your username and password to the list of users

  37. Use XML Based Validation

More Related