Business Reference Architecture: Enterprises to consumers (B2C E-Commerce Practice) Chapter 7: Consolidatedretail.com's fun

zhaozj2021-02-08  251

Business reference architecture: business to consumers

Chapter 7: Function of ConsolidatedRetail.com

Microsoft Corporation

May 2001

Summary: This chapter introduces the functionality of the consolidatedretail.com application, and provides a pseudo code and actual code example to detail the processing flow.

Introduction

Now, you have an overall understanding of the components of the solution, you can start checking the specific features provided by the site. This chapter discusses the following aspects of the solution and focus on the internal problems faced when writing code for each ribbon:

Represents service user authentication and user profile maintenance product catalog "Shopping Basket" Management Order Processing

When reading each section of this chapter, you will learn about the implementation of specific features, and how to reuse some or all of your company in your own enterprises (B2C) solutions for the consuppidatedretail.com application.

Express service

The representation service in the consolidatedretail.com site is provided by the XSLisapi filter. The main development problem is: How to generate a suitable XML in each PASP script, and how to create the appropriate XSL style sheet to represent the XML as HTML (or other representation format).

XML output from the PASP file in consolidatedretail.com

In the consolidateDretail.com site, each PASP file generates the same XML document. This is to join the include reference to the Common.asp file in each page of the site, and call its Pagestart process.

The PageStart process in the Common.asp file contains the following code:

Sub Pagestart (STRPAGENAMEWITHEXTENSION)

'Remove the PASP file extension

DIM STRPAGENAME

StrPageName = Trim (left (StrPageNamewitHextension, _

INSTRREV (StrPageNameWitHextension, _

".") - 1))

'XML header

Response.write_

"

"Server-config =" "" "" ""

STRPAGENAME & "-config.xml" "href =" "" & _

STRPAGENAME & "-ie5.xsl"?> "

'The root of the page element.

'Generate end tags in the "pagend" subroutine.

Response.write " "& vbcrlf

End Sub

This process creates an XML header for the document to be generated for the PASP file. At the end of each PASP script, the PageEnd process will be called to generate the end tag of and complete the XML document. The following is listed below related code in the Pagend process:

Sub pagend ()

'In order to express it more clear, the code for directory, logout and error message is omitted here.

Call XmlendTag ("Page")

End Sub

The XMlendTAG process is one of the many XML Helper processes in Common.asp. (For more information, please refer to the "XML Helper Process" section in this chapter.) It generates an XML end tag using the following code: SUB XMLENDTAG (STRTAGNAME)

Response.write Mc_STRSTARTTAG & MC_STRFORWARDSLASHTAG & _

Lcase (Replace (Strtagname, MC_STRBLANK, _

MC_STRUNDERSCORE)) & _

MC_STRENDTAG & VBCRLF

End Sub

The XML document generated using the Pagestart and Pagend processes is similar to the following code:

Server-config = "filename-config.xml"

HREF = "filename-ie5.xsl"?>

XML Helper process

In addition to the XMLendTAG mentioned above, Common.asp also contains multiple utility routines related to XML. Use these procedures to generate some tags that will be used in the XML document generated by the PASP page in the ConsolidatedRetail.com site.

