Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 45 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
45
Dung lượng
902,9 KB
Nội dung
Finally If Not dr Is Nothing Then dr.Close() End If End Try Instead of writing all of that code, the CBO Hydrator can be used to greatly simplify things. The code snippet in Listing 7-5 does the same thing as the code in Listing 7-4, only it uses the CBO Hydrator. Listing 7-5: Filling an Object Using the CBO Hydrator Return CType(CBO.FillObject(DataProvider.Instance().GetFolder(PortalID, _ FolderPath), GetType(Services.FileSystem.FolderInfo)), FolderInfo) This section covered how Custom Business Objects are used throughout DotNetNuke to create a truly object-oriented design. The objects provide for type safety and enhance performance by allowing code to work with disconnected collections rather than with DataReaders, DataTables, or DataSets. Use the CBO Hydrator whenever possible to reduce the amount of coding and to enhance the maintainability of the application. Architectural Overview The DotNetNuke architecture permits the application tiers to be distributed across two servers: the web server and the database server, as shown in Figure 7-3. The web server contains the presentation, busi- ness logic, and data access layers. The database server contains the data layer. Figure 7-3 Clients Browser Module (User Control) Custom Business Objects (CBO) Exception Management CBO Controllers Business Logic Caching Services Localization Event Logging Personalization Search Common Data Provider Microsoft SQL Data Provider Implementation Other Data Provider Implementation Data Access Data Database Server Skin & Skin Objects Containers Default.aspx Presentation Microsoft SQL Server Other Data Store Web Server 195 DotNetNuke Architecture 11_595636 ch07.qxd 5/10/05 10:03 PM Page 195 Presentation Layer The presentation layer provides an interface for clients to access the portal application. This layer con- sists of the following elements: ❑ Web Forms: The primary web form is the Default.aspx. This page is the entry point to the por- tal. It is responsible for loading the other elements of the presentation layer. You can find Default.aspx in the root installation directory. ❑ Skins: The Default.aspx web form loads the skin for the page based on the settings for each page or portal. You can find the base Skin class in /admin/Skins/Skin.vb. ❑ Containers: The Default.aspx web form also loads the containers for the modules based on the settings for each module, page, and portal. You can find the base Container class in /admin/ Containers/Container.vb. ❑ Module User Controls: Modules will have at least a single user control that is the user interface for the module. These user controls are loaded by Default.aspx and embedded within the con- tainers and skin. You can find the module user controls in .ascx files in /DesktopModules/ [module name]. ❑ Client-Side Scripts: Several client-side JavaScript files are used by the core user-interface frame- work. For instance, the /DotNetNuke/controls/SolpartMenu/spmenu.js script file is used by the SolPartMenu control. Custom modules can include and reference JavaScript files as well. You can find client-side JavaScript files that are used by the core in the /js folder. Some skins may use client-side JavaScript and in this case you would find the scripts in the skin’s installation directory. Any client-side scripts used by modules are located under the module’s installation directory. Rendering the Presentation When visiting a DotNetNuke portal, the web form that loads the portal page is Default.aspx. The code- behind for this page ($AppRoot/Default.aspx.vb) loads the selected skin for the active page. The Skin is a user control that must inherit from the base class DotNetNuke.UI.Skins.Skin. The Skin class is where most of the action happens for the presentation layer. First, the Skin class iterates through all of the modules that are associated with the portal page. Each module has a container assigned to it; the container is a visual boundary that separates one module from another. The container can be assigned to affect all modules within the entire portal, all modules within a specific page, or a single module. The Skin class loads the module’s container and injects the module control into the container. Next, the Skin class determines whether the module implements the DotNetNuke.Entities.Modules .iActionable interface. If it does, the Skin class discovers the actions that the module has defined and adds them to the container accordingly. Next, the Skin class adds references to the module’s style sheets to the rendered page. It looks for a file named module.css in the specific module’s installation directory. If it exists, it adds an HtmlGenericControl to the page to reference the style sheet for the module. All of this happens within the Skin class in the Init event as shown in Figure 7-4. The final rendering of the contents of a module is handled within each module’s event life cycle. 196 Chapter 7 11_595636 ch07.qxd 5/10/05 10:03 PM Page 196 Figure 7-4 Finally, the code-behind ($AppRoot/Default.aspx.vb) renders the appropriate cascading style sheet links based on the configuration of the portal and its skin. See Chapter 13 for more details on style sheets and the order they are loaded in. Business Logic Layer The business logic layer provides the business logic for all core portal activity. This layer exposes many services to core and third-party modules. These services include ❑ Localization ❑ Caching ❑ Exception Management ❑ Event Logging ❑ Personalization Default.aspx Skin Load Modules CSS StyleSheets Module Info Module Actions Skin Pane Container 1. Load Skin 1. Load Skin 2. Load and Render Modules 2. Load and Render Modules 7. Add Module 7. Add Module CSS Stylesheets CSS Stylesheets 3. Get Module 3. Get Module Info Info 5. Inject Module Into 5. Inject Module Into Container and Container and Add to Skin Pane Add to Skin Pane 4. Load 4. Load Container Container 6. Add Module 6. Add Module Actions Actions 1. Load Skin 2. Load and Render Modules 7. Add Module CSS Stylesheets 3. Get Module Info 5. Inject Module Into Container and Add to Skin Pane 4. Load Container 6. Add Module Actions 197 DotNetNuke Architecture 11_595636 ch07.qxd 5/10/05 10:03 PM Page 197 ❑ Search ❑ Installation & Upgrades ❑ Security The business logic layer is also home to custom business objects that represent most entities that collec- tively make up the portal. Custom business objects are discussed in more detail later in this chapter. For now it is important to understand that the fundamental purpose of custom business objects is to store information about an object. Data Access Layer The data access layer provides data services to the business logic layer. This layer allows for data to flow to and from a data store. As described earlier in this chapter, the data access layer uses the Provider Model to allow DotNetNuke to support a wide array of data stores. The data access layer consists of two elements: ❑ Data Provider API: This is an abstract base class that establishes the contract that the implemen- tation of the API must fulfill. ❑ Implementation of Data Provider API: This class inherits from the Data Provider API class and fulfills the contract by overriding the necessary members and methods. The core DotNetNuke release provides a Microsoft SQL Server implementation of the Data Provider API. Beginning with the CBO Controller class, the following code snippets show how the Data Provider API works with the Implementation of the Data Provider API. Listing 7-6 shows how the IDataReader that is sent into CBO.FillObject is a call to DataProvider.Instance().GetFolder(PortalID, FolderPath). Listing 7-6: The FolderController.GetFolder Method Public Function GetFolder(ByVal PortalID As Integer, ByVal FolderPath As String) As FolderInfo Return CType(CBO.FillObject(DataProvider.Instance().GetFolder(PortalID, _ FolderPath), GetType(Services.FileSystem.FolderInfo)), FolderInfo) End Function Figure 7-5 breaks down each of the elements in this method call. Figure 7-5 Data Provider API Returns Instance of the Implementation of the Data Provider API Method that is required by the Data Provider API contract. DataProvider.Instance().GetFolder(PortalID, FolderPath) 198 Chapter 7 11_595636 ch07.qxd 5/10/05 10:03 PM Page 198 The Instance() method is returning an instance of the implementation of the Data Provider API, and is therefore executing the method in the provider itself. The GetFolder method called in Listing 7-6 is an abstract method that is detailed in Listing 7-7. Listing 7-7: The DataProvider.GetFolder Abstract Method Public MustOverride Function GetFolder(ByVal PortalID As Integer, _ ByVal FolderPath As String) As IDataReader This abstract method is part of the contract between the API and the implementation of the API. It is overridden in the implementation of the API as shown in Listing 7-8. Listing 7-8: The SQLDataProvider.GetFolder Method Public Overloads Overrides Function GetFolder(ByVal PortalID As Integer, ByVal _ FolderPath As String) As IDataReader Return CType(SqlHelper.ExecuteReader(ConnectionString, DatabaseOwner & _ ObjectQualifier & “GetFolders”, GetNull(PortalID), -1, FolderPath), _ IDataReader) End Function Microsoft Data Access Application Block Listing 7-8 shows a reference to the SqlHelper class. This class is part of the Microsoft Data Access Application Block. DotNetNuke uses the Data Access Application Block to improve performance and reduce the amount of custom code required for data access. The Data Access Application Block is a .NET component that works with ADO.NET to call stored procedures and execute SQL commands on Microsoft SQL Server. Data Layer The data layer provides data to the data access layer. The data store used in the data layer must be sup- ported by the implementation of the Data Provider API to fulfill the data requests. Because the DotNetNuke Data Provider model is so extensible, several Data Providers are available. These include both core-released Data Providers and providers released by third-party developers including Microsoft SQL Server, Microsoft Access, mySQL, and Oracle providers. The core DotNetNuke release provides a Microsoft SQL Server implementation of the Data Provider API. Installation Scripts Along with the implementation of the API is a collection of scripts that create the database in the data layer during the installation process. These scripts collectively create the database tables, stored procedures, and data necessary to run DotNetNuke. The installation scripts are run only during a new installation and are run from the DotNetNuke.Services.Upgrade.Upgrade.InstallDNN method. Following are the scripts: ❑ DotNetNuke.SetUp.SqlDataProvider: This script prepares the database for the installation by dropping some key tables. ❑ DotNetNuke.Schema.SqlDataProvider: This script installs the tables and stored procedures. ❑ DotNetNuke.Data.SqlDataProvider: This script fills the tables with data. 199 DotNetNuke Architecture 11_595636 ch07.qxd 5/10/05 10:03 PM Page 199 Upgrade Scripts For subsequent upgrades performed after the initial installation, a collection of scripts are run that mod- ify the schema or data during the upgrade process. These scripts are run from the DotNetNuke.Services .Upgrade.Upgrade.UpgradeDNN method. There is one script per baseline version of DotNetNuke. A baseline version is a working version of DotNetNuke that represents some internal milestone. For instance, after the core team integrates a major new feature, such as the Member Role provider, the code is tested, compiled, and zipped up for distribution among the core team. This doesn’t necessarily mean there is one script per released version of DotNetNuke because behind the scenes we may have several baseline versions before a formal public release. The file naming convention includes the version of the script followed by the “SqlDataProvider” extension. The extension must be the same name as found in the DefaultProvider attribute of the Data Provider’s con- figuration settings in the web.config file. For example, the filename for the upgrade script for upgrading from baseline version 3.0.11 to 3.0.12 is 03.00.12.SqlDataProvider. When the DotNetNuke application is upgraded to another version, these scripts will be executed in logi- cal order according to the version number. Only the scripts with a version number that is less than or equal to the value of the constant DotNetNuke.Common.Globals.glbAppVersion will be run. This con- stant is defined in the /components/Shared/Globals.vb file. Script Syntax These scripts are written in SQL; however, two non-SQL tags are used in the scripts that are important to understand. These tags are {databaseOwner} and {objectQualifier}. Both of these tags represent a pro- grammatically replaceable element of the script. Earlier in this chapter, Listing 7-1 showed that the configuration settings for the Microsoft SQL Server Data Provider implementation include two XML attributes named databaseOwner and objectQualifier. The databaseOwner attribute defines the database owner to append to data objects in the scripts. The objectQualifier attribute defines a string to prefix the data objects within the scripts. As an example, take a look at how we create the GetSearchSettings stored procedure in the 03.00.04.SqlDataProvider script (see Listing 7-9). Listing 7-9: A SqlDataProvider Upgrade Script CREATE PROCEDURE {databaseOwner}{objectQualifier}GetSearchSettings @ModuleID int AS SELECT tm.ModuleID, settings.SettingName, settings.SettingValue FROM {objectQualifier}Tabs searchTabs INNER JOIN {objectQualifier}TabModules searchTabModules ON searchTabs.TabID = searchTabModules.TabID INNER JOIN {objectQualifier}Portals p ON searchTabs.PortalID = p.PortalID INNER JOIN {objectQualifier}Tabs t ON p.PortalID = t.PortalID INNER JOIN {objectQualifier}TabModules tm ON t.TabID = tm.TabID INNER JOIN 200 Chapter 7 11_595636 ch07.qxd 5/10/05 10:03 PM Page 200 {objectQualifier}ModuleSettings settings ON searchTabModules.ModuleID = settings.ModuleID WHERE searchTabs.TabName = N’Search Admin’ AND tm.ModuleID = @ModuleID GO In Listing 7-9, the code looks like SQL with the addition of these two non-SQL tags. The first line, shown below, will create a new stored procedure. It will be created in the context of the databaseOwner defined in web.config and the name of the stored procedure will be prefixed with the objectQualifier value from web.config. CREATE PROCEDURE {databaseOwner}{objectQualifier}GetSearchSettings If in the web.config settings the databaseOwner is set to “dbo” and the objectQualifier is set to “DNN,” the preceding line would be programmatically converted to CREATE PROCEDURE dbo.DNN_GetSearchSettings The objectQualifier attribute is useful when you want to maintain multiple instances of DotNetNuke in the same database. For instance, you could have a single web server with 10 DotNetNuke installations on it, each using the same database. But you wouldn’t want these 10 installations using the same data tables. The objectQualifier adds the flexibility for you to store data from multiple DotNetNuke installa- tions in the same database. Security Model Until DotNetNuke 3.0, the portal only offered a single security solution; the forms-based security that was included with the core release. The forms-based security worked well, but it limited the ability to implement DotNetNuke in way that tightly integrates with other security mechanisms. Although Windows authentication was never supported by the core, enhancements by third-party developers are available that allow Windows authentication to be used in versions prior to DotNetNuke 3.0. Before diving into the details of how the Membership/Roles API works in DotNetNuke 3.0, it is impor- tant to understand how security works in ASP.NET 2.0. This will help you understand the challenges we faced in implementing the API, which will help you understand the finer details of how security works in DotNetNuke today. Security in ASP.NET 2.0 In ASP.NET 1.x, the native authentication and authorization services relied on external data stores or configuration in the web.config file. For example, in ASP.NET 1.1 an application can provide forms- based authentication. This requires the developer to create a login form and associated controls to acquire, validate, and manage user credentials. Once authenticated, authorization was provided through XML configurations in the web.config file. In ASP.NET 2.0, the introduction of several new security enhancements expands on these services in three distinct ways: 201 DotNetNuke Architecture 11_595636 ch07.qxd 5/10/05 10:03 PM Page 201 ❑ Login & User Controls: A new suite of login and user controls provide plenty of functionality out of the box, which reduces the need for each application to provide its own login and user controls. For instance, it is easy to generate a set of pages for registering a new user, allowing an existing user to log in, and even handle forgotten passwords by simply placing the appropriate controls on a page and setting a few properties. ❑ User Management: ASP.NET 2.0 provides a new configuration interface for each application that allows for easy management of that application. One feature of the configuration interface is the ability to manage security for the application. For instance, you can easily create a new user and a new role, and then add the user to the role all within the ASP.NET 2.0 native configu- ration interface. As an alternative to the configuration interface, security can be managed by writing a custom management tool to access the same functionality programmatically. ❑ Membership/Roles Provider: This new provider is the conduit between the presentation layer (specifically the login/user controls and the configuration interface) and the persistence mecha- nism. It encapsulates all of the data access code required to manage users and roles. Together these three components reduce the amount of code that is required to provide authentication and authorization services and persist the data to a data store. DotNetNuke and ASP.NET 2.0 To build an application that fully supports authentication and authorization in ASP.NET 2.0, the Membership/Roles provider should be integrated into the application. Several benefits exist to using this provider in an application. First, it can reduce the amount of code that is written to bring these ser- vices to the application. This is true as long as the business requirements fall within the functionality that the default Membership/Roles provider provides. Second, implementing the Membership/Roles provider can allow other applications to share user and role information with the application. With regard to security, this provides seamless integration between diverse applications. Because ASP.NET 2.0 was not released at the time of the DotNetNuke 3.0 development cycle, we lever- aged a backported version of the Membership/Roles provider created by Microsoft. This backported version conforms to the same API as is found in ASP.NET 2.0, except it will run in ASP.NET 1.1. This has been a great addition to DotNetNuke for many reasons, but one key benefit is that it allows DotNetNuke to conform to several ASP.NET 2.0 specifications even before ASP.NET 2.0 is released. Security in DotNetNuke 3.0 Security in DotNetNuke 3.0 has been implemented with quite a bit of forward thinking. We have combined the best features of prior versions of DotNetNuke with the features of the ASP.NET 2.0 Membership/Roles Provider. The result is a very extensible security model that aligns DotNetNuke closely with best practice security models that will be in ASP.NET 2.0. Portals and Applications DotNetNuke supports running many portals from a single DotNetNuke installation. Each portal has its own users and roles that are not shared with any other portals. A portal is identified by a unique key, the PortalID. 202 Chapter 7 11_595636 ch07.qxd 5/10/05 10:03 PM Page 202 Because the default Membership/Role Provider implementation is a generic solution, it does not natively support the concept of having multiple portals, each with their own users and roles. The default Membership/Role Provider implementation was designed in a way that only supports a single portal site in a DotNetNuke installation. The Membership/Role Provider refers to the DotNetNuke installation as an “application,” and without customization that application can only support a single set of users and roles (a single portal instance). To overcome this limitation, a wrapper was needed for the SQL data providers that were provided with the Membership/Role Providers. This customization allows us to support application virtualization. The end result is that the Membership/Role Providers, as implemented in DotNetNuke, can support multi- ple applications (multiple portal instances in a single DotNetNuke installation). We mapped PortalID in DotNetNuke to the ApplicationName in the Membership/Role Provider. When a call is made to the Membership/Role Provider, the ApplicationName is switched on-the-fly to match the PortalID of the portal instance. The custom implementations of the SQL data providers for the Membership/Role Providers can be found in ❑ $AppRoot\Providers\MembershipProviders\CoreProvider\DataProviders\DNNSQL MembershipProvider ❑ $AppRoot\Providers\ProfileProviders\CoreProvider\DataProviders\DNNSQLProfileProvider ❑ $AppRoot\Providers\RoleProviders\CoreProvider\DataProviders\DNNSQLRoleProvider Data Model for Users and Roles In order to achieve the full benefit from the Membership/Roles Provider, it is important to recognize that User and Role information can be externalized from DotNetNuke and stored in a data store that is independent of the main data store. For instance, DotNetNuke may use Microsoft SQL Server as its database to store content and system settings, but the Membership/Roles Provider may use Windows authentication, LDAP, or another mechanism to handle authentication and authorization. Because secu- rity can be externalized using the Provider Model, it was important to ensure that the implementation of the Membership/Roles Provider didn’t customize any code or database tables used by the provider. The data tables used by the provider had to be independent from the other core DotNetNuke tables. We could not enforce referential integrity between DotNetNuke data and the Membership/Roles Provider data, nor could we use cascade deletes or other data-level synchronization methods. In a nutshell, all of the magic had to happen in the business layer. One challenge we faced in implementing the Membership/Roles Provider was dealing with the fields that DotNetNuke currently supports but the Membership/Roles Provider does not support. Ideally, we would have completely replaced the DotNetNuke authentication/authorization-related tables with the tables used by the Membership/Roles Provider. We could not achieve this goal because the authentica- tion/authorization tables in DotNetNuke were already tied to so many existing and necessary features of the application. For instance, the DotNetNuke “Users” table has a column named “UserID,” which is a unique identifier for a user. This UserID is used in nearly all core and third-party modules as well as the core. The most significant problem with UserID was that it doesn’t exist in the Membership/Roles Provider. Instead, the Membership/Roles Provider uses the username as the unique key for a user within an application. The challenge was that we needed a way to maintain the UserID to preserve the DotNetNuke functionality that depended on it. This is just one example of an attribute that cannot be handled by the default Membership/Roles Provider provided by Microsoft. 203 DotNetNuke Architecture 11_595636 ch07.qxd 5/10/05 10:03 PM Page 203 Ultimately, we decided that we would need to maintain satellite tables to support the DotNetNuke attributes that could not be managed by the Membership/Roles Provider. The goal was to maintain enough information in the DotNetNuke tables so that functionality was not lost, and offload whatever data we can to the Membership/Roles Provider tables. The end result is a data model that mirrors the Membership/Roles Provider data tables, as shown in Figure 7-6. Figure 7-6 Note in Figure 7-6 that none of the tables on top have database relationships to the any of the tables on the bottom. The lines connecting them simply show their relationship in theory, not an actual relation- ship in the database. UserId aspnet_Membership Password PasswordFormat PasswordSalt MobilePIN Email LoweredEmail PasswordQuestion PasswordAnswer IsApproved IsLockedOut CreateDate ApplicationName aspnet_Applications LoweredApplicationName ApplicationId Description UserId aspnet_Profile PropertyNames PropertyValuesString PropertyValuesBinary LastUpdatedDate ApplicationId aspnet_Users UserId UserName LoweredUserName MobileAlias IsAnonymous LastActivityDate PortalId Portals PortalName LogoFile FooterText ExpiryDate UserRegistration BannerAdvertising AdministratorId Currency HostFee HostSpace AdministratorRoleId RoleId Roles PortalId RoleName Description ServiceFee BillingFrequency TrialPeriod TrialFrequency BillingPeriod TrialFee IsPublic AutoAssignment UserId Users PortalId UserName FirstName LastName IsSuperUser AffiliateId UserRoleId UserRoles UserId RoleId ExpiryDate IsTrialUsed ProfileId Profile UserId PortalId ProfileData CreatedDate ApplicationId aspnet_Roles RoleId RoleName LoweredRoleName Description UserId aspnet_UsersInRoles RoleId Synchronization and Aggregation 204 Chapter 7 11_595636 ch07.qxd 5/10/05 10:03 PM Page 204 [...]... LogGUID=”39c72059-bcd1-42ca-88 86- 002 363 d1c9dc” LogFileID=”6b780a60cf 46- 4588-8a 76- 75ae9c577277” LogTypeKey=”GENERAL_EXCEPTION” LogUserID=”-1” LogUserName=”” LogPortalID=”-1” LogPortalName=”” LogCreateDate=”2005-02-04T23:25:44 .68 734 56- 05:00” LogCreateDateNum=”2005020423254 468 7” LogServerName=”DNNTEST”> AssemblyVersion 03.00.10 214 Core DotNetNuke APIs ... LogFileID=”b 863 59bbe984-4483-891b-26a2b95bf9bd” LogTypeKey=”USER_CREATED” LogUserID=”-1” LogUserName=”” LogPortalID=”0” LogPortalName= DotNetNuke LogCreateDate=”2005-02-04T14:33: 46. 931 867 2-05:00” LogCreateDateNum=”200502041433 469 31” LogServerName=”DNNTEST”> UserID 6 FirstName John 212 Core DotNetNuke. .. requirement to log any further details about the event Public Overloads Sub AddLog(ByVal _PortalSettings As PortalSettings, ByVal UserID _ As Integer, ByVal objLogType As _ Services.Log.EventLog.EventLogController.EventLogType) 210 Core DotNetNuke APIs Parameter Type Description _PortalSettings PortalSettings This is the current PortalSettings object UserID Integer This is the UserID of the authenticated user... identical to the previous method, except you can send in a PortalSettings object to derive the portal’s default locale Public Shared Function GetString(ByVal name As String, ByVal objPortalSettings _ As PortalSettings) As String Parameter Type Description Name String This is the string to be translated objPortalSettings PortalSettings This is the PortalSettings object for the current context 3 To localize... covers the DotNetNuke API to familiarize you with many of the powerful services the DotNetNuke core application provides developers 2 06 Core DotNetNuke APIs Introduction DotNetNuke provides significant capability straight out of the box Just install and go Sometimes, however, you may need to extend the base framework DotNetNuke provides a variety of integration points: from HTTP Modules to providers... Public Overloads Sub AddLog(ByVal objCBO As Object, ByVal _PortalSettings As _ PortalSettings, ByVal UserID As Integer, ByVal UserName As String, ByVal _ objLogType As Services.Log.EventLog.EventLogController.EventLogType) Parameter Type Description objCBO Object This is a Custom Business Object _PortalSettings PortalSettings This is the current PortalSettings object UserID Integer This is the UserID... would not be added to the native DotNetNuke tables It is for this reason that we need to provide synchronization services between the two data structures In DotNetNuke 3.0, the introduction of the Membership/Roles API has brought extensibility to the security framework We have purposely positioned DotNetNuke 3.0 to implement several ASP.NET 2.0 features so we can convert to ASP.NET 2.0 more quickly and... PropertyValue As _ String, ByVal _PortalSettings As PortalSettings, ByVal UserID As Integer, ByVal _ objLogType As Services.Log.EventLog.EventLogController.EventLogType) Parameter Type Description PropertyName String This is the name of the property to log PropertyValue String This is the value of the property to log _PortalSettings PortalSettings This is the current PortalSettings object UserID Integer... PropertyName As String, ByVal PropertyValue As _ String, ByVal _PortalSettings As PortalSettings, ByVal UserID As Integer, ByVal _ LogType As String) Parameter Type Description PropertyName String This is the name of the property to log PropertyValue String This is the value of the property to log _PortalSettings PortalSettings This is the current PortalSettings object UserID Integer This is the UserID of... Sub AddLog(ByVal objProperties As LogProperties, ByVal _ _PortalSettings As PortalSettings, ByVal UserID As Integer, ByVal LogTypeKey As _ String, ByVal BypassBuffering As Boolean) 211 Chapter 8 Parameter Type Description objProperties LogProperties This is a collection of LogDetailInfo objects _PortalSettings PortalSettings This is the current PortalSettings object UserID Integer This is the UserID . in ASP. NET 2.0, except it will run in ASP. NET 1.1. This has been a great addition to DotNetNuke for many reasons, but one key benefit is that it allows DotNetNuke to conform to several ASP. NET. the powerful services the DotNetNuke core application provides developers. 2 06 Chapter 7 11_59 563 6 ch07.qxd 5/10/05 10:03 PM Page 2 06 Core DotNetNuke APIs Introduction DotNetNuke provides significant. base class for the Data Provider API is in the DotNetNuke. Data namespace. 205 DotNetNuke Architecture 11_59 563 6 ch07.qxd 5/10/05 10:03 PM Page 205 ❑ DotNetNuke. Entities: This namespace is used for