Expert VB 2005 Business Objects Second Edition phần 9 pdf

69 234 0
Expert VB 2005 Business Objects Second Edition phần 9 pdf

Đ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

Look back at Figures 10-6 and 10-7 to see the visual appearance of the pages. Both Default. aspx and ProjectEdit.aspx are content pages, adding their content to that already provided by MasterPage.master: <%@ Master Language="VB" CodeFile="MasterPage.master.vb" Inherits="MasterPage" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> < head runat="server"> <title>Untitled Page</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <form id="form1" runat="server"> <div id="mainTable"> <div id="header"> <asp:Label ID="PageTitle" runat="server"> </asp:Label> </div> <div id="navigation"> <div id="navigationContent"> <asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1" ShowExpandCollapse="False" SkipLinkText="" > <NodeStyle CssClass="nav" /> </asp:TreeView> </div> </div> <div id="subnavigation"> <div id="logout"> <asp:LoginStatus ID="LoginStatus1" runat="server"/> </div> </div> <div id="content"> <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </div> <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="False" /> </form></body> </html> MasterPage.master defines the header/title bar at the top of the page. The area immediately beneath the header/title bar contains the Login button, and there is a navigation area down the left. Perhaps most importantly, it also defines a content area containing a ContentPlaceHolder control: <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> This is the area where content pages provide their content, and it is the main body of the page. You’ll see how each content page provides content for this area later in the chapter. CHAPTER 10 ■ WEB FORMS UI 529 6315_c10_final.qxd 4/7/06 1:51 PM Page 529 Theme Support ASP.NET 2.0 supports the concept of themes for a website, where the visual appearance of the site is defined by a theme: a group of files in a theme-specific subdirectory beneath the App_Themes directory in the virtual root. A theme is a group of style sheets, graphics, and control skins that describe the appearance of a site. A given site can have many themes, and you can even allow the user to choose between them if you so desire. Notice how all of the regions in the master page are set up using div tags. No appearance char- a cteristics are specified in the page itself. Instead, the actual appearance is defined by a CSS style sheet contained within the current theme for the site. The PTWeb site includes and uses a Basic theme. The use of the Basic theme is set up in web.config: <pages theme="Basic" styleSheetTheme="Basic"> The theme property sets the default runtime theme, while styleSheetTheme sets the theme for use at design time in Visual S tudio. The styleSheetTheme proper ty should be r emoved when the website is deployed to a production server. The files defining this theme are in the App_Themes/Basic folder beneath the virtual r oot. You should notice that the names of the css and skin files match the name of the theme folder itself. Having the names match allows ASP.NET to automatically realize that it needs to use these files when the theme is selected for the website. The files in this theme are listed in Table 10-4. Table 10-4. Files in the Basic Theme File Description Basic.css The style sheet for the site Basic.skin The skins for GridView, DetailsView, and Login controls Images\background.jpg The background graphic for the header region Images\corner.png The graphic for the rounded corner in the upper-left Combined, these files define the look and feel of the site. This includes defining the appearance of the regions in MasterPage.master. For instance, the header region is defined in the css file like this: #header { background-image: url('images/background.jpg'); background-repeat: no-repeat; height: 64px; line-height: 60px; text-align: left; color: #FFFFFF; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 36px; font-weight: bold; font-style: italic; padding-left: 10px } A control skin defines the appearance of specific controls in the website, such as GridView, TextBox, and so forth. For instance, the appearance of the Login control is defined in the skin file like this: CHAPTER 10 ■ WEB FORMS UI530 6315_c10_final.qxd 4/7/06 1:51 PM Page 530 <asp:Login runat="server" BackColor="#DEDEDE" BorderColor="Black" BorderStyle="Solid" BorderWidth="1px" Font-Names="Verdana" Font-Size="10pt"> <TitleTextStyle BackColor="Black" Font-Bold="True" Font-Names="Verdana" Font-Size="10pt" ForeColor="White" /> </asp:Login> Each type of control in Web Forms has different options you can set in a skin file, allowing y ou to set the appearance of each control in many ways. By making the site theme-enabled, you can easily change the appearance of the site later by creating a new theme directory and similar theme files, and setting the theme property in web.config to use the new theme. Header Region The header region of the page is the title area across the top. It contains a single Label contr ol named PageTitle. This control displays the title of the current content page, based on the Title property set for that page. The following code is included in MasterPage.master to load this value: Protected Sub Page_Load( _ ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load PageTitle.Text = Page.Title End Sub As each content page loads, not only does the Load event for the content page run, but so does the Load event for the master page. This means that code can be placed in the master page to run when any content page is loaded—in this case, to set the title at the top of the page. Navigation Region The navigation region displays the navigation links down the left side of each page. To do this, a web.sitemap file and associated SiteMapDataSource control are used to load the over all structure of the site into memory. This data is then data bound to a TreeView control for display to the user. The web.sitemap file is an XML file that contains a node for each page to be displayed in the navigation region: <?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > <siteMapNode url="" title="" description=""> <siteMapNode url="~/Default.aspx" title="Home" description="Main page" /> <siteMapNode url="~/ProjectList.aspx" title="Project list" description="Project list" /> <siteMapNode url="~/ResourceList.aspx" title="Resource list" description="Resource list" /> <siteMapNode url="~/RolesEdit.aspx" title="Project roles" description="Project roles" /> </siteMapNode> </siteMap> The site map concept can be used to define hierarchical website structures, but in this case, I’m using it to define a flat structure. Notice how each <siteMapNode> element defines a page— except the first one. That root node is required in the file, but since I’m defining a flat structure, CHAPTER 10 ■ WEB FORMS UI 531 6315_c10_final.qxd 4/7/06 1:51 PM Page 531 it really doesn’t represent a page and is just a placeholder. If you were to define a hierarchical page structure, that node would typically point to Default.aspx. Notice that MasterPage.master includes a SiteMapDataSource control: <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="False" /> T his special data control automatically reads the data from the w eb.sitemap f ile and makes it available to controls on the page. The ShowStartingNode property is set to False, indicating that the root node in web.sitemap is to be ignored. That’s perfect, because that node is empty and shouldn’t be displayed. In this case, a TreeView control in the navigation region is bound to the SiteMapDataSource, so it displays the items listed in web.sitemap to the user. LoginStatus Control In the subnavigation region of MasterPage.master, you’ll see a LoginStatus control: <asp:LoginStatus ID="LoginStatus1" runat="server"/> This is one of the login controls provided with ASP.NET 2.0, and its purpose is to allow the user to log into and out of the site. The control automatically displays the word Login if the user is logged out, and Logout if the user is logged in. When clicked, it also automatically redirects the user to a login web page defined in web.config. I’ll cover the web.config options later. Because the control automatically directs the user to the appropriate login page to be logged in, no code is required for that process. However, code is required to handle the case in which the user clicks the control to be logged out. This code goes in the master page: Protected Sub LoginStatus1_LoggingOut( _ ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.LoginCancelEventArgs) _ Handles LoginStatus1.LoggingOut ProjectTracker.Library.Security.PTPrincipal.Logout() Session("CslaPrincipal") = Csla.ApplicationContext.User System.Web.Security.FormsAuthentication.SignOut() End Sub This code covers a lot of ground. First, the Logout() method of PTPrincipal is called, which sets the current principal on the current Thread object to an unauthenticated PTPrincipal object. This was discussed in Chapter 8 and used in PTWin in Chapter 9. However, when the user is logged in, their principal object is stored in a Session field so it can be easily reloaded on every page request. The details on how this works are discussed later in the chapter. When the user logs out, that Session field is updated to reference the new principal object. ■Note If you want to avoid Session, you can choose to reload the user’s identity and roles from the security da tabase on every page request. While that avoids the use of Session, it can put a substantial workload on your security database server. In PTWeb, I have opted to use Session to minimize the load on the database. The final step is to tell ASP.NET itself that the user is no longer authenticated. This is done by calling FormsAuthentication.SignOut(). This method invalidates the security cookie used by ASP.NET to indicate that the user has been authenticated. The result is that ASP.NET sees the user as unauthenticated on all subsequent page r equests . CHAPTER 10 ■ WEB FORMS UI532 6315_c10_final.qxd 4/7/06 1:51 PM Page 532 This covers the logout process, but the login process requires some more work. While the LoginStatus control handles the details of directing the user to a login page, that page must be created. Login Page Like the PTWin smart client, the PTWeb site is designed to use custom authentication, so I can illus- trate the custom authentication support provided by CSLA .NET. I’ll also briefly discuss the use of Windows integrated security and the ASP.NET membership service. In Web Forms, when using custom authentication, you need to configure the site appropriately using web.config, and implement a login web page to collect and validate the user’s credentials. That’s the purpose behind Login.aspx. Forms-Based Authentication When using for ms-based authentication, users ar e often automatically redirected to a login form before being allowed to access any other pages. Alternatively, anonymous users can be allowed to use the site, and they can choose to log into the site to gain access to extra features or functionality. The specific behaviors are defined by web.config. Before moving on, remember that the following implementation only works within IIS. The ASP.NET Development Server provided with Visual Studio has various limitations; among them is the inability to load custom security objects from assemblies in the Bin directory. This means you can’t use the ASP.NET Development Server to test or debug custom principal objects, custom mem- bership providers, or other custom security objects if they’re in an assembly referenced from the project. Though this is an unfortunate limitation, it can be argued that the ASP.NET Development Server is not intended for anything beyond hobbyist or casual usage, and that IIS should be used for any serious business development. ■Note An alternative solution is to install the assembly containing your custom principal and identity classes into the .NET Global Assembly Cache (GAC). For PTWeb, this would mean giving ProjectTracker.Library a strong name and using the gacutil.exe command line utility to install the assembly into the GAC. ProjectTracker. Library would need to be updated in the GAC after each time you build the assembly. I find that using IIS is a far simpler solution than using the GAC. Configuring the Site U sing for ms-based secur ity in ASP .NET means that web.config includes elements like this: <authentication mode="Forms"> <forms loginUrl="Login.aspx" name="ptracker"/> </authentication> <authorization> <allow users="*"/> </authorization> This tells ASP .NET to use for ms-based authentication ( mode="Forms"), y et to allo w unauthenti - cated users ( <allow users="*"/>). CHAPTER 10 ■ WEB FORMS UI 533 6315_c10_final.qxd 4/7/06 1:51 PM Page 533 ■Note To require users to log in before seeing any pages, replace <allow users="*"/> with <deny users="?"/>. It is important that you also ensure that the security on the virtual root itself (within IIS) is con- figured to allow anonymous users. If IIS blocks anonymous users, then it doesn’t really matter what kind of security you use within ASP.NET. ■Note Remember that IIS security runs first, and then any ASP.NET security is applied. With the web.config options shown previously, users can use the site without logging in, but the concept of logging in is supported. The goal is the same as with PTWin in Chapter 9: allow all users to perform certain actions, and allow authenticated users to perform other actions based on their roles. When a user chooses to log in, the <forms> tag specifies that he will be directed to Login.aspx, which will collect and validate their credentials. Figure 10-9 shows the appearance of Login.aspx. CHAPTER 10 ■ WEB FORMS UI534 Figure 10-9. L ayout of the Login page 6315_c10_final.qxd 4/7/06 1:51 PM Page 534 Now this is where things get kind of cool. There is no code behind Login.aspx. This page uses the ASP.NET Login control: <asp:Login ID="Login1" runat="server"> </asp:Login> T his control is designed to automatically use the default ASP.NET membership provider for the site. ■Caution The user’s credentials flow from the browser to the web server in clear text—they are not automati- cally encrypted. Due to this, it is recommended that Login.aspx be accessed over an SSL (Secure Sockets Layer) connection so that data traveling to and from the browser is encrypted during the login process. You can write code to handle the events of the Login control if you desire, but a membership provider offers a cleaner solution overall. Of course, the membership provider that comes with ASP.NET doesn’t understand PTPrincipal and PTIdentity objects, so PTWeb includes its own custom membership provider. Custom Membership Provider A membership provider is an object that inherits from System.Web.Security.MembershipProvider to handle all aspects of membership. These aspects include: • Validating user credentials • Adding a new user • Deleting a user • Changing a user’s password • And more . . . Of course, PTPrincipal doesn’t understand all these things, and ProjectTracker.Library doesn’t implement a full set of membership objects either. If you want to support all these capa- bilities, you should create your own security library with appropriate objects. But PTPrincipal does understand how to validate a user’s credentials. Fortunately, it is pos- sible to implement a subset of the complete membership provider functionality, and that’s what I do in PTWeb. The PTMembershipProvider class is in the App_Code dir ectory, so ASP.NET automatically com- piles it and makes it available to the website. This class inherits from MembershipProvider and overrides the ValidateUser() method: Public Class PTMembershipProvider Inherits MembershipProvider Public Overrides Function ValidateUser( _ ByVal username As String, ByVal password As String) As Boolean If PTPrincipal.Login(username, password) Then System.Web.HttpContext.Current.Session("CslaPrincipal") = _ Csla.ApplicationContext.User Return True CHAPTER 10 ■ WEB FORMS UI 535 6315_c10_final.qxd 4/7/06 1:51 PM Page 535 Else Return False End If End Function ' other methods … End Class All other methods are overridden to throw an exception indicating that they aren’t imple- m ented by this provider. Notice how the ValidateUser() method already accepts username and password parameters. This is convenient because the Login() method of PTPrincipal accepts those parameters as well. The code simply calls the Login() method and records the result; True if the user was logged in, False otherwise. Remember from Chapter 8 that the Login() method sets the User property of Csla. ApplicationContext , thus automatically setting either the Thread object’s CurrentPrincipal property or the HttpContext.Current.User property to an authenticated PTPrincipal if the user’s credentials were valid; otherwise, it is set to an unauthenticated PTPrincipal. Since this code will be running within ASP.NET, it is the HttpContext value that is set to the user’s principal. The code then sets a Session field, CslaPrincipal, to contain this principal value so that it will be available to subsequent pages. Then the result value is returned. The ASP.NET membership infrastructure relies on this return value to know whether the user’s credentials were valid or not. Befor e this custom membership provider can be used, it must be defined in web.config as follows: <membership defaultProvider="PTMembershipProvider"> <providers> <add name="PTMembershipProvider" type="PTMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="false" passwordFormat="Clear" description="Stores and retrieves membership data using CSLA .NET business objects." /> </providers> </membership> B y making PTMembershipProvider the default pr o vider , this definition tells ASP .NET to auto- matically use it for any membership activities, including validating a user’s credentials. R eloading the Principal At this point, you’ve seen how the user can log in or out using the LoginStatus control on the master page . And y ou ’ ve seen how Login.aspx and the custom membership pr o vider ar e used to gather and v alidate the user ’s credentials. But how does the principal object carry forward from page to page? Remember that the web technologies are stateless by default, and it is up to the web developer to manually implement state management as she chooses. Unfortunately, this extends to the user’s identity as well. The for ms-based security infrastructure provided by ASP.NET writes an encrypted cookie to the user’s browser. That cookie contains a security ticket with a unique identifier for the user, the CHAPTER 10 ■ WEB FORMS UI536 6315_c10_final.qxd 4/7/06 1:51 PM Page 536 user’s name, and an expiration time. This cookie flows from the browser to the web server on each page request, so that basic information is available. Notice, however, that the cookie doesn’t include the principal and identity objects. That is because those objects could be quite large, and in some cases, might not even be serializable. Though PTPrincipal and PTIdentity are serializable, they could still be large enough to pose a problem if you tried to write them to the cookie. Cookies have a size limit, and remember that PTIdentity contains an array with all the role names for the user. Given a large number of roles o r lengthy role names, this could easily add up to a lot of bytes of data. ■Note It is possible to serialize the principal and identity objects into the cookie (if the objects are serializable). Doing so isn’t recommended, however, due to the size limitations on cookies. It is quite possible to reload PTPrincipal and PTIdentity from the security database on every page request. Remember that the ASP.NET security cookie contains the username value, and you already know that the user was authenticated. All you would need is another stored procedure in the database that returns the user information based on user name alone; no password would be provided or checked. Similarly, another Shared method like Login() would be implemented in PTPrincipal to load the objects based only on the username value . There are two drawbacks to this. First, reloading this data from the security database on every page request could cause a serious performance issue. The security database could get overloaded with all the requests. Second, there’s an obvious security risk in implementing methods that allow loading user identities without having to supply the password. While that functionality wouldn’t be exposed to the end user, it makes it easier for accidental bugs or malicious back-door code to creep into y our website. This is why I use Session to store the principal object in PTWeb. The user’s credentials are vali- dated, and the resulting principal object is placed in a Session field named CslaPrincipal. On all subsequent page requests, this value is retrieved from Session and is used to set both the current Thread and HttpContext object’s principals. The work occurs in Global.asax, as this file contains the event handlers for all events leading up to a page being processed. In this case, it is the AcquireRequestState event that is used: Protected Sub Application_AcquireRequestState( _ ByVal sender As Object, ByVal e As System.EventArgs) Dim principal As System.Security.Principal.IPrincipal Try principal = _ CType(Session("CslaPrincipal"), System.Security.Principal.IPrincipal) Catch principal = Nothing End Try If principal Is Nothing Then ' didn't get a principal from Session, so ' set it to an unauthenticted PTPrincipal ProjectTracker.Library.Security.PTPrincipal.Logout() Else ' use the principal from Session Csla.ApplicationContext.User = principal End If End Sub CHAPTER 10 ■ WEB FORMS UI 537 6315_c10_final.qxd 4/7/06 1:51 PM Page 537 The reason for using the AcquireRequestState event, rather than the more obvious AuthenticateRequest event, is that Session isn’t initialized when AuthenticateRequest is raised, but it usually is initialized when AcquireRequestState is raised. The code first attempts to retrieve the principal object from Session. This can result in an exception if Session doesn’t exist, and so the value would end up being Nothing. Also, if this is the first page request by the user, the Session field will return Nothing. So the outcome is either a valid P TPrincipal o bject or N othing . If the resulting principal value is Nothing, PTPrincipal.Logout() is called to set the current principal as an unauthenticated PTPrincipal, and the HttpContext is set to use that same principal object. This supports the idea of an unauthenticated anonymous guest user. Both the web and business library code have access to valid, if unauthenticated, principal objects, and can apply authorization code as needed. Additionally, by having the current principal be a valid PTPrincipal object, a remote data portal can be invoked and the application server will impersonate the unau- thenticated user identity so that code can apply authorization rules as well. On the other hand, if a principal object is retrieved from Session, then that value is set as the current principal. Using Windows Integrated Security If you wanted to use Windows integrated security, you wouldn’t need Login.aspx, the custom mem- bership provider, or the code in Global.asax, because the user’s identity is already known. The user provided his Windows credentials to the browser, which in turn provided them to the web server. This means that the virtual r oot in IIS must be configured to disallow anonymous users, thus forcing the user to provide credentials to access the site. It is IIS that authenticates the user and allo ws authenticated users into the site. To have ASP.NET use the Windows identity from IIS, web.config must be configured correctly: <authentication mode="Windows"/> <identity impersonate="true"/> The authentication mode is set to Windows, indicating that ASP.NET should defer all authenti- cation to the IIS host. Setting the impersonate property to true tells ASP.NET to impersonate the user authenticated by IIS. ■Note If you use Windows integrated security, and you are using a remote data portal, you must make sure to change the application server configuration file to also use Windows security. If the data portal is hosted in IIS, the virtual root must be set to disallow anonymous access, thereby forcing the client to provide IIS with the Windows identity from the web server via integrated security. Using the ASP.NET Membership Service ASP.NET 2.0 not only supports the broad concept of membership as used previously, but it provides a complete membership ser vice, including all the code to make it work. The membership service is most often used with the SQL membership provider that comes with ASP.NET. This provider requires that you use a predefined database schema, along with the membership objects provided by Microsoft to manage and interact with the database. By default, ASP .NET will use a M icr osoft SQL Server 2005 Express database in the virtual root’s App_Data dir ec - tory, but you can override that behavior to have it use another Microsoft SQL Server database if needed. The other membership provider shipped with ASP.NET is a connector to Active Directory (AD). It does the same thing, but stores the user information in AD instead of a SQL database. CHAPTER 10 ■ WEB FORMS UI538 6315_c10_final.qxd 4/7/06 1:51 PM Page 538 [...]... optimize the performance of the website, business objects are stored in Session While they could be retrieved directly from the database when needed, storing them in Session reduces the load on the database server To minimize the number of objects maintained in Session, all pages use the same Session field to store their business objects: currentObject This way, only one business object is stored in Session... Function GetRoles() As ProjectTracker.Library.Admin.Roles Dim businessObject As Object = Session("currentObject") If businessObject Is Nothing OrElse _ Not TypeOf businessObject Is ProjectTracker.Library.Admin.Roles Then businessObject = _ ProjectTracker.Library.Admin.Roles.GetRoles Session("currentObject") = businessObject End If Return CType(businessObject, ProjectTracker.Library.Admin.Roles) End Function... taken in PTWeb is better Second, the data portal will only accept principal objects that inherit from Csla.Security.BusinessPrincipalBase, and of course the ASP.NET membership principal types don’t do that The first problem is one of application architecture, and you need to decide if it makes sense for you to have the security mechanism talk directly to a database while your business code uses an application... mix of ASP.NET login controls and the prebuilt ProjectTracker security objects to implement custom authentication Now let’s move on and discuss the pages that provide actual business behaviors Business Functionality With the common functionality in the master page, Login.aspx, and Global.asax covered, it is possible to move on to the business functionality itself As I mentioned earlier, I’ll walk through... ProjectListDataSource.SelectObject e.BusinessObject = GetProjectList() End Sub 6315_c10_final.qxd 4/7/06 1:51 PM Page 553 CHAPTER 10 s WEB FORMS UI As in RolesEdit, this page caches the business object in Session The details of that process are handled by GetProjectList(): Private Function GetProjectList() As ProjectTracker.Library.ProjectList Dim businessObject As Object = Session("currentObject") If businessObject Is... ProjectTracker.Library.ProjectList Dim businessObject As Object = Session("currentObject") If businessObject Is Nothing OrElse _ Not TypeOf businessObject Is ProjectList Then businessObject = ProjectTracker.Library.ProjectList.GetProjectList Session("currentObject") = businessObject End If Return CType(businessObject, ProjectTracker.Library.ProjectList) End Function This method is the same as the GetRoles() method discussed... central business object from Session, or to retrieve it from the database as necessary This not only implements a type of cache to reduce load on the database, but it provides support for the browser’s Back button as well The same thing is done in ProjectEdit: Private Function GetProject() As Project Dim businessObject As Object = Session("currentObject") If businessObject Is Nothing OrElse _ Not TypeOf businessObject... String.IsNullOrEmpty(idString) Then Dim id As New Guid(idString) businessObject = Project.GetProject(id) 557 6315_c10_final.qxd 558 4/7/06 1:51 PM Page 558 CHAPTER 10 s WEB FORMS UI Else businessObject = Project.NewProject End If Session("currentObject") = businessObject Catch ex As System.Security.SecurityException Response.Redirect("ProjectList.aspx") End Try End If Return CType(businessObject, Project) End Function As... This data source control provides access to a RoleList business object, so the DropDownList controls are populated with the list of roles a resource can play on a project This way, ASP.NET does all the hard work of mapping the Key values for each role to the corresponding human-readable text value The numeric Key values are stored in the business objects, while the text values are displayed on the page... directly to a database while your business code uses an application server to talk to the business database The second problem can be overcome with just a bit of code You need to wrap the ASP.NET membership principal in a CSLA NET–style principal There are two parts to this First, you need a custom principal class; second, you need to add some code to Global.asax A custom principal class to wrap the ASP.NET . ser v er . To minimize the number of objects maintained in Session, all pages use the same Session field to store their business objects: currentObject. This way, only one business object is stored in. ProjectTracker.Library.Admin.Roles Dim businessObject As Object = Session("currentObject") If businessObject Is Nothing OrElse _ Not TypeOf businessObject Is ProjectTracker.Library.Admin.Roles Then businessObject. security mechanism talk directly to a database while your business code uses an application server to talk to the business database. The second problem can be overcome with just a bit of code.

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

Từ khóa liên quan

Mục lục

  • Expert VB 2005 Business Objects, Second Edition

    • CHAPTER 11 Web Services Interface.

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

Tài liệu liên quan