Although in many cases, the desired XML characters (such as "<" and ">", please note that the quotation marks are hardened more efficient, however, in various XML generation, a large number of XML characters constants are all Declaration in Common.asp. This increases the readability of the code while helping to debug. These constants are:

Const mc_strstarttag = "<"

Const mc_strendtag = ">"

Const mc_strforwardslashtag = "/"

Const mc_strunderscore = "_"

Const mc_strblank = "" "

These constants are used in the following XML generation process:

XMLbegtag: This utility is written in an XML start tag (for example ) according to the strtagname parameter. XMlendTag: This utility (described above) is written according to the strtagname parameter (for example, ). XMLEMPTYTAG: This utility writes an empty XML tag (for example, ) according to the StrtagName parameter. XMLTAG: This utility writes an XML tag that contains values ​​(for example ) based on the StrtagName and the StrtagValue parameters (eg MyValue ). GetXmlFromrs: This utility creates the XML representation of the record set. GetxmlFromrsrow: This utility creates XML representation of the current line in the recordset.

In addition, many other processes (collectively referred to as xxxwithdsplynm) are used to generate an XML tag containing the displayName property, for example: joe

The marked display name is retrieved from the CatalogDefinitionProperties application-level dictionary variable based on the tagname.

To fully understand the features provided by the XML Helper process, check the source code in Common.asp.

XSL style sheet in consolidatedretail.com site

As mentioned earlier, each page has a associated "file name" -config.xml file, which lists the XSL style sheet to be applied to each client browser or device type. In this implementation, you only support Microsoft® Internet Explorer 5.5, although you can create an alternative style sheet and add to the site to solve this problem.

The XSL file for each PASP page is named "Page Name" -ie5.xsl (where "page name" is a non-version specific name of the PASP page), which contains the page data dedicated XSL code. However, in order to keep the site uniform appearance, you need to define the public user interface (UI) element of all pages in a separate XSL file (named UI_Layout-IE5.xsl). This file is stored in the incrude directory. Each page dedicated XSL file uses the XSL Include instruction to merge the representation logic in ui_layout-ie5.xs to the present page, as shown in the following code segment:

Templates used in Ui_Layout-IE5.xsl

The UI_Layout-IE5.xsl file contains several templates. The Page Template will be applied to the element in the XML document generated by each PASP page. This template references the stylesheet.css cascade style sheet and creates an HTML table containing five lines, and the overall page will be based on the HTML table. The system calls other templates in the UI_Layout-IE5.xsl file to populate these rows.

The first line of the table contains calls to the PageHeader template (defined in the following scripts). This template presents page headline, including images that link to "Shopping Basket", "Profile", and "Home".

The second line is used to create a spacing from the third line, while the third line contains the call to the main template. This template contains the logic required to present the left menu panel (including search form) on the left side of the page. Main template calls the GetCatalogsForuser template, Exceptions template, and Advertising or ProfileMenu template (depending on whether there is an Advertising or ProfileMenu XML element).

The fourth line of the table is similar to the second line, used to create the spacing from the fifth line; the fifth line calls the PageFooter template. This template presents the bottom panel of the page, including a copyright statement.

The PAGE template in Ui_Layout-IE5.xsl is shown in the following code. You can view PageHeader, Main, PageFooter, and other templates for rendering sites in UI_Layout-IE5.xsl.

consolidatedretail.com </ title></p> <p><link rel = "stylesheet" type = "text / css" href = "stylesheet.css" /></p> <p></ hEAD></p> <p><body bgcolor = "# ceb6d5" leftmargin = "0" marginwidth = "0" TopMargin = "0" marginheight = "0" οnlοad = "FOCUS ()"></p> <p><table width = "100%" cellpadding = "0" cellspacing = "0" border = "0"></p> <p><tr></p> <p><TD></p> <p><XSL: Call-Template Name = "PageHeader" /></p> <p></ td></p> <p></ TR></p> <p><tr></p> <p><TD Height = "10" /></p> <p></ TR></p> <p><tr></p> <p><TD></p> <p><XSL: Call-Template Name = "Main" /></p> <p></ td></p> <p></ TR></p> <p><tr></p> <p><TD Height = "10" /></p> <p></ TR></p> <p><tr></p> <p><TD></p> <p><XSL: Call-Template Name = "Pagefooter" /></p> <p></ td></p> <p></ TR></p> <p></ TABLE></p> <p></ body></p> <p></ html></p> <p></ xsl: template></p> <p><! - In order to express more clear, this is omitted with the code of other templates -></p> <p></ xsl: stylesheet></p> <p>Render index.pasp</p> <p>You can check the INDEX.PASP page to see the combination relationship between all pages in the site. The index.pasp page is the default page of the site (ie, home page). INDEX.PASP contains code that performs the following tasks:</p> <p>Use the value index.pasp to define a constant called MC_STRPAGENAME. Call the Pagestart procedure in Common.asp to create the appropriate <page> start tag. Create an empty <Advertising /> tag using the XMLEMPTYTAG process. Call the Pagend process Create </ page> End Tag. The following code performs the above tasks:</p> <p><! - # include file = "incrude / site_const.asp" -></p> <p><! - # include file = "incrude / common.asp" -></p> <p><%</p> <p>Const mc_strpagename = "index.pasp"</p> <p>Sub main ()</p> <p>Call PageStart (MC_STRPAGENAME)</p> <p>XMLEMPTYTAG (MC_STRADVERTISINGMENU)</p> <p>Call Pagend ()</p> <p>End Sub</p> <p>Call main ()</p> <p>%></p> <p>This code generates the following XML documentation:</p> <p><? Xml-stylesheet type = "text / xsl"</p> <p>Server-config = "index-config.xml"</p> <p>HREF = "index-ie5.xsl"?></p> <p><Page PageName = "INDEX.PASP"></p> <p><advutising /></p> <p><getCatalogsforuser></p> <p><SelectionTitle> Browse Directory: </ SelectionTitle></p> <p><catalog></p> <p><catalogname> book </ catalogname></p> <p></ catalog></p> <p><catalog></p> <p><CatalogName> Hardware </ CatalogName></p> <p></ catalog></p> <p></ getcatalogsforuser></p> <p><Profile /></p> <p><Exceptions> </ exceptions></p> <p></ page></p> <p>These XML code will be passed to the XSLISAPI filter that determines the corresponding style sheet in Index-Config.xml. The XSLISAPI filter checks the HTTP request header information to determine the type and version of the browser. Then, the browser information is compared to the corresponding style sheet in INDEX-Config.xml. If a matching entry is not found, apply the default style sheet (INDEX-IE5.xsl).</p> <p>INDEX-Config.xml is similar to the following code:</p> <p><? XML Version = "1.0"?></p> <p><Server-Styles-Config></p> <p><! - For HDML 3.0 Browser -></p> <p><device target-markup = "HDML 3.0"></p> <p><stylesheet href = "index-hdml3.xsl" /></p> <p></ device></p> <p><! - For WML 1.1 Browser -></p> <p><device target-markup = "wml1.1"></p> <p><stylesheet href = "index-wml11.xsl" /></p> <p></ device></p> <p><! - For IE 4.0 Browser -></p> <p><Device Browser = "IE" Version = "4.0"> <stylesheet href = "index-ie5.xsl" /></p> <p></ device></p> <p><! - For IE 5.0 Browser -></p> <p><Device Browser = "IE" Version = "5.0"></p> <p><stylesheet href = "index-ie5.xsl" /></p> <p></ device></p> <p><! - For MME Browser -></p> <p><device Browser = "MME"></p> <p><stylesheet href = "index-wml11.xsl" /></p> <p></ device></p> <p></ Server-Styles-Config></p> <p>When receiving the request from the Internet Explorer 5.0 browser, use the index-ie5.xsl style sheet as an HTML. (Other entries in the index-config.xml file are just as an example; the consolidatedretail.com site does not provide the corresponding style sheet.)</p> <p>INDEX-IE5.xsl is similar to the following code:</p> <p><? XML Version = "1.0"?></p> <p><XSL: Stylesheet XMLns: XSL = "http://www.w3.org/1999/xsl/transform" Version = "2.0"></p> <p><xsl: include href = "incrude / ui_layout-ie5.xsl" /></p> <p><XSL: Template Match = "* | /"> <xsl: Apply-Templates /> </ XSL: Template></p> <p><XSL: Template Match = "Text () | @ *"> <xsl: value-of select = "." /> </ xsl: template></p> <p><XSL: Template Name = "Pageleft" /></p> <p><XSL: Template Name = "PageCenter"></p> <p><script language = "javascript"></p> <p><! [Cdata [</p> <p>Function focus () {</p> <p>Document.formsearch.txtSearchphrase.focus ()</p> <p>}</p> <p>]]]]</p> <p></ script></p> <p><table width = "100%" cellpadding = "0" cellspacing = "0" border = "0" bgcolor = "# fff"></p> <p><tr></p> <p><td width = "11"></p> <p><img src = "/ china / msdn / images / spacer.gif" width = "1" height = "1" border = "0" /></p> <p></ td></p> <p><TD Valign = "TOP" class = "content-text"> <table width = "100%" cellpadding = "0" cellspacing = "0" border = "0"></p> <p><tr></p> <p><TD Valign = "TOP" colspan = "3" class = "content-text"></p> <p><p class = "Headline-text-purple"> Welcome to consolidateDretail.com </ p></p> <p><p> Welcome to this site, you can easily purchase any items you need here. </ p></p> <p><p align = "center"> <a href="registration.Pasp"> <img src = "/ china / msdn / images / home_freeshipping.gif" width = "271" height = "46" vSpace = "5" border = "0" /> </> </ p></p> <p></ td></p> <p></ TR></p> <p><tr></p> <p><TD Valign = "TOP" class = "content-text"></p> <p><p> <b> </ b></p> <p><img src = "/ china / msdn / images / spaceer.gif" width = "200" height = "1" border = "0" /> </ p></p> <p></ td></p> <p><td width = "1" bgcolor = "# CEB6D5"></p> <p><img src = "/ china / msdn / images / spacer.gif" width = "1" height = "1" border = "0" /></p> <p></ td></p> <p><td width = "125" align = "right" Valign = "TOP" class = "content-text"></p> <p><img src = "/ china / msdn / images / giftregistries.gif" Width = "118" height = "30" border = "0" /></p> <p><p> This function can be implemented in the near future. </ p></p> <p></ td></p> <p></ TR></p> <p></ TABLE></p> <p></ td></p> <p><td width = "11"></p> <p><img src = "/ china / msdn / images / spaceer.gif" width = "1" height = "1" border = "0" /> </ td></p> <p></ TR></p> <p></ TABLE></p> <p></ xsl: template></p> <p><XSL: Template Name = "PAgeright" /></p> <p></ xsl: stylesheet></p> <p>This style table contains the UI_Layout-IE5.xsl style sheet described above. Ui_Layout-IE5.xsl style sheet is used to present the public UI element of the page. In this example, the XML document contains the <advertising /> tag. Therefore, UI_Layout-IE5.xsl also uses the Advertising template to render the right panel of the page. The resulting index page is similar to Figure 7-1.</p> <p>Figure 7-1: Code</p> <p>The consolidatedretail.com site is rendered in the PASP page in accordance with the method described above. Use this method (XML content in the PASP file, define a representation in the XSL style sheet), you can easily change the style sheet for displaying the page without affecting the business logic in the PASP file. Therefore, this solution is very flexible and is easy to reuse.</p> <p>User authentication and maintenance of user profiles</p> <p>Microsoft® Commerce Server 2000 supports scalable configuration file systems that store large number of user data. The user data (or user profile) can include the consignee address and contact information. Customers can use these profiles to store personal data, including consignee addresses and contact information so they do not have to re-enter such information every time you have access to the site. Companies can use the profile information for commercial analysis and carry out targeted advertising activities.</p> <p>To create and maintain a configuration file, the user must log in to the site and register on the site. This will create a unique user ID that identifies the user and retrieves the corresponding profile information from the database. The user's ID is stored in the cookie on the client browser. If the user is not logged in, the cookie will contain the user ID associated with an anonymous user, at which point the configuration file information is not available. When the user logs in, the corresponding user ID will be retrieved and the cookie is written, so that the configuration file information can be used during the later session.</p> <p>Note that this site requires the browser to allow cookies. If the user uses the browser configured to allow each session cookie (ie, cookie not stored on the user's hard disk), the user will be able to log in to the site, but also use the site, but cannot use the product Put it in the shopping basket. If you don't allow cookies at all, the user will not access this site.</p> <p>User registration</p> <p>Users can register to this site using the registration.pasp page. This page contains a form that is sent back to itself when using the Registration-IE5.xsl style sheet. The registration.pasp page contains the code that performs the following tasks:</p> <p>Check the data in the form to determine the MODE and Processction parameters. The MODE parameter is used to specify the user to redirect the user after the registration is complete (the default value is acct.pasp). The ProcessAction parameter is used to determine whether the registration form is displayed to allow the user to register, or turn the form back back to proceed. Transfer the registration data to the PutuserObject to create a new configuration file. PutuserObject is defined in the Profile.asp header file. Redirect the user to the acct.pasp page (or other pages specified by the MODE parameter). Registration.PASP Pages Use the MSCSAppframework application-level variable to retrieve the Mode and ProcessAction values ​​from the query string, as shown in the following code segment: strpagemode = _Application ("mscsappframework"). RequestString (_</p> <p>"Mode", Null,, True, True, 0, NULL</p> <p>StrProcessingAction = _</p> <p>Application ("mscsappframework"). RequestString (_</p> <p>"Processction", NULL, TRUE, TRUE, 0, NULL</p> <p>Mode is usually empty, which means that the user has successfully registered and should be redirected to the account management page (Acct.PASP). In some cases, Mode contains the name of other pages, and the user should be redirected to the page. For example, if an anonymous user adds the product to the shopping basket before registration, you may want to redirect the user to the "Checkout" page after the user is registered. The ProcessAction parameter is used to determine that the user is from another page in the site to enter the registration page, or from the registration page itself. If it is the former case, a registration form will be rendered; if it is the latter case, the content of the registration form will be used to register the user. If the ProcessAction parameter is EditUserObject, you can use the data in the form on the form to register the user. The script then retrieves the form data and passes the data to the PUTUSEROBJECT function, which is defined in the profile.asp header file. The header contains various processes for managing user profiles, and each page in the site will use these procedures. The PUTUSEROBJECT function is used to add or update the user profile and return a Boolean value indicating success or failure. If the user is successfully created, the user is allowed to log in and redirect it to another page. If it fails (for example, due to the specified username already exists), the registration.pasp page is res. and the error message indicates that the problem is. The code calls the GetUserID function in Common.asp to retrieve user ID. This function is used to update existing users, which will be discussed in detail later. The next line of the next line for registering new users will check if there is user name with the specified user name: set objmscsprofile = _</p> <p>Application ("MscsprofileService"). Getprofile (strusername, _</p> <p>_ MC_STRUSEROBJECT, BLNRETURNCODE)</p> <p>IF not (objmscsprofile is nothing) THEN</p> <p>Call addexception (m_varrexceptions, 1, _</p> <p>"The user name already exists.", MC_STRPAGENAME)</p> <p>Set objmscsprofile = Nothing</p> <p>If this username has not been used, the code will generate a GUID (unique user ID) and add the user while calling the CreateProfile method of the ProfileService object. The value from the registration form will assign the configuration file: struserid = generateGUID () set objmscsprofile = _</p> <p>Application ("MscsprofileService"). CreateProfile (_</p> <p>StruserName, MC_STRUSEROBJECT)</p> <p>Objmscsprofile.fields (mc_strgeneralinfo) .value _</p> <p>(MC_STRUSER_ID) = CSTR (StrUserID)</p> <p>Objmscsprofile.fields (mc_straccountinfo) .value _</p> <p>(MC_STRACCOUNT_STATUS) = CINT (1)</p> <p>Objmscsprofile.fields (mc_strgeneralinfo) .value _</p> <p>("User_Type") = STRUSERTYPE</p> <p>Objmscsprofile.fields (mc_strgeneralinfo) .value _</p> <p>(MC_STRUSER_SECURITY_PASSWORD) = STRPASSWORD</p> <p>Most of the code in the remainder of this page is used to update existing user objects. Finally, update the configuration file object, the function returns true: objmscsprofile.Update</p> <p>Set objmscsprofile = Nothing</p> <p>PutuserObject = TRUE</p> <p>After the function is running, the new user registers the site database. After the user is registered, registration.pasp redirects the browser to acct.PASP (if the Mode parameter is null) or other pages specified by the MODE parameter: if BlnRegistered Then</p> <p>IF isnull (strpagemode) THEN</p> <p>Response.Redirect "acct.pasp? Mode =" & strpagemode</p> <p>Else</p> <p>Response.Redirect strpagemode & "? Mode =" & strpagemode</p> <p>END IF</p> <p>END IF</p> <p>Authenticate users</p> <p>The registered user must log in and via authentication to access its configuration file information. As mentioned above, the code in the registration.PASP will automatically log in to the newly registered user. However, when the user logs in again, the username and password must be provided to verify.</p> <p>Note: In this application example, login details are passed using the HTTP protocol to pure text format. However, in the actual site, you should use the Secure Hypertext Transfer Protocol (HTTPS) to encrypt security credentials.</p> <p>Users can log in with Login.PASP page. Like Registration.PASP, this page sends data to itself and uses Profile.asp to process data. Login.PASP page contains code that performs the following tasks:</p> <p>Check the data in the form to determine the MODE and Processction parameters. The Mode parameter is used to specify the page to redirect the user after the login is complete (the default value is acct.pasp). The ProcessAction parameter is used to specify whether to display the user credential form to allow the user to log in, or turn the form back to proceed. Retrieve user credentials from the form. Pass the credential to the login function in Profile.asp. Redirect the user to the acct.pasp page (or other pages specified by the MODE parameter). The most important code in login.pasp is a call to the login function in profile.asp: blnloginsuccessful = login (strusername, strpassword) login function is used to verify the user's username and password, and send the authentication order in the form of cookie to Client browser. The first task of this function is to create and initialize the AuthManager object using the following code: set objmscsauthmgr = _</p> <p>Server.createObject (MC_STRAUTHMANAGER)</p> <p>Call Objmscsauthmgr.initialize_</p> <p>(Application ("mscsdictconfig"). S_sitename)</p> <p>The code then removes the user's existing authentication list from the previous login: if objmscsauthmgr.isauthenticated then</p> <p>Call objmscsauthmgr.setauthticket_</p> <p>("", blncookiesupport, _</p> <p>Application ("mscsdictconfig") ._</p> <p>I_Formlogintimeout</p> <p>END IF</p> <p>Check and make sure the username is not empty, the code will use the application-level MSCSProfileService object to load configuration files for users with the specified name: set objmsprofileObject = Application ("msprofileservice"). Getprofile (strusername, mc_struserObject, blnreturncode)</p> <p>If you find a matching profile for the registered user, check your password and user ID and compare the password provided by the user: strprofilepassword = _</p> <p>ObjmscsprofileObject (mc_strgeneralinfo) .value _</p> <p>(MC_STRUSER_SECURITY_PASSWORD)</p> <p>Struserid = objmscsprofileObject (mc_strgeneralinfo). _</p> <p>Value (MC_STRUSER_ID)</p> <p>IF cstr (strprofilepassword) = cstr (strpassword) THEN</p> <p>...</p> <p>You can add the product to the shopping basket while browsing in anonymous manner, which is one of the design features of the consolidatedretail.com site. If the user added the product to the shopping basket before logging in, the user has issued an anonymous configuration file. The AuthManager object now retrieves this document so that you can transfer anonymous users' shopping basket content to a shopping basket for users who have passed authenticated: strprofileuserid = _</p> <p>Objmscsauthmgr.getuserid (MC_BYTPROFILETICKETTYPE)</p> <p>Tag a new document (by authentication user documents), set anonymous cookies to blank values, to delete it: Call Objmscsauthmgr.SetAutAutHticket_ (Struserid, Blncookiesupport, _</p> <p>Application ("mscsdictconfig").</p> <p>I_Formlogintimeout</p> <p>Call objmscsauthmgr.setUserid (mc_bytauthtickettype, _</p> <p>struserid</p> <p>Call objmscsauthmgr.setUserid (mc_bytprofiletickettype, "")</p> <p>Call Objmscsauthmgr.SetProfiletic (", BLNCOOKIESUPPORT)</p> <p>Finally, transmit all products in anonymous shopping basket and state the success: if (len (strprofileuserid> 0) THEN</p> <p>'Get profiles from anonymous sessions</p> <p>'Object</p> <p>Set objmscsunregprofileObject = Application (_</p> <p>"MscsprofileService"). Getprofilebykey (_</p> <p>MC_STRUSER_ID, STRPROFILEUSERID, _</p> <p>Mc_struserObject, blnreturncode)</p> <p>'If you return a matching anonymous configuration file</p> <p>IF not (objmscsunregprofileObject is nothing) THEN</p> <p>'Transfer your shopping basket from anonymous ID to has been registered</p> <p>'Id</p> <p>Call MovebasketItems (StrofileUserid, Struserid)</p> <p>'Remove anonymous profile from the configuration file store</p> <p>Call Application ("MscsprofileService"). _</p> <p>DeleteProfilebyKey (Mc_Struser_ID, _</p> <p>StrofileUserid, MC_STRUSEROBJECT)</p> <p>END IF</p> <p>Set objmscsunregprofileObject = Nothing</p> <p>END IF</p> <p>'Return to indicate the value of successful login</p> <p>Logon = TRUE</p> <p>During the subsequent session, the user provides authentication cookies for each request, so that the code can retrieve the user's configuration file information.</p> <p>Retrieve and update configuration file information</p> <p>This site allows users to view and edit their configuration file information on multiple pages. Since all pages use similar code to update the fields in the user profile, this chapter only discusses the userprofile.pasp page in detail. You can also view code in EditadDressbook.PASP and ChangePasswd.Pasp, which performs similar features.</p> <p>UserProfile.PASP page contains a form that users can view and change the name, last name, email address, and phone number in this form. Its design idea is similar to the Registration.PASP page described above. UserProfile.PASP page contains the code that performs the following tasks:</p> <p>Check the value of the ProcessingAction query string. If the value is EdituserObject, the page has sent the form content to itself, and the configuration file must be updated. Retrieve the form value from the query string. Pass the form value to the PutuserObject function in Profile.asp. Convert the configuration file value to an XML format. As mentioned above, the PUTUSEROBJECT function is used to register new users when receiving the username. If the user name is not received, the function assumes that the user has existed and attempts to update the data in the existing configuration file. To access the configuration file, PutuserObject uses the GetUserID function in Common.asp to retrieve the current user ID from the authentication order, as shown below: Function GetUserid () Dim Objmscsauthmgr 'Authentication Manager</p> <p>DIM STRUSER_ID 'from the Authentication Manager</p> <p>'Retrieved user ID</p> <p>'Institute of Authmanager objects and initialize.</p> <p>Set objmscsauthmgr = _</p> <p>Server.createObject (MC_STRAUTHMANAGER)</p> <p>Call Objmscsauthmgr.initialize_</p> <p>(Application ("mscsdictconfig"). S_sitename)</p> <p>Struser_id = NULL</p> <p>'If the user has verified by authentication and the authentication is not</p> <p>' time out</p> <p>IF objmscsauthmgr.isauthenticated then</p> <p>'Get the unique login ID used in authentication.</p> <p>Struser_id = _</p> <p>Objmscsauthmgr.getuserid (MC_BYTAUTHTICKETTYPE)</p> <p>'Otherwise, if the user browsses anonymously</p> <p>Else</p> <p>'Get the configuration file user ID (ie Guid).</p> <p>'If the getUserid method returns an empty string</p> <p>'Convert this string to NULL</p> <p>Struser_id = _</p> <p>Objmscsauthmgr._</p> <p>GetUserId (MC_BYTPROFILETICKETTYPE)</p> <p>IF not isnull (struser_id) THEN</p> <p>If Len (Trim (Struser_ID)) = 0 THEN</p> <p>Struser_id = NULL</p> <p>END IF</p> <p>END IF</p> <p>END IF</p> <p>'Return to new GUID or currently verified by authentication</p> <p>' username</p> <p>GetUserid = struser_id</p> <p>Set objmscsauthmgr = Nothing</p> <p>END FUNCTION</p> <p>In order to retrieve user profiles, PROFILE.ASP's PUTUSEROBJECT function code uses the PROFILEBYKEY method of the ProfileService object: set objmscsprofile = Application ("mscsprofileservice"). Getprofilebykey (_</p> <p>MC_STRUSER_ID, STRUSERID, MC_STRUSEROBJECT, BLNRETURNCODE) Finally, the code updates the user's configuration file field: objmsprofile.fields (mc_strgeneralinfo) .value (_ _</p> <p>MC_STRFIRST_NAME) = StrfirstName</p> <p>Objmscsprofile.fields (mc_strgeneralinfo) .value (_</p> <p>MC_STRLAST_NAME) = STRLASTNAME</p> <p>Objmscsprofile.fields (Mc_StrGeneralInfo) .value (_MC_STREMAIL_ADDRESS = strearatdress</p> <p>Objmscsprofile.fields (mc_strgeneralinfo) .value (_</p> <p>MC_STRTEL_NUMBER) = STRTELNUMBER</p> <p>Objmscsprofile.fields (mc_strgeneralinfo) .value (_</p> <p>MC_STRWORK_NUMBER) = StrWorkNumber</p> <p>Objmscsprofile.fields (mc_strgeneralinfo) .value (_</p> <p>MC_STRWORK_EXTENSION = StrWorKextension</p> <p>Objmscsprofile.fields (MC_STRPROFILESTEM) .VALUE (_ _</p> <p>MC_STRDATE_LAST_CHANGED) = now</p> <p>Objmscsprofile.update</p> <p>After updating the configuration file, the code in the userprofile.pasp calls the GetUserObjectXML process, which will use the entire user profile as an XML render (actually display the fields referenced in UserProfile-IE5.xsl, but can do not change the code, Style sheets are modified to display other profile information). The GetUserObjectXML process uses the GetProfileByKey method of the ProfileService object to retrieve the user's configuration file. Then, use the XML Helper routine in include / Common.asp to present data. The getUserObjectXML routine is similar to the following code: SUB getUserObjectXML ()</p> <p>DIM Objmscsprofile</p> <p>DIM STRUSERID</p> <p>DIM Field</p> <p>Dim Group</p> <p>DIM BLNRETURNCODE</p> <p>Const c_strofile = "UserObject"</p> <p>struserid = getUserid</p> <p>IF not isnull (struserid) THEN</p> <p>'Use the specified architecture to initialize the configuration file service and connect to the configuration file storage area</p> <p>IF Not Application ("MscsprofileService") is nothing then</p> <p>'Use the configuration file service to retrieve the user's configuration file object and assign the object</p> <p>'Return value for functions</p> <p>Set objmscsprofile = Application ("MscsprofileService")</p> <p>.Getprofilebykey (mc_struser_id, getuserid, _</p> <p>Mc_struserObject, blnreturncode)</p> <p>IF not objmsprofile is nothing then</p> <p>Call Xmlbegtag (c_strprofile)</p> <p>For Each Group in Objmscsprofile.fields</p> <p>Call Xmlbegtag (Group.name)</p> <p>For Each Field in Group.Value</p> <p>Call Xmltag (Field.Name, Field.Value)</p> <p>NEXT</p> <p>Call XmlendTag (Group.name)</p> <p>NEXT</p> <p>Call XmlendTag (c_strprofile)</p> <p>END IF</p> <p>Set objmscsprofile = Nothing</p> <p>END IF</p> <p>END IF</p> <p>End Sub</p> <p>This process will generate the following XML output:</p> <p><? Xml-stylesheet type = "text / xsl"</p> <p>Server-config = "UserProfile-config.xml"</p> <p>HREF = "UserProfile-IE5.xsl"?></p> <p><Page PageName = "UserProfile.Pasp"></p> <p><profilemenu /></p> <p><PageMode /></p> <p><UserObject></p> <p><accountinfo></p> <p><ORG_ID /></p> <p><Account_Status> 1 </ Account_Status></p> <p><user_catalog_set /></p> <p><date_register /></p> <p></ accountinfo></p> <p><Advertising></p> <p><campaign_history />></p> <p></ advertising></p> <p><businessdesk></p> <p><partner_desk_role /></p> <p></ businessdesk></p> <p><generalinfo></p> <p><user_id></p> <p>{8A7D56E9-DABA-499A-96B8-1F8DD93D032B}</p> <p></ user_id></p> <p><logon_name> Kim </ logon_name></p> <p><user_security_password></p> <p>Password</p> <p></ user_security_password></p> <p><email_address> kim@somecompany.com </ email_address></p> <p><User_Type> 1 </ user_type></p> <p><user_title /></p> <p><last_name> </ last_name></p> <p><first_name> </ first_name></p> <p><tel_number> </ tel_number></p> <p><TEL_EXTENSION /></p> <p><fax_number> </ fax_number></p> <p><fax_extension> </ fax_extension></p> <p><user_id_changed_by /></p> <p></ generalinfo></p> <p><ProfileSystem></p> <p><Date_Last_Changed></p> <p>2/8/2001 11:57:13 PM</p> <p></ date_last_changed></p> <p><date_created> 2/8/2001 11:57:13 PM </ date_created></p> <p></ profilesystem></p> <p></ userObject></p> <p><! - The rest of this page is generated by common.asp -></p> <p><getCatalogsforuser></p> <p><SelectionTitle> Browse Directory: </ SelectionTitle></p> <p><catalog></p> <p><catalogname> Book </ CatalogName></p> <p></ catalog></p> <p><catalog></p> <p><CatalogName> Hardware </ CatalogName></p> <p></ catalog></p> <p></ getcatalogsforuser></p> <p><Profile Auth = "Auth" /></p> <p><Exceptions> </ exceptions></p> <p></ page></p> <p>The consolidatedretail.com site provides a valid configuration file feature and demonstrates the basic method of creating, retrieving, and updating user profile information. With Commerce Server Management Desk, you can extend this feature to create custom profile properties, and you can use profile information to provide site personalized services for each user. For more information on using the Commerce Server 2000 configuration file function, please refer to the Commerce Server 2000 documentation. product list</p> <p>A simple way to browse the product catalog for users is one of the most important design goals when designing e-commerce sites. The consolidatedretail.com site implements this goal through the following three ways:</p> <p>The directory is always listed in the user interface. Users can browse through the hierarchical category structure. Users can search for a specific string in the directory.</p> <p>The current user-related directory set is always column in the left pane of the user interface. This is implemented by adding a code that determines and displays the code that can be used and displayed in the Pagend process of Common.asp:</p> <p>This process creates and initializes the CatalogSet object, then calls its GetCatalogSforuser method to pass the ProfileService object referenced by the MSCSProfileService application level variable, the current user (possibly an anonymous user) ID and the default directory collection name to use (if not assigned to the user Directory Set): set objcatalogsets = _</p> <p>Server.createObject (MC_STRCATALOGSETS)</p> <p>Call ObjcatalogSets.initialize_</p> <p>(Application ("mscsdictconfig"). _</p> <p>s_catalogconnectionstring, _</p> <p>Application ("mscsdictconfig") ._</p> <p>S_TransactionsConnectionstring)</p> <p>Set rscatalogs = ObjcatalogSets.getcatalogsforuser (_</p> <p>Application ("MscsprofileService", GetUserid & "", _</p> <p>GetDefaultCatalogSet)</p> <p>This will return an ADO recorder object, you can use standard recordset programming techniques (such as check file end (EOF) tag and use the MoveNext method) to browse this object: Do While Not Rscatalogs.eof</p> <p>Call Xmlbegtag (c_strcatalog)</p> <p>Call getxmlfromrswithdsplynm (RSCatalogs)</p> <p>Call XmlendTag (C_STRCATALOG)</p> <p>Rscatalogs.Movenext</p> <p>Loop</p> <p>When using the UI_Layout-IE5.xsl style sheet to present the XML generated by this code, the resulting web page displays the name of each directory in the directory set as a link to category.PASP. The generated XML segment is similar to the following: <catalog></p> <p><catalogname> Book </ CatalogName></p> <p></ catalog></p> <p><catalog></p> <p><CatalogName> Hardware </ CatalogName></p> <p></ catalog></p> <p>Directory browsing function</p> <p>The directory in the consolidatedretail.com solution is implemented in a hierarchical structure. Both "books" and "hardware" include several categories. The Book of Books also contains a subclass. The product can be stored on any layer of the directory.</p> <p>The page used to browse directory data in the consolidatedretail.com is category.pasp. You can use this page in two modes: root mode or category mode. In the root mode, the page retrieves the product and category from the root specified directory. In the category mode, this page retrieves the product, subcategory, and parent categories from the specified category. This page contains the code that performs the following tasks:</p> <p>Use the MSCSAppFramework object to retrieve the TXTCATALOG and TXTCATEGORY values ​​transmitted in the request string. If the txtcatalog value is not found, then the page redirects the user to Index.PASP. Call the XML header of the pagestart generation page. Retrieve the specified directCatalog object from the MSCSCATALOGMANAGER application variable and write the directory name into the <SearchScope> XML element. Rendering the directory property as an XML. Thus, an attribute such as a directory name can be presented in the user interface. Determine if the catenation name is delivered in the request string. If you do not specify a class name, the page retrieves categories and products from the root of the directory and converts it to an XML format. If a category is provided, the page retrieves the data from the category provided and converts the data to an XML format. Call the Pagend process to close the XML document.</p> <p>This page uses the following code to create <searchscope> element before using the Commerce Server Directory Object to retrieve directory information.</p> <p>Call XMLTAG (c_strsearchscope, strcatalogname)</p> <p>UI_LAYOUT-IE5.xsl Style Table Use this element to pass the current directory name to the search function, then qualify the search. (This chapter will discuss the search function later.)</p> <p>Actual directory data is retrieved using the hierarchical structure of the Commerce Server automation object. The top layer of the hierarchical structure is a CatalogManager object that is used to access all program access to the directory system. The CatalogManager object contains some ProductCatalog objects that represent the directory in the site. In category.pasp, the GetCatalog method for the MSCSCatalogManager application-level variable is used to retrieve the specified directory, as shown in the following code segment:</p> <p>Set objmscsprdcat = application ("mscscatalogmanager"). _</p> <p>GetCatalog (STRCATALOGNAME)</p> <p>With the GetCatalogAttributes method, you can retrieve the properties of the ProductCatalog object as the ADO recordset. Code in category.PASP Use this method to pass each row in the record set to the getXmlFromrswithDSPlyNM routine in Common.asp, which converts the row to XML format:</p> <p>SET RSPROPERTIES = _</p> <p>Objmscsprdcat.getCatalogATTRIBUTES</p> <p>If not (rsproperties.eof and rsproperties.bof) THEN</p> <p>Call Xmlbegtag (c_strgetcatalogattribute)</p> <p>Do While Not Rsproperties.eof</p> <p>'Get the XML version of the record collection</p> <p>Call getxmlfromrswithdsplynm (rsproperties)</p> <p>rsproperties.movenext</p> <p>Loop</p> <p>Call XmlendTag (c_strgetcatalogattributes)</p> <p>END IF</p> <p>This will generate an XML code segment in the following format:</p> <p><getCatalogAttributes></p> <p><CatalogName> Book </ CatalogName> <locale> 8 </ local></p> <p><StartDate> 12/8/1999 </ startdate></p> <p><Enddate> 12/8/2006 </ enddate></p> <p><variantid> ISBN </ variantid></p> <p><ProductID> Title </ ProductID></p> <p><currency> USD </ currency></p> <p><weightmedmeasure> lbs </ weightmeasure></p> <p><catalogid> 1 </ CatalogID></p> <p><CustomCatalog> False </ CustomCatalog></p> <p><freetextindexcreated> 2/8/2001 11:56:22 PM </ freetextindexcreated></p> <p><ProductTableUpdated> 2/8/2001 11:53:37 PM </ productTableUpdated></p> <p></ getcatalogattributes></p> <p>You can also use the recordset object to represent the category in the directory root. The rootcategories method is used to retrieve these categories from category.PASP, as shown in the following code segment (note that the Fields collection property is used to retrieve the specified data field from the record set):</p> <p>Set rscategories = objmscsprdcat.rootcategories</p> <p>'In order to express it, some code is omitted here.</p> <p>Do While Not Rscategories.eof</p> <p>Call Xmlbegtag (c_strrootcategory)</p> <p>Call XmltagwithdsplyNM ("CatalogName", Objmscsprdcat.catalogName)</p> <p>Call XmltagwithdsplyNM ("CategoryName", _</p> <p>Rscategories.fields ("categoryName"). Value</p> <p>Call XmlendTag (c_strrootcategory)</p> <p>Rscategories.Movenext</p> <p>Loop</p> <p>This will generate an XML code segment as follows:</p> <p><rootcategory></p> <p><catalogname> Book </ CatalogName></p> <p><categoryName> Business Software </ CategoryName></p> <p></ rootcategory></p> <p><rootcategory></p> <p><catalogname> Book </ CatalogName></p> <p><categoryName> Development Tool </ categoryName></p> <p></ rootcategory></p> <p><rootcategory></p> <p><catalogname> Book </ CatalogName></p> <p><categoryName> Featured Products </ categoryName></p> <p></ rootcategory></p> <p>...</p> <p>Similar to it, for products in the root, you can use the rootproducts method to retrieve the record sets containing these products:</p> <p>Set rsproducts = objmscsprdcat.rootproducts</p> <p>XML generated for each product in the RSProducts record is similar to the following code: <book></p> <p><OID> 64 </ OID></p> <p><definitionname> SDKBook </ definitionname></p> <p><cy_list_price displayName = "Price"> 19.99 </ cy_list_price></p> <p><OriginalPrice DisplayName = "Buy Price"> 19.99 </ Original PricE></p> <p><i_classtype> 4 </ i_classtype></p> <p><Parentoid> -1 </ Parentoid></p> <p><productID></p> <p>Microsoft Age of Empires II: The Age of Kings: Inside Moves</p> <p></ productID></p> <p><variantid /></p> <p><title displayName = "Title"> Microsoft Age of Empires II: The Age of Kings: Inside Moves </ Title></p> <p><ISBN DisplayName = "ISBN"> 0-7356-0513-0 </ ISBN></p> <p><Description> In an exciting new version of Microsoft Age of Empires, you will master all key strategic strategies, skills, and counseling that can help you capture victories! Microsoft Age of Empires II: Age of Kings: Inside Moves show you how to survive from the Roman Empire to the Middle Ages for thousands of years. </ description></p> <p><image_filename> Boxshots / Press / 2388.gif </ image_filename></p> <p><image_height> 120 </ iMage_height></p> <p><image_width> 120 </ image_width></p> <p><author displayname = "Author"> Microsoft Corporation </ author></p> <p><name displayName = "Name"> Microsoft Age of Empires II: The Age of Kings: Inside Moves </ name></p> <p><PageCount DisplayName = "Page"> 280 </ pagecount></p> <p><ProductURL DisplayName = "Product Information URL"> a href = http://mspress.microsoft.com/produ/books/2388.htm target = _a http://mspress.microsoft.com/produ/2388.htm / a </ produterl></p> <p><publication_year displayname = "Published Year"> 1999 </ publication_year></p> <p><Publisher DisplayName = "Publisher"> Microsoft Press </ PUBLISHER></p> <p><Reading_level DisplayName = "Read Level:"> All Level </ Reading_level> <CatalogName> Book </ CatalogName></p> <p></ book></p> <p>If the code needs to drill to a deeper directory and retrieve some of the contents of the category, you can use the Category object. Category.PASP page Use the Category object to access the contents of the specified category. This object instantiates using the getCategory method of the ProductCatalog object, as shown in the following code segment:</p> <p>Set objmscscategory = _</p> <p>Objmscsprdcat.getcategory (strcategoryName)</p> <p>You can use the Products property to retrieve the products in the category as a recordset:</p> <p>SET RSPRODUCTS = ObjmscScategory.Products</p> <p>The Category object also provides the ChildCategories property to retrieve the subclass of records, providing the ParentCategories property to return the parent category recordset.</p> <p>Whether they are in a hierarchical structure, you can use Commerce Server Business Desk to create the relationship between categories and products in your catalog. The Category object provides the RelatedCategories and the RelatedProducts property to retrieve the record set containing the corresponding content. You can see examples of how to use these objects in Category.Pasp.</p> <p>View Product</p> <p>Category-IE5.xsl style sheet for rendering directory data generates HTML, which is requested by the user when the user clicks the "Get Detail" link of a particular product. This page will display specific data for the selected product.</p> <p>The beginning of the code in Product.Pasp is similar to category.pasp. This code retrieves the directory, product ID, and optional product variables in the request string. If there is no directory or product ID parameter, redirect the user to INDEX.PASP. Then, the code calls PageStart starts to generate XML for this page.</p> <p>The code becomes interesting when retrieving the Commerce Server product object from the directory object using the getProduct method:</p> <p>Set objmscsprd = objmscsprdcat.getProduct (STRPRoductID)</p> <p>You can use the getProductProperties method to retrieve some properties of the product in the record set object, such as product name and price:</p> <p>Set rsproduct = objmscsprd.getProductProperties</p> <p>Products in the Commerce Server directory support variants (such as different colors or different products). You can use the Variants attribute to retrieve a variable list of a particular product as a recordset. In addition, you can also use the RelatedProducts and the RelatedCategories property to retrieve any related products or categories. Use these properties to create a link to get a cross-selling opportunity. All of these properties are used to generate XML data for the product in Product.PASP page, which lists a XML code. Then use the Product-IE5.xsl style sheet to present these data.</p> <p><getProduct></p> <p><book></p> <p><catalogname> Book </ CatalogName></p> <p><definitionname> SDKBook </ definitionname></p> <p><cy_list_price displayName = "Price"> 19.99 </ cy_list_price> <originalprice displayName = "Buy Price"> 19.99 </ Original Price></p> <p><i_classtype> 4 </ i_classtype></p> <p><ProductID> Microsoft Age of Empires II: The Age of Kings: Inside Moves </ ProductID></p> <p><variantid /></p> <p><author displayname = "Author"> Microsoft Corporation </ author></p> <p><Description> In an exciting new version of Microsoft Age of Empires, you will master all key strategic strategies, skills, and counseling that can help you capture victories! Microsoft Age of Empires II: Age of Kings: Inside Moves show you how to survive from the Roman Empire to the Middle Ages for thousands of years. </ description></p> <p><image_filename> Boxshots / Press / 2388.gif </ image_filename></p> <p><image_height> 120 </ iMage_height></p> <p><image_width> 120 </ image_width></p> <p><ISBN DisplayName = "ISBN"> 0-7356-0513-0 </ ISBN></p> <p><name displayName = "Name"> Microsoft Age of Empires II: The Age of Kings: Inside Moves </ name></p> <p><PageCount DisplayName = "Page"> 280 </ pagecount></p> <p><ProductURL DisplayName = "Product Info. URL"> a href = http: //mspress.microsoft.com/produ/books/2388.htm target = _a http://mspress.microsoft.com/Prod/Books/2388. HTM / A </ productURL></p> <p><publication_year displayname = "Published Year"> 1999 </ publication_year></p> <p><Publisher DisplayName = "Publisher"> Microsoft Press </ PUBLISHER></p> <p><Reading_level DisplayName = "Read Level:"> All levels </ reading_level></p> <p><title displayName = "Title"> Microsoft Age of Empires II: The Age of Kings: Inside Moves </ Title></p> <p></ book></p> <p></ getProduct></p> <p>Search directory</p> <p>In addition to providing users who are used to browse directory, a high-efficiency site should also provide search. In the consolidateDretail.com site, users can enter search criteria, search for specific products in the directory. Search features in Commerce Server 2000 can be searched in the current directory, or search in a directory based on the current user. Search feature is implemented in SearchResults.Pasp, searchResults.PASP contains code that performs the following tasks:</p> <p>Retrieve the search phrase, directory, the number of rows, directories to return from the query string, and give the default value as needed and the number of start position parameters to be given, and generate an exception in the case where the search phrase is not provided. If the directory is not specified, retrieve the directory set based on the current user profile. Search for specified search phrases in the specified directory or user directory set. Rendering the search results as XML.</p> <p>The actual code of the search directory uses the FretextSearch method for the application-level MSCSCatalogManager object to retrieve the search results in the record set. This method accepts the following parameters:</p> <p>Search for a list of directory lists to search (separated by comma) The attribute list (comma-separated) should be selected as a result of the result list indicates the number of record numbers to be returned by the Boolean value in ascending order. Output parameters, indicate the number of total rows that are actually returned</p> <p>If the user does not specify a directory, the current user's default directory set will be retrieved as the recordset, and each directory name is connected to a comma-separated string:</p> <p>Set objcatalogsets = server.createObject (MC_STRCATALOGSETS)</p> <p>Call ObjcatalogSets.initialize_</p> <p>(Application ("mscsdictconfig"). S_catalogconnectionstring, _</p> <p>Application ("mscsdictconfig"). S_transactionsconnectionstring)</p> <p>Set rscatalogs = ObjcatalogSets.getcatalogsforuser_</p> <p>(Application ("MscsprofileService", GetUserid & "", _</p> <p>GetDefaultCatalogSet)</p> <p>STRCATALOGSTOSEARCH = "" "</p> <p>IF not (RSCatalogs.eof and rscatalogs.bof) THEN</p> <p>Do While Not Rscatalogs.eof</p> <p>STRCATALOGSTOSEARCH = STRCATALOGSTOARCH & "," & _</p> <p>Rscatalogs.fields ("CatalogName"). Value & ""</p> <p>Rscatalogs.Movenext</p> <p>Loop</p> <p>STRCATALOGSEARCH = TRIM (MID (Strcatalogstosearch, 2))</p> <p>END IF</p> <p>Or, if you specify a directory, simply assign the directory name to the STRCATALOGSTOSEARCH variable:</p> <p>STRCATALOGSEARCH = STRCATALOGNAME</p> <p>Finally, call the freeEtextSearch method:</p> <p>SET RSPRODUCTS = _</p> <p>Application ("MSCSCATALOGMANAGER"). FreetextSearch_</p> <p>(strsearchphase, strcatalogstosearch,, _</p> <p>"CatalogName, CategoryName, Definitionname, _</p> <p>OriginalPrice, CY_LIST_PRICE, I_CLASSTYPE,</p> <p>ProductID, Description, Image_FileName, _</p> <p>Image_width, image_height, name, _</p> <p>"i_classtype, catalogname", _</p> <p>True, _</p> <p>LNGSEARCHSTARTPOS, _</p> <p>LNGSEARCHROWTORTURN, _</p> <p>LNGTOTALRECORDSINQUERY)</p> <p>The remaining code on this page is just converting the rows in the records returned by FreeEtextSearch to an XML format, so that the XSLisapi application can present search results for display. The XML generated for the search results has the following format:</p> <p><SearchScope> Book </ SearchScope></p> <p><searchString> Age of Empires </ searchString></p> <p><Searchcount> 4 </ searchcount></p> <p><SearchrowStoreTurn> 15 </ searchrowstoreTurn></p> <p><searchstartpos> 1 </ searchstartpos></p> <p><searchResults></p> <p><book></p> <p><catalogname> Book </ CatalogName></p> <p><definitionname> SDKBook </ definitionname></p> <p><OriginalPrice DisplayName = "Buy Price"> 19.99 </ Original PricE></p> <p><cy_list_price displayName = "Price"> 19.99 </ cy_list_price></p> <p><i_classtype> 4 </ i_classtype></p> <p><ProductID> Microsoft Age of Empires II: The Age of Kings: Inside Moves </ ProductID></p> <p><Description> In an exciting new version of Microsoft Age of Empires, you will master all key strategic strategies, skills, and counseling that can help you capture victories! Microsoft Age of Empires II: Age of Kings: Inside Moves show you how to survive from the Roman Empire to the Middle Ages for thousands of years. </ description></p> <p><image_filename> Boxshots / Press / 2388.gif </ image_filename></p> <p><image_width> 120 </ image_width></p> <p><image_height> 120 </ iMage_height></p> <p><name displayName = "Name"> Microsoft Age of Empires II: The Age of Kings: Inside Moves </ name></p> <p></ book></p> <p><! - In order to express more clear, other results are omitted here -></p> <p><SelectionTitle> The product found in the search criteria 'Age of Empires'. </ selectionTitle></p> <p></ searchResults> "Shopping Basket"</p> <p>Like most B2C sites, consolidateDretail.com solution uses a shopping cart or a shopping basket concept to select the product to be purchased together. Whether it is logged in or anonymous user, consolidatedretail.com allows them to add products to the shopping basket; but anonymous users must log in before checkout.</p> <p>Add products to your shopping basket</p> <p>When the user clicks on the Product.PASP page, the product and quantity information will be sent to the _addItem.asp page. This page contains the code that performs the following tasks before the user is redirected to the Basket.PASP page that is displayed in the shopping basket:</p> <p>Retrieve the categories, products, variables, and directory values ​​recorded in the query string. Check the number value passed in the query string (if the number is not passed, add 1 instance of the item). Carry the user's shopping basket into an OrderGroup object. If the product has been listed in the shopping basket, add the specified number to an existing entry; otherwise create a new entry for this product. Redirect the user to BASKET.PASP.</p> <p>_ADDITEM.ASP Page Use the loadbasket function in the Basket.asp header file to retrieve the OrderGroup object containing the current user shopping basket. The LoadBasket function is similar to the following code:</p> <p>Function Loadbasket (Struserid)</p> <p>DIM Objmscsordergroup</p> <p>Set objmscsordergroup = Server.createObject (_</p> <p>MC_STRORDERGROUP)</p> <p>Call Objmscsordergroup.initialize (Application)</p> <p>"Mscsdictconfig"). S_TransactionsConnectionstring, _</p> <p>struserid</p> <p>Call objmscsordergroup.loadbasket ()</p> <p>Set loadingbasket = objmscsordergroup</p> <p>Set objmscsordergroup = Nothing</p> <p>END FUNCTION</p> <p>Note: The ORDERGROUP object is created and initialized by transmitting a transaction connection string defined in the MSCSDictConfig application variable and the user ID of the current user. (User ID is taken from the getGuaranteedUserid function in the profile.asp header. For the logged in user, the user ID will be returned to the authentication, and the configuration file user ID is returned for anonymous users.)</p> <p>Then, the LoadBasket method of the ORDERGROUP object is called to retrieve the shopping basket content associated with the current user.</p> <p>After loading the shopping basket, the code in _additem.asp searchs in the basket in the shopping basket, check whether the requested product is listed. If the product has been in the shopping basket, add the specified quantity on the order, as shown below:</p> <p>Blnskumatch = false</p> <p>'If the detail project exists</p> <p>IF Objmscsordergroup.value ("Total_LineItems"> 0 THEN</p> <p>'Cycle search for each detailed item, look up match</p> <p>For Each Colitem in ObjmscsOrdergroup.Value_</p> <p>("ORDERFORMS"). Value ("default"). Items</p> <p>If isnull (strvariantid) THEN</p> <p>IF (Trim (CSTR (Colitem.Product_ID) = _</p> <p>Trim (CSTR (STRPRoductID)))))</p> <p>Isnull (Colitem.Product_variant_id) Thenblnskumatch = TRUE</p> <p>EXIT for</p> <p>END IF</p> <p>Else</p> <p>IF (Trim (CSTR (Colitem.Product_ID) = _</p> <p>Trim (CSTR (STRPRoductID)))))</p> <p>TRIM (CSTR (Colitem. _</p> <p>Product_variant_id)) = _</p> <p>TRIM (CSTR (Strvariantid)))</p> <p>BLnskumatch = TRUE</p> <p>EXIT for</p> <p>END IF</p> <p>END IF</p> <p>NEXT</p> <p>IF blnskumatch</p> <p>'If the project has been in the basket, add the number of new items to</p> <p>'The number of existing projects</p> <p>Colitem.quantity = colitem.quantity intProductQty</p> <p>'Save new shopping basket</p> <p>Call objmscsordergroup.saveasbasket ()</p> <p>...</p> <p>If the product is not listed in the shopping basket, the code calls the AddITEMTOBASKET partial function to add it to the shopping basket. The AddITEMTOBASKET function creates a dictionary object to represent the project and add the item to the shopping basket using the AddItem method of the ORDERGROUP object. Then, use the SaveAsBasket method to save the shopping basket. The code of the AddItemTobasket function is similar to the following code:</p> <p>Function additemtobasket (ObjmscsorderGroup, _</p> <p>STRPRODUCTID, _</p> <p>STRCATALOGNAME, INTPRODUCTQTY, _</p> <p>Strvariantid, strcategoryName)</p> <p>DIM ObjmscsProductDictionary</p> <p>'Creating a product dictionary</p> <p>Set objmscsproductDictionary = _</p> <p>Server.createObject (MC_STRDictionary)</p> <p>ObjmscsproductDictionary.LineItem_UID = generateGUID ()</p> <p>ObjmscsproductDictionary.product_id = strproductID</p> <p>ObjmscsproductDiction.Product_catalog = strcatalogname</p> <p>ObjmscsproductDiction.quantity = intProductQty</p> <p>IF not isnull (strvariantid) THEN</p> <p>ObjmscsproductDictionary.product_variant_id = _</p> <p>StrvariantID</p> <p>END IF</p> <p>IF not isnull (strcategoryName) THEN</p> <p>ObjmscsproductDictionary.Product_category = _</p> <p>StrcategoryName</p> <p>END IF</p> <p>Call objmscsordergroup.additem (objmscsproductDictionary)</p> <p>Call objmscsordergroup.saveasbasket ()</p> <p>Set objmscsproductDictionary = Nothing</p> <p>END FUNCTION</p> <p>Note: Adding a project is achieved by creating a Dictionary object representing the item and then passes the item to the AddIst method method of OrderGroup (indicating the shopping basket).</p> <p>After updating the shopping basket, the code in _addItem.asp redirects the user to Basket.PASP.</p> <p>View shopping basket</p> <p>Users can use the Basket.PASP page to view and edit the content of the shopping basket. Basket.PASP contains code that performs the following tasks: Check the integrity of the shopping basket. Retrieve user ID (retrieved from the authentication order or anonymous configuration file). If the user's shopping basket is non-empty, use the Pagbasket pipe to retrieve the shopping basket information to display. Write the total count of detailed items into the <TotallineItems> XML tag. Use the Commerce Server DictionaryXmlTransForms object to convert the shopping basket content to XML and write its response.</p> <p>This page uses the following code to load the user's shopping basket and check if the shopping basket contains products:</p> <p>Set objmscsordergroup = loadingbasket (struserid)</p> <p>'Check if the shopping basket contains projects</p> <p>IF not isbasketeempty (objmscsordergroup) THEN</p> <p>blnbasketisempty = false</p> <p>END IF</p> <p>ISBASKETEMPTY function in include / Basket.asp checks if the project is included in ORDERGROUP. If the shopping basket contains the product, transfer the shopping basket to the Pagbasket pipe to prepare for display:</p> <p>Set objmscspipelines = Application ("mscspipes")</p> <p>Interrorlevel = _</p> <p>Runmtspipeline (Objmscspipelines.pagbasket, _</p> <p>Objmscspipelines.logfolder & struserid & _</p> <p>".log", _</p> <p>Objmscsordergroup)</p> <p>Pagbasket pipeline</p> <p>The pipe is used to configure a series of components that will operate a business object in a fixed order. The operation of the pipeline is divided into several "phases". In this example, the components contained in the Pagbasket pipe operate on the ORDERGROUP object, which represents the user's shopping basket. You can use the Commerce Server pipeline editor to view the configuration of the Pagbasket pipeline, just open the Pagbasket.pcf file in the "Pipe" folder on the site. Pagbasket pipes are shown in Figure 7-2.</p> <p>Figure 7-2: Pagbasket pipeline</p> <p>When a shopping basket is displayed each time, the Pagbasket pipe collects all the data required to display the shopping basket and makes the necessary calculations. In addition to running the pipe before displaying the shopping basket, it is also necessary to run it in the final stage of the checkout process to make the necessary calculations to create the final order totaled.</p> <p>Product information</p> <p>The pipe starts from the "product information" phase. This stage is used to manage product information, involving two components:</p> <p>QueryCatalogInfo: QueryCatalogInfo component retrieves product information from each item in the order. It will retrieve information to each project dictionary in the order form. RequiredProdInfo: RequiredProdInfo Components Check all items of the items collection in ORDERFORM, and delete all items set to 1.</p> <p>Order initialization stage</p> <p>Then enter the Order Initialization phase, initialize the corresponding value in the ORDERGROUP. This phase only involves a component: RequiredOrderinitcy. First, Requiredorderinitcy ensures that the ORDER_ID button is worthless. If there is no value, RequiredOrderinitCy will generate a unique order ID and assign it to this button. Then, in order to ensure the order integrity, the component will assign the null value to each Total key to initialize it. Finally, for each item in the items collection, RequiredOrderinitcy is copied to the value in the Quantity to the _n_unadjusted key, initialize the number of un discounted items, and initialize the _oadjust_adjustedprice (the total cost of the project) into zero. Order check phase</p> <p>The order checks for the "Order Check" phase check is valid and all entries needed for subsequent processing. This phase only involves a component: RequiredOrderCheck. The RequiredOrderCheck component ensures that the ORDERFORM project list is not empty.</p> <p>Project pricing phase</p> <p>The Project Pricing phase is set to each item in the order form _iadjust_regularprice. This phase involves the following two components:</p> <p>DefaultItempricecy: For each item in the order form (that is, each item in the items collection), DefaultItempricecy will assign the _iadjust_regularprice key to the value stored in the _cy_product_list_price. Some components included in each phase of the "Project Pricing" phase in the pipeline depend on the set _iadjust_regularprice key. If this button is not assigned, the components will fail. The RequiredItempricecy: RequiredItemPricecy component checks for each item in the project list_Cy_iadjust_regularprice. Before running the RequiredItemprice component, you should use the DEFAULTITEMPRICECY component to initialize the project list to include the latest pricing information for the project. If _cy_iadjust_regularprice does not contain a value, an error will occur.</p> <p>Project price adjustment stage</p> <p>The "Project Paraage" phase is set to each item in the order form _iadjust_currentprice. This phase only involves a component: RequiredItemadjustPricecy. The RequiredItemAdjustPriceCY Current price of each item (_CY_IADJUST_CURRENTPRICE) in the list of verified items exists. If this value does not exist, the component creates it and initializes it to a regular price (_CY_IADJUST_REGULARPRICE). In addition, the component checks the current price (cy_iadjust_currentprice) to check the price (cy_placed_price) to see if the current price has changed after the product is placed in the shopping basket. If the place is placed, the component creates it and set it to the current price (CY_IADJUST_CURRENTPRICE). If the price exists but does not mean the current price, RequiredItemAdjustPricecy retrieves the warning message text that invalid place the price from the MessageManager and writes the message to the _basket_errors collection in the order form.</p> <p>Order price adjustment phase</p> <p>The "Order Panel" phase is set to each item in the order form _oadjust_adjustedprice to take into account the factors of the price discount. This phase only involves the following components: RequiredRadjustPRicecy: For each project, RequiredRadjustPricecy first calculates the amount of discounts that do not discounted. The method is to multiply the current price of the project (_CY_IADJUST_CURRENTPRICE) with the number of items (N_UNADJUSTED), and then add the product to the total cost of the project (_Cy_oadjust_adjustedPrice). Then, calculate the item discount (cy_oadjust_discount). The method is to use the current price of the project (_CY_IADJUST_CURRENTPRICE) to multiply the total cost of the project with a total quantity, then subtract the previously calculated non-discount project fees, which calculates the item discount. Order small schedule</p> <p>The "Order Try" phase is set on the order form _oadjust_subtotal. This phase involves the following three components:</p> <p>DEFAULTORDERSUBTOURCY: Adds the total cost of each item in the SIMPLIST project in ORDERFORM, calculates the small count (_Cy_oadjust_subtotal). Persistility: Persistility is a custom component for copying the values ​​in ORDERFORM. It is mainly used to persist value. Otherwise, the name of the name will not be held lastu. The source code of the PersistUtility component is provided with Visual C to provide with the business reference architecture. Requiredordersubtotalcy: Requiredordersubtotalcy Check the _oadjust_subtotal key in the order of ORDERFORM, make sure the value assigned to the key is not NULL.</p> <p>Convert shopping basket content to XML</p> <p>After running the pipeline, the code in Basket.Pasp checks the ORDERGROUP object again to ensure that the object is still included (because some items may have been removed in the pipe). If the shopping basket contains items, use the Commerce Server DictionaryXmlTransForms object to convert content to XML and write it to the response object. The XML generated by the DictionaryXmlTransForms object is similar to the following code:</p> <p>ORDERFORM_ID = "{0F111D4C-E79F-4615-B1AD-9193C811DE86}"</p> <p>Saved_cy_oadjust_subtotal = "24.99"></p> <p><Items quantity = "1"</p> <p>Product_ID = "Quick Course In Microsoft Office 2000"</p> <p>Product_catalog = "Book" Product_category = ""</p> <p>description = "QUICK COURSE IN MICROSOFT OFFICE 2000 provide some crash course to help you learn the basics quickly this office suite, familiar with Microsoft Excel, Microsoft Word, Microsoft PowerPoint, Microsoft Outlook, Microsoft Access, Microsoft Internet Explorer 5, Microsoft FrontPage and Microsoft Publisher. "D_Datecreated =" 16/02/2001 18:36:06 "</p> <p>CY_LINEITEM_TOTAL = "24.99" CY_Unit_price = "24.99"</p> <p>LineItem_UID = "{FC57A7EA-1420-40A8-8F55-569FE9B2BEDE}"</p> <p>_Product_name = "Quick Course In Microsoft Office 2000"</p> <p>_CY_OADJUST_ADJUSTEDPRICE = "24.99" /></p> <p></ orderform></p> <p>Then, use the Basket-IE5.xsl style sheet to present the shopping basket as an HTML.</p> <p>Order processing</p> <p>When the user decides to check out, the following steps must be performed:</p> <p>Specify the consignee address for the order (or choose to send different items to different addresses). Select the delivery method. Provide payment information for orders. Confirm order details. Complete the ordering process.</p> <p>The consolidateDretail.com site uses the Commerce Server object and the pipeline component to process these processes.</p> <p>Specify the consignee address</p> <p>Users typically use shipping.pasp to specify the consignee address. This page contains a form that lists all consignee addresses in the user profile, along with options for creating new addresses or editing existing addresses. Users only need to specify the address to be sent to the project. Then, the page returns the table to itself, updates the OrderGroup object indicating the content of the shopping basket with the specified address.</p> <p>When the user specifies the consignee address, the code in Shipping.PASP uses the GetUserID function in the Common.asp header file to retrieve the ID of the current user. Then, Shipping.PASP calls the loadbasket routine in the Basket.asp header file to populate the ORDERGROUP object, as shown below:</p> <p>struserid = getUserid</p> <p>Set objmscsordergrp = loadingbasket (struserid)</p> <p>Next, the code is retrieved from the query string to update each item in the shopping basket with the specified address ID:</p> <p><OrderForm</p> <p>For Each StrorderFormName In objmscsordergrp.value.orderForms</p> <p>Set objmscsorderform = objmscsordergrp.value.orderForms_</p> <p>(StrORDERFORMNAME)</p> <p>For Each Colitem in ObjmscsorderDerform.Items</p> <p>Colitem.Value ("Shipping_Address_ID") = straddressID</p> <p>NEXT</p> <p>NEXT</p> <p>Finally, set the consignee address of the entire ORDERGROUP; for the previously set address, if it is not used, it is deleted; then save the shopping basket. Redirect the user to ShippingMethod.PASP to specify the delivery method for the order:</p> <p>Call objmscsordergrp.setshippingaddress (straddressid) call objmscsordergrp.saveasbasket ()</p> <p>Set objmscsordergrp = Nothing</p> <p>Response.Redirect "ShippingMethod.PASP"</p> <p>However, if the user is first accessing the shipping.pasp page, you must retrieve the possible address list from the user profile to display the list in the form. The code in Shipping.PASP uses ADO queries to retrieve in the address table of the site database, as shown below:</p> <p>StrUserid = getUserid ()</p> <p>SET CNBIZDESK = Server.createObject (mc_stradodb_connection)</p> <p>SET RSADDRESS = Server.createObject (MC_STRADODB_RECORDSET)</p> <p>CNBIZDESK.Open_</p> <p>Application ("mscsdictconfig"). S_bizDataStoreConnectionstring</p> <p>rsAddress.Open "select g_address_id as' address_id ', i_address_type as' address_type', u_description as' description ', u_address_name as' address_name', u_address_line1 as' address_line1 ', u_address_line2 as' address_line2', u_city as' city ', u_region_name as' Region_code ', u_region_name as' region_name', u_postal_code as' postal_code 'from address, where g_id =' "& struserid &" 'Order by u_address_name ", CNBIZDESK</p> <p>If an address is not listed in the user's configuration file, use the MODE parameter to redirect the user to the EditadDressBook.PASP page. This parameter returns the user to this page after adding the address:</p> <p>If ifeaddress.eof the 'does not enter any address for the user ID</p> <p>Rsaddress.close</p> <p>Set rsaddress = Nothing</p> <p>CNBIZDESK.CLOSE</p> <p>SET CNBIZDESK = Nothing</p> <p>Response.Redirect "EditadDressbook.Pasp? Mode =" & MC_STRPAGENAME</p> <p>END IF</p> <p>If the user profile contains one or more addresses, add the address information to the shopping basket (the last address specified is the default consignee address) and rendered it as an XML:</p> <p>Call Xmlbegtag (MC_STRADDRESSES)</p> <p>Do While Not Rsaddress.eof</p> <p>straddressID = Rsaddress.fields ("Address_ID"). Value</p> <p>STRDESCRIPTION = RSADDRESS.FIELDS ("Description"). Value</p> <p>StraddressName = rsaddress.fields ("address_name"). ValueSSRADRESSLINE1 = RsAddress.fields ("address_line1"). Value</p> <p>StraddressLine2 = Rsaddress.fields ("Address_Line2"). Value</p> <p>Strcity = rsaddress.fields ("city"). Value</p> <p>Strregioncode = rsaddress.fields ("region_code"). Value</p> <p>StrregionName = rsaddress.fields ("region_name"). Value</p> <p>Strpostalcode = rsaddress.fields ("postal_code"). Value</p> <p>BLNSAVESUCCESSFUL = PutorderAddress (Objmscsordergrp, _</p> <p>MC_LNGSHIPPINGADDRESS, STRADDRESSID, STRADDRESSNAME, _</p> <p>StraddressLine1, StraddressLine2, StRCITY, STRREGONNAME, _</p> <p>Strpostalcode, STRDESCRIPTION)</p> <p>IF BLNSAVESUCCESSFUL THEN</p> <p>Call Xmlbegtag (MC_STRADDRESS)</p> <p>Call XMLTAG (MC_STRADDRESS_ID, STRADDRESSID)</p> <p>Call XMLTAG (MC_STRDESBRIPTION, STRDESCRIPTION)</p> <p>Call XMLTAG (MC_STRADDRESS_NAME, STRADDRESSNAME)</p> <p>Call XMLTAG (MC_STRADDRESS_LINE1, STRADDRESSLINE1)</p> <p>Call XMLTAG (MC_STRADDRESS_LINE2, STRADDRESSLINE2)</p> <p>Call XMLTAG (MC_STRCITY, STRCITY)</p> <p>Call XMLTAG (MC_STRREGON_CODE, STRREGONNAME)</p> <p>Call XMLTAG (MC_STRRREGON_NAME, STRREGONNAME)</p> <p>Call XMLTAG (MC_STRPOSTAL_CODE, STRPOSTALCODE)</p> <p>Call XmlendTag (MC_STRADDRESS)</p> <p>'Set payment address</p> <p>IF faddress.fields ("address_type"). Value = 2 THEN</p> <p>Objmscsordergrp.value ("ORDERFORMS"). Value_</p> <p>("default"). Value ("billing_address_id") = straddressID</p> <p>END IF</p> <p>END IF</p> <p>Rsaddress.movenext</p> <p>Loop</p> <p>Call XmlendTag (MC_STRADDRESSES)</p> <p>END IF</p> <p>The XML format generated by this code is shown in the following code:</p> <p><addresses></p> <p><address></p> <p><address_id> {0243FFF8-E633-4DE4-AA2E-2083E9D5ABB4} </ address_id></p> <p><Description> Home Address </ Description></p> <p><address_name> Kim Abercrombie </ address_name></p> <p><address_line1> My residential number </ address_line1> <address_line2> My Street </ address_line2></p> <p><city> redmond </ city></p> <p><region_code> Washington </ region_code></p> <p><region_name> Washington </ region_name></p> <p><postal_code> 12345 </ postal_code></p> <p></ address></p> <p><address></p> <p><address_id> {b87edb27-8fbe-4bda-83be-ed037a0b7e4c} </ address_id></p> <p><Description> Work Address </ Description></p> <p><address_name> Kim Abercrombie </ address_name></p> <p><address_line1> Microsoft Corp. </ address_line1></p> <p><address_line2> 1 Microsoft Way </ address_line2></p> <p><city> redmond </ city></p> <p><region_code> Washington </ region_code></p> <p><region_name> Washington </ region_name></p> <p><postal_code> 54321 </ postal_code></p> <p></ address></p> <p></ addresses></p> <p>Specify delivery method</p> <p>After the user specifies the consignee address for the order, the delivery method must be selected. Commerce Server 2000 supports a variety of delivery methods, each method has different price ranges, depending on the weight, number of projects or total order. (For more information on defining delivery methods, please refer to the Commerce Server 2000 documentation.)</p> <p>Use ShippingMethod.PASP pages, users can select one from the numerous shipments defined in the site database. This page contains a form that lists various shipments as an option. After the user selects an option, send the selected selection back to this page and processes. Retrieve the delivery method from the application level ShippingMethodsXML variable to display.</p> <p>The available shipping method list is retrieved from the application-level ShipPingMethodsXML variable, which initializes the variable using the getshippingMethodsXML function in Global.asa, as shown below:</p> <p>Function getshippingMethodsXML (ObjmscsdictConfig)</p> <p>DIM Objmscsshpmthmgr</p> <p>Dim RsshippingMethods</p> <p>DIM STRXMLSTREAM</p> <p>Strxmlstream = "" "</p> <p>Set objmscsshpmthmgr = _</p> <p>Server.createObject ("Commerce.ShippingMethodManager)</p> <p>Objmscsshpmthmgr.initialize _</p> <p>(ObjmscsDictconfig.s_TransactionsConnectionstring)</p> <p>SET RSSHIPPINGMETHODS = _</p> <p>Objmscsshpmthmgr.getInstalledMethodList_</p> <p>("", "Shipping_Method_name", Array ("Shipping_Method_ID", _ "Shipping_Method_name")))))</p> <p>If not (rsshippingmethods.eof and rsshippingmethods.bof) THEN</p> <p>Do While Not RsshippingMethods.eof</p> <p>Strxmlstream = strxmlstream & vbcrlf & "<shipping_method>"</p> <p>Strxmlstream = strxmlstream & vbcrlf & "<shipping_method_id>" & _</p> <p>RSshippingMethods.fields ("Shipping_Method_ID"). Value &_</p> <p>"</ shipping_method_id>"</p> <p>Strxmlstream = Strxmlstream & Vbcrlf &_</p> <p><shipping_method_name> "& _</p> <p>RSshippingMethods.fields ("Shipping_Method_name"). Value &_</p> <p>"</ shipping_method_name>"</p> <p>Strxmlstream = strxmlstream & vbcrlf & "</ shipping_method>"</p> <p>rsshippingmethods.movenext</p> <p>Loop</p> <p>END IF</p> <p>Set objmscsshpmthmgr = Nothing</p> <p>GetshippingMethodsXML = Strxmlstream</p> <p>END FUNCTION</p> <p>The ShippingMethod.PASP page contains a list of available shipments, as shown in the following XML format:</p> <p><shipping_method></p> <p><shipping_method_id></p> <p>{00000000-0000-0000-0000-003688009465}</p> <p></ shipping_method_id></p> <p><shipping_method_name> Express </ shipping_method_name></p> <p></ shipping_method></p> <p><shipping_method></p> <p><shipping_method_id></p> <p>{00000000-0000-0000-0000-001140002642}</p> <p></ shipping_method_id></p> <p><shipping_method_name> Stand </ shipping_method_name></p> <p></ shipping_method></p> <p>When the user selects the delivery method, the ID and name of the method must be stored in ORDERGROUP. Since only ID passed from the form, you must retrieve the name from the database using the Commerce Server ShipPingMethodManager object. This object provides a GetInStalledMethodList method, using this method to retrieve the method of matching specified criteria as a recordset. The code based on the supplied ID retrieval related method name is similar to the following:</p> <p>Set objmscsshpmthmgr = _</p> <p>Server.createObject (MC_STRSHIPPINGMETHODMANAGER)</p> <p>Objmscsshpmthmgr.initialize (Application ("mscsdictconfig"). _s_bizdatastoreConnectionstring)</p> <p>SET RSSHPMTHNAME = Objmscsshpmthmgr.getInstalledMethodList_</p> <p>("Shipping_Method_ID = '" &</p> <p>STRSHIPPINGMETHODID & "'" "," ", _</p> <p>Array (MC_STRSHIPPING_METHOD_NAME))</p> <p>Set objmscsshpmthmgr = Nothing</p> <p>IF not (rsShpmthname.eof and ly) THEN</p> <p>STRSHIPPINGMETHODNAME = rsShpmthname.fields (0) .Value</p> <p>END IF</p> <p>rsshpmthname.close</p> <p>SET RSSHPMTHNAME = Nothing</p> <p>After searching for the delivery method name, you will use the delivery method data to update the items in the shopping cart and redirect the user to payment.pasp to specify payment information:</p> <p>For Each StrorderFormName In objmscsordergrp.value.orderForms</p> <p>Set objmscsorderform = objmscsordergrp.value. _</p> <p>OrderForms (StrORDERFORMNAME)</p> <p>For Each Colitem in ObjmscsorderDerform.Items</p> <p>Colitem.Value (mc_strshipping_method_id) = strshippingmethodidId</p> <p>Colitem.Value (mc_strshipping_method_name) = strshippingmethodname</p> <p>NEXT</p> <p>NEXT</p> <p>Call objmscsordergrp.saveasbasket ()</p> <p>Set objmscsordergrp = Nothing</p> <p>Response.Redirect "payment.pasp"</p> <p>Specify multiple consignee addresses and delivery methods</p> <p>Users can specify different consignee addresters and shipments for each project in the shopping cart. The code that supports this feature is located in the multishipping.pasp page. This page contains a set of TxtShippingMethodID and TXTADDRESSID input fields (each project in the shopping basket has an input field).</p> <p>When the user requests the delivery method and address of each project, send the form back to multishipping.pasp while updating the OrderGroup representing the shopping basket. The following code is used to update the shipping method and address data of each item:</p> <p>'Fill each item with shipping method ID</p> <p>For Each StrorderFormName In objmscsordergrp.value.orderForms</p> <p>Set objmscsorderform = _</p> <p>Objmscsordergrp.value.orderForms (StrORDERFORMNAME)</p> <p>For Each Colitem in ObjmscsorderDerform.Items</p> <p>INTINDEX = INTINDEX 1</p> <p>strshippingmethodid = _</p> <p>Request.form ("txtshippingmethodid). Item (intIndex)</p> <p>STRSHIPPINGMETHODNAME = NULL</p> <p>IF not isnull (strshippingmethodid) THEN</p> <p>'Shipping method name</p> <p>Set objmscsshpmthmgr = server.createObject _ (MC_STRSHIPINGMETHODMANAGER)</p> <p>Objmscsshpmthmgr.initialize (Application ("mscsdictconfig").</p> <p>S_bizdatastoreConnectionstring)</p> <p>SET RSSHPMTHNAME = Objmscsshpmthmgr.getInstalledMethodList_</p> <p>("Shipping_Method_ID = '" & strshippingMethodID & _</p> <p>"'", ", Array (mc_strshipping_method_name))</p> <p>Set objmscsshpmthmgr = Nothing</p> <p>IF not (rsShpmthname.eof and ly) THEN</p> <p>STRSHIPPINGMETHODNAME = rsShpmthname.fields (0) .Value</p> <p>Else</p> <p>STRSHIPPINGMETHODID = NULL</p> <p>END IF</p> <p>rsshpmthname.close</p> <p>SET RSSHPMTHNAME = Nothing</p> <p>END IF</p> <p>Straddressid = Request.form ("TXTADDRESSID"). Item (intIndex)</p> <p>Colitem.Value (mc_strshipping_method_id) = strshippingmethodidId</p> <p>Colitem.Value (mc_strshipping_method_name) = strshippingmethodname</p> <p>Colitem.Value ("Shipping_Address_ID") = straddressID</p> <p>NEXT</p> <p>Specify payment information</p> <p>As part of the checkout process, the user must specify payment details for the order. Payment.PASP Pages handle this in order processing order.</p> <p>Note: In this application example, the payment details are transmitted in the form of plain text using HTTP. In the actual site, HTTPS should be used to encrypt payment data.</p> <p>The Payment.PASP page contains a form that allows users to specify credit cards and payment address details from the configuration file. If the payment address is not defined in the configuration file, redirect the user to the EditadDressBook.PASP page that can add this address. Payment.PASP page reads the payment details in this form and then writes the information to the OrderGroup object representing the user's shopping basket.</p> <p>struserid = getUserid</p> <p>Set objmscsordergrp = loadingbasket (struserid)</p> <p>For Each StrorderFormName In objmscsordergrp.value.orderForms</p> <p>Set objmscsorderform = objmscsordergrp.value. _</p> <p>OrderForms (StrORDERFORMNAME)</p> <p>'Payment Method - Site only supports credit card</p> <p>ObjmscsOrderform.Value ("payment_method") = "credit_card"</p> <p>'Credit card full name</p> <p>Objmscsorderform.Value ("cc_name") = strpaymentMethod</p> <p>'Credit card internal code</p> <p>Objmscsorderform.value ("cc_code") = strpaymentMethod 'credit card holder name</p> <p>Objmscsorderform.value ("cc_account_holder") = STRNAMEONACCT</p> <p>' credit card number</p> <p>Objmscsorderform.Value ("cc_number") = strcardno</p> <p>'Credit card expiration month</p> <p>Objmscsorderform.value ("cc_expmonth") = strcardexpmth</p> <p>'Credit card expired year</p> <p>Objmscsorderform.Value ("cc_expyear") = strcardexpyr</p> <p>NEXT</p> <p>Call objmscsordergrp.saveasbasket ()</p> <p>Response.Redirect "ORDERSUMMARY.PASP"</p> <p>After filling out the payment information, the user will be redirected to the OrdersumMary.PASP page.</p> <p>Confirm order details</p> <p>Before entering the last step of the order processing, the user also has the opportunity to confirm or change order details. Order details are displayed on the ordersummary.pasp page.</p> <p>The code uses two pipes to retrieve order details in order to display this information. First, the Pagbasket pipe has retrieves the content of the shopping basket. The PAGTOTAL pipelines then calculates shipping costs and small centers. For instructions on Pagbasket pipeline, refer to the "View Shopping Basket" section in this chapter. Pagtotal Pipeline will be introduced in the next section.</p> <p>Pagtotal pipeline</p> <p>Pagtotal pipes are shown in Figure 7-3. Open TOTAL.PCF using the Commerce Server pipeline editor.</p> <p>Figure 7-3: Pagtotal pipeline</p> <p>Demolition stage of goods</p> <p>The "goods split" stage is ready for the delivery dictionary. This phase involves two components:</p> <p>Commerce.Splitter: Detachment Assembly Generates Shipment (Shipments), this dictionary is in ORDERFORM. This dictionary contains the goods to be sent separately, which are created according to the shipping_address_id and shipping_method_id values ​​in the order. Commerce.shippingMethodrouter: ShippingMethodRouter Components Read ShipPingManagerCache using the CacheManager object to map the shipping method to a specific delivery component. This component browsses the list of shipping methods, if there is a cargo sent by the specified method, which will collect the dictionary of these goods, pass the goods to the shipping component, and then run the relevant shipping component. The total shipping costs of each delivery component are calculated. After processing all the goods sent, the total shipping cost will be calculated.</p> <p>Shipping phase</p> <p>The shipping discount is applied to orders during the "shipping" phase. This phase only involves a component: ShippingDiscountadjust. This component checks _shipping_discount_type and adjusts the total assembly fee for the order. If the discount is blank, the component does not perform any operation. If the discount type is 1 or 2, the component is applied to the assembly. If the discount is neither a blank is not a discount type 1 or 2, the component returns an error. Use the ORDERDISCOUNT object to determine the _shipping_discount_type value.</p> <p>Conductor stage</p> <p>The "Office" phase sets in the order form _handling_total. This phase involves the following two components:</p> <p>DEFAULTHANDLINGCY: This component assigns zero to the General Office of the Order Dictionary. It is a placeholder component, which will be replaced by another office component when used. RequiredHandlingcy: RequiredHandlingcy Component Check ORDER._HANDLING_TOTAL button exists. Tax stage</p> <p>The "tax" phase sets the _tax_total and _tax_included value on the order form. This phase involves the following two components:</p> <p>SampleRegionalTax: This component sets the tax field (_CY_TAX_TAX_TAX_INCLUDED) based on tax information in RegionalTaxCache to a suitable tax value. RequiredTaxcy: RequiredTaxcy Component Check the order form exists _cy_tax_total and _cy_tax_included keys. If a key does not exist, RequiredTaxcy retrieves the error message text from the MessageManager using the PUR_BADTAX constant and stores the message in the order of the orderform _purchase_errors.</p> <p>Order total</p> <p>The "Order Total" phase sets the _total_total value on the order form. This phase involves the following three components:</p> <p>DEFAULTTOALCY: Whether all four totals are set on this component check order. If these four values ​​exist, add them and assign the summary to the final total of the order dictionary. If some values ​​are missing, the component will stop running and return an error. Persistility: Persistility is a custom component for copying the values ​​in ORDERFORM. It is mainly used to persist value. Otherwise, the ORDERFORM value at the beginning of the following line (_) is not persisted. The source code of the PersistUtility component is provided with Visual C to provide with the business reference architecture. RequiredTotalcy: RequiredTotalcy Components Browse the _verify_with dictionary, make sure each key exists in the order form and has the same value.</p> <p>Correction phase</p> <p>The last stage is a "correction" phase, which only involves a component: Truncate Description. In Commerce Server 2000, the fields that have more than 255 characters in length will be attributed to the text type; and this component is written in VBScript, providing a method of solving this problem.</p> <p>Get the user's email address</p> <p>After running the pipeline, the code in OrdersumMary.Pasp retrieves ProfileObject for the current user, and extracts the email address to the order confirmation message. Then add the address to the default ORDERFORM of OrderGroup, save the OrderGroup:</p> <p>'Get the default Orderform</p> <p>Set objmscsorderform = objmscsordergroup.value ("ORDERFORMS"). _</p> <p>Value ("Default")</p> <p>'Setup email addresses for order confirmation messages.</p> <p>Set objmscsprofileObject = getUserObject ()</p> <p>Objmscsorderform.user_email_address = objmscsprofileObject_</p> <p>(MC_STRGENERALINFO) .VALUE (MC_STREMAIL_ADDRESS)</p> <p>Set objmscsprofileObject = Nothing</p> <p>Call objmscsordergroup.saveasbasket () Finally, use the Commerce Server DictionaryXmlTransForms object to convert the contents of the ORDERGROUP to XML and write it to the Response object, as shown in the following code:</p> <p>Set objxmltransforms = _</p> <p>Server.createObject (mc_strxmltransforms)</p> <p>Set objxmlorderform = _</p> <p>Objxmltransforms.generatexmlfordictionaryusingschema _</p> <p>(ObjmscsORDERFORM, Application ("Transformschema"))</p> <p>Set objmscsorderform = Nothing</p> <p>Set objxmltransforms = Nothing</p> <p>IF not isempty (objxmlorderform) THEN</p> <p>Response.write ObjxmlORDERFORM.XML</p> <p>Else</p> <p>Call AddException (M_Varrexceptions, "1222", _</p> <p>"Error when converting OrderForm into XML.", _</p> <p>"Basket.asp")</p> <p>END IF</p> <p>This will generate OrderGroup represented by the following XML format:</p> <p><ORDERFORM ORDERFORM_ID = "{CD9EABBE-B0BF-48FE-9DB9-58A35A8FEE9F}"</p> <p>Payment_method = "CREDIT_CARD"</p> <p>BILLING_ADDRESS_ID = "{0243FFF8-E633-4DE4-AA2E-2083E9D5ABB4}"</p> <p>Saved_cy_oadjust_subtotal = "44.98" Saved_cy_total_total = "49.98"</p> <p>Cc_name = "American express" cc_expyear = "2001" cc_expmonth = "08"</p> <p>CC_Number = "1234" _cy_shipping_total = "5" _cy_tax_total = "0"</p> <p>User_email_address = "kim@somecompany.com"</p> <p>CC_account_holder = "kim" cy_tax_total = "0"</p> <p>CY_SHIPPING_TOTAL = "5"></p> <p><Addresses address_name = "kim abercrombie" address_line1 = "My residential"</p> <p>Address_Line2 = "My Street" City = "My City" region_code = "wa"</p> <p>Postal_code = "12345" country_code = "US" Description = "Home Address"</p> <p>AddresSdictKey = "{0243FFF8-E633-4DE4-AA2E-2083E9D5ABB4}" /></p> <p><Items quantity = "1"</p> <p>Product_ID = "Quick Course In Microsoft Office 2000" Product_name = "Quick Course In Microsoft Office 2000"</p> <p>Product_catalog = "book" product_category = ""</p> <p>description = "QUICK COURSE IN MICROSOFT OFFICE 2000 provide some crash course to help you learn the basics quickly this office suite, familiar with Microsoft Excel, Microsoft Word, Microsoft PowerPoint, Microsoft Outlook, Microsoft Access, Microsoft Internet Exp"</p> <p>Shipping_address_id = "{0243FFF8-E633-4DE4-AA2E-2083E9D5ABB4}"</p> <p>Shipping_method_id = "{00000000-0000-0000-0000-003688009465}"</p> <p>SHIPPING_METHOD_NAME = "Express"</p> <p>D_datecreated = "16/02/2001 18:36:06" CY_LINEITEM_TOTAL = "24.99"</p> <p>CY_Unit_price = "24.99"</p> <p>LineItem_UID = "{FC57A7EA-1420-40A8-8F55-569FE9B2BEDE}"</p> <p>_Product_name = "Quick Course In Microsoft Office 2000"</p> <p>_CY_OADJUST_ADJUSTEDPRICE = "24.99" /></p> <p><shipments</p> <p>Shipping_address_id = "{0243FFF8-E633-4DE4-AA2E-2083E9D5ABB4}"</p> <p>Shipping_method_id = "{00000000-0000-0000-0000-003688009465}"</p> <p>_CY_SHIPPING_TOTAL = "5" /></p> <p></ orderform></p> <p>Complete order processing</p> <p>After the user confirms the order details, the order processing is complete. The code for the last step of order processing is implemented in the touryou.pasp page.</p> <p>Run the previously described Pagbasket and Pagtotal pipes, start running Thankyou.Pasp. Then, run the PAGFinal pipe to complete the order processing.</p> <p>PAGFinal pipeline</p> <p>Use the Commerce Server pipeline editor to open Final.PCF, you can view the PAGFinal pipe. The PAGFinal pipe is shown in Figure 7-4.</p> <p>Figure 7-4: PAGFinal pipeline</p> <p>The only stage in the ordering process is named Ordertransfer. This phase only involves a component: Queueemail Class. This is a custom pipeline assembly for sending an order confirmation message in the form of an email to the user_e-mail_address field in the default ORDERFORM.</p> <p>Send an order to confirm email</p> <p>QueueEmail Class is a pipe component (COM object) for implementing the iPipeLineComponent interface. Queueemail Class Components Get information from ORDERFORM, convert the information to XML, and then use custom Queuedemailer.cmailer queuing components to send information as email messages. Since the queuing component is called to send an email message, this process is performed asynchronous, which prevents the delay in the email process to adversely affect the response time of the user checkout. The custom property page for the Queueemail Class component is used to configure the component in the pipe editor. This will allow you to set the corresponding message queue, tag, and proGID to instantiate the queuing component, which will actually be used to send emails, as shown in Figure 7-5.</p> <p>Figure 7-5: QueueEmail Class Custom Properties Page</p> <p>QueueDemailer.cmailer</p> <p>The process of actually sends an email is processed by the Queuedemailer.cmailer queuing component. This component is mounted in a COM application labeled queued. In addition, since the _cmailer interface is also marked as queuing, the method of this interface is allowed to call through the message queue. The _cmailer interface only contains a method (Sendmail), which is defined using the following method signs:</p> <p>HRESULT Sendmail</p> <p>[in] BSTR STRXMLORDERFORM,</p> <p>[in] Variant_Bool BLNUSEHTMLMAIL);</p> <p>Note that both parameters in the above code are marked as [IN], because the queuing component does not support the [OUT] or [RETVAL] parameter. The STRXMLORDERFORM parameter is used to pass the XML representation of the order form to the component. The BLNUSEHTMLMAIL parameter value is a Boolean value to determine whether to send an email message in an HTML format or in a pure text format.</p> <p>You can also configure the QueueDemailer.cmailer component to support object build. This means that the component can implement the IObjectConstruct interface, which contains a method called construct. When the object is instantiated, COM will call this method. The constructor string is passed to the construct method, which contains configuration information that the object can use. The constructor string transmitted to Queuedemailer.cmailer uses the following XML format:</p> <p><config></p> <p><from> support@consolidatedretail.com </ from></p> <p><Subject> Order Confirm </ SUBJECT></p> <p><TextXSL> C: /inetpub/b2cref/xml/emailtext.xsl </ textxsl></p> <p><Htmlxsl> c: /inetpub/b2cref/xml/emailhtml.xsl </ htmlxsl></p> <p><SMTPSERVER> </ smtpserver></p> <p><SMTPPORT> </ SMTPPORT></p> <p><SMTPTIMEOUT> </ smtptimeout></p> <p><Usesl> false </ usssl></p> <p><SMTPUSERNAME> </ smtpusername></p> <p><SMTPASSWORD> </ smtppassword></p> <p><SMTPAUTHMETHOD> </ smtpauthmethod></p> <p></ config></p> <p>Use the Component Services Microsoft Management Console (MMC) snap-in (as shown in Figure 7-6) to configure this constructor. Figure 7-6: Component Services MMC Management Unit</p> <p>Queuedemailer.cmAiler object uses MSXML3 and CDOSYS objects. The loading of XML and XSL is done with XMLDOMDocument using the MSXML3 object. The actual transmission of the email message is done by the iMessage object (CDO collaboration data object), which is used to use the CDOSYS object. Collaboration Data Objects (CDO) CDOSYS.DLL for Windows 2000 implements version 2.0 version of the CDO API specification, which is a COM component, which is dedicated to simplifying the programming of the creation or manipulating Internet messages.</p> <p>to sum up</p> <p>Now you should have learned the basic features and development strategies behind the consolidatedretail.com application. The code annotation in the article provides more detailed information.</p></div><div class="text-center mt-3 text-grey"> 转载请注明原文地址:https://www.9cbs.com/read-3354.html</div><div class="plugin d-flex justify-content-center mt-3"></div><hr><div class="row"><div class="col-lg-12 text-muted mt-2"><i class="icon-tags mr-2"></i><span class="badge border border-secondary mr-2"><h2 class="h6 mb-0 small"><a class="text-secondary" href="tag-2.html">9cbs</a></h2></span></div></div></div></div><div class="card card-postlist border-white shadow"><div class="card-body"><div class="card-title"><div class="d-flex justify-content-between"><div><b>New Post</b>(<span class="posts">0</span>) </div><div></div></div></div><ul class="postlist list-unstyled"> </ul></div></div><div class="d-none threadlist"><input type="checkbox" name="modtid" value="3354" checked /></div></div></div></div></div><footer class="text-muted small bg-dark py-4 mt-3" id="footer"><div class="container"><div class="row"><div class="col">CopyRight © 2020 All Rights Reserved </div><div class="col text-right">Processed: <b>0.049</b>, SQL: <b>9</b></div></div></div></footer><script src="./lang/en-us/lang.js?2.2.0"></script><script src="view/js/jquery.min.js?2.2.0"></script><script src="view/js/popper.min.js?2.2.0"></script><script src="view/js/bootstrap.min.js?2.2.0"></script><script src="view/js/xiuno.js?2.2.0"></script><script src="view/js/bootstrap-plugin.js?2.2.0"></script><script src="view/js/async.min.js?2.2.0"></script><script src="view/js/form.js?2.2.0"></script><script> var debug = DEBUG = 0; var url_rewrite_on = 1; var url_path = './'; var forumarr = {"1":"Tech"}; var fid = 1; var uid = 0; var gid = 0; xn.options.water_image_url = 'view/img/water-small.png'; </script><script src="view/js/wellcms.js?2.2.0"></script><a class="scroll-to-top rounded" href="javascript:void(0);"><i class="icon-angle-up"></i></a><a class="scroll-to-bottom rounded" href="javascript:void(0);" style="display: inline;"><i class="icon-angle-down"></i></a></body></html><script> var forum_url = 'list-1.html'; var safe_token = 'OlKlmMCzUAgLsn06L50UdzEZpWbzCagCy3U4vUzIHOq60k1dTo8vVEAWApC2OX9adfY1Xso97hruSILzduY3FA_3D_3D'; var body = $('body'); body.on('submit', '#form', function() { var jthis = $(this); var jsubmit = jthis.find('#submit'); jthis.reset(); jsubmit.button('loading'); var postdata = jthis.serializeObject(); $.xpost(jthis.attr('action'), postdata, function(code, message) { if(code == 0) { location.reload(); } else { $.alert(message); jsubmit.button('reset'); } }); return false; }); function resize_image() { var jmessagelist = $('div.message'); var first_width = jmessagelist.width(); jmessagelist.each(function() { var jdiv = $(this); var maxwidth = jdiv.attr('isfirst') ? first_width : jdiv.width(); var jmessage_width = Math.min(jdiv.width(), maxwidth); jdiv.find('img, embed, iframe, video').each(function() { var jimg = $(this); var img_width = this.org_width; var img_height = this.org_height; if(!img_width) { var img_width = jimg.attr('width'); var img_height = jimg.attr('height'); this.org_width = img_width; this.org_height = img_height; } if(img_width > jmessage_width) { if(this.tagName == 'IMG') { jimg.width(jmessage_width); jimg.css('height', 'auto'); jimg.css('cursor', 'pointer'); jimg.on('click', function() { }); } else { jimg.width(jmessage_width); var height = (img_height / img_width) * jimg.width(); jimg.height(height); } } }); }); } function resize_table() { $('div.message').each(function() { var jdiv = $(this); jdiv.find('table').addClass('table').wrap('<div class="table-responsive"></div>'); }); } $(function() { resize_image(); resize_table(); $(window).on('resize', resize_image); }); var jmessage = $('#message'); jmessage.on('focus', function() {if(jmessage.t) { clearTimeout(jmessage.t); jmessage.t = null; } jmessage.css('height', '6rem'); }); jmessage.on('blur', function() {jmessage.t = setTimeout(function() { jmessage.css('height', '2.5rem');}, 1000); }); $('#nav li[data-active="fid-1"]').addClass('active'); </script>