Analysis of the shopping cart and order processing module (Profile technology, asynchronous MSMQ message) in the Microsoft. net PetShop Program)

Source: Internet
Author: User
Tags msmq

For the shopping cart and order processing modules in the Microsoft. net PetShop program, this paper mainly analyzes the application of the two technologies:
1. The Profile technology is used in the PetShop program in three places:
1) shopping cart-the following example describes the shopping cart process.
2) Add WishList to favorites
3) AccountInfo
Registering a new user NewUser. aspx: The CreateUserWizard control is used. Based on the MemberShip mechanism, create a user in the aspnet_Users table of the database MSPetShop4Services.
Modify user registration information UserProfile. aspx: Based on Profile technology, create user information in the database MSPetShop4Profile table Profiles and Account
2. asynchronous message processing technology is applied to order processing
4.1 Web. config Configuration
Profile can use the database to store personalized information about users, which is a bit like a session object. However, the session object has a lifetime, and the session object automatically becomes invalid after the lifetime. The profile is different unless it is explicitly removed. To implement the profile function, you must first define it in web. config.
In web. congfig, some attributes/values are defined to store the variables and values to be saved, such as the language attribute, and their values are of the string type. The <group> label puts together variable values of the same or similar functions.
Procedure: Profile. language = ddlLanguage. SelectedItem. Value;
<Profile automaticSaveEnabled = "false" defaultProvider = "ShoppingCartProvider">
<Providers>
<Add name = "ShoppingCartProvider" connectionStringName = "SQLProfileConnString" type = "PetShop. Profile. PetShopProfileProvider" applicationName = ". NET Pet Shop 4.0"/>
<Add name = "WishListProvider" connectionStringName = "SQLProfileConnString" type = "PetShop. Profile. PetShopProfileProvider" applicationName = ". NET Pet Shop 4.0"/>
<Add name = "AccountInfoProvider" connectionStringName = "SQLProfileConnString" type = "PetShop. Profile. PetShopProfileProvider" applicationName = ". NET Pet Shop 4.0"/>
</Providers>
<Properties>
<Add name = "ShoppingCart" type = "PetShop. BLL. Cart" allowAnonymous = "true" provider = "ShoppingCartProvider"/>
<Add name = "WishList" type = "PetShop. BLL. Cart" allowAnonymous = "true" provider = "WishListProvider"/>
<Add name = "AccountInfo" type = "PetShop. Model. AddressInfo" allowAnonymous = "false" provider = "AccountInfoProvider"/>
</Properties>
</Profile>
4.2 shopping cart procedure-Profile Technology
1. Click "add to shopping cart": http: // localhost: 2327/Web/ShoppingCart. aspx? AddItem = EST-34
2. ShoppingCart. aspx File Processing: processing before the init Method
Protected void Page_PreInit (object sender, EventArgs e ){
If (! IsPostBack ){
String itemId = Request. QueryString ["addItem"];
If (! String. IsNullOrEmpty (itemId )){
Profile. ShoppingCart. Add (itemId); // note that the ShoppingCart type is PetShop. BLL. Cart
// The Save method writes the modified configuration file attribute value to the data source. For example, the ShoppingCart attribute has changed.
Profile. Save ();
  
// Redirect to prevent duplictations in the cart if user hits "Refresh"
// Prevent multiple submissions due to refresh
Response. Redirect ("~ /ShoppingCart. aspx ", true); // redirects the client to a new URL. Specify the new URL and whether the execution of the current page should be terminated.
}
}
3. PetShop. BLL. Cart class
// Dictionary: key/value
Private Dictionary <string, CartItemInfo> cartItems = new Dictionary <string, CartItemInfo> ();
/// <Summary>
/// Add an item to the cart.
/// When ItemId to be added has already existed, this method will update the quantity instead.
/// </Summary>
/// <Param name = "itemId"> Item Id of item to add </param>
Public void Add (string itemId ){
CartItemInfo cartItem;
// Obtain the value TryGetValue (TKey key, out TValue) associated with the specified key)
If (! CartItems. TryGetValue (itemId, out cartItem )){
Item item = new Item ();
ItemInfo data = item. GetItem (itemId );
If (data! = Null ){
CartItemInfo newItem = new CartItemInfo (itemId, data. ProductName, 1, (decimal) data. Price, data. Name, data. CategoryId, data. ProductId );
CartItems. Add (itemId, newItem );
}
}
Else
CartItem. Quantity ++;
}
4. Update the Profile
// The Save method writes the modified configuration file attribute value to the data source. For example, the ShoppingCart attribute has changed.
Profile. Save ();
How to update:
According to the ShoppingCartProvider type PetShop. Profile. PetShopProfileProvider in the configuration.
The ASP. NET configuration file provides persistent storage and retrieval of user-specific attributes. The configuration file property values and information are stored in the data source in a way determined by the ProfileProvider.
Each user configuration file is uniquely identified in the database's Profiles table. This table contains the configuration file information, such as the application name and last activity date.
Create table Profiles
(
UniqueID AutoIncrement not null primary key,
Username Text (255) not null,
ApplicationName Text (255) not null,
IsAnonymous YesNo,
LastActivityDate DateTime,
LastUpdatedDate DateTime,
CONSTRAINT PKProfiles UNIQUE (Username, ApplicationName)
)
5. PetShop. Profile. PetShopProfileProvider class, inherited from ProfileProvider
// Create PetShop. SQLProfileDAL. PetShopProfileProvider class-database operation
Private static readonly IPetShopProfileProvider dal
= DataAccess. CreatePetShopProfileProvider ();
/// <Summary>
/// Set the value of the specified attribute setting group
/// </Summary>
Public override void SetPropertyValues (SettingsContext context, SettingsPropertyValueCollection collection ){
String username = (string) context ["UserName"];
CheckUserName (username );
Bool isAuthenticated = (bool) context ["IsAuthenticated"];
Int uniqueID = dal. GetUniqueID (username, isAuthenticated, false, ApplicationName );
If (uniqueID = 0)
UniqueID = dal. CreateProfileForUser (username, isAuthenticated, ApplicationName );
Foreach (SettingsPropertyValue pv in collection ){
If (pv. PropertyValue! = Null ){
Switch (pv. Property. Name ){
Case PROFILE_SHOPPINGCART: // ShoppingCart
SetCartItems (uniqueID, (Cart) pv. PropertyValue, true );
  
Break;
Case PROFILE_WISHLIST:
SetCartItems (uniqueID, (Cart) pv. PropertyValue, false );
  
Break;
Case PROFILE_ACCOUNT:
If (isAuthenticated)
SetAccountInfo (uniqueID, (AddressInfo) pv. PropertyValue );
  
Break;
Default:
Throw new ApplicationException (ERR_INVALID_PARAMETER + "name .");
}
}
}
UpdateActivityDates (username, false );
}
// Update cart
Private static void SetCartItems (int uniqueID, Cart cart, bool isShoppingCart ){
Dal. SetCartItems (uniqueID, cart. CartItems, isShoppingCart );
}
6. PetShop. SQLProfileDAL. PetShopProfileProvider class
Use transactions: contains two SQL actions, which are deleted before being inserted.
/// <Summary>
/// Update shopping cart for current user
/// </Summary>
/// <Param name = "uniqueID"> User id </param>
/// <Param name = "cartItems"> Collection of shopping cart items </param>
/// <Param name = "isShoppingCart"> Shopping cart flag </param>
Public void SetCartItems (int uniqueID, ICollection <CartItemInfo> cartItems, bool isShoppingCart ){
String sqlDelete = "delete from Cart WHERE UniqueID = @ UniqueID AND IsShoppingCart = @ IsShoppingCart ;";
SqlParameter [] parms1 = {
New SqlParameter ("@ UniqueID", SqlDbType. Int ),
New SqlParameter ("@ IsShoppingCart", SqlDbType. Bit )};
Parms1 [0]. Value = uniqueID;
Parms1 [1]. Value = isShoppingCart;
If (cartItems. Count> 0 ){
// Update cart using SqlTransaction
String sqlInsert = "insert into Cart (UniqueID, ItemId, Name, Type, Price, CategoryId, ProductId, IsShoppingCart, Quantity) VALUES (@ UniqueID, @ ItemId, @ Name, @ Type, @ Price, @ CategoryId, @ ProductId, @ IsShoppingCart, @ Quantity );";
SqlParameter [] parms2 = {
New SqlParameter ("@ UniqueID", SqlDbType. Int ),
New SqlParameter ("@ IsShoppingCart", SqlDbType. Bit ),
New SqlParameter ("@ ItemId", SqlDbType. VarChar, 10 ),
New SqlParameter ("@ Name", SqlDbType. VarChar, 80 ),
New SqlParameter ("@ Type", SqlDbType. VarChar, 80 ),
New SqlParameter ("@ Price", SqlDbType. Decimal, 8 ),
New SqlParameter ("@ CategoryId", SqlDbType. VarChar, 10 ),
New SqlParameter ("@ ProductId", SqlDbType. VarChar, 10 ),
New SqlParameter ("@ Quantity", SqlDbType. Int )};
Parms2 [0]. Value = uniqueID;
Parms2 [1]. Value = isShoppingCart;
SqlConnection conn = new SqlConnection (SqlHelper. ConnectionStringProfile );
Conn. Open ();
SqlTransaction trans = conn. BeginTransaction (IsolationLevel. ReadCommitted );
Try {
SqlHelper. ExecuteNonQuery (trans, CommandType. Text, sqlDelete, parms1 );
Foreach (CartItemInfo cartItem in cartItems ){
Parms2 [2]. Value = cartItem. ItemId;
Parms2 [3]. Value = cartItem. Name;
Parms2 [4]. Value = cartItem. Type;
Parms2 [5]. Value = cartItem. Price;
Parms2 [6]. Value = cartItem. CategoryId;
Parms2 [7]. Value = cartItem. ProductId;
Parms2 [8]. Value = cartItem. Quantity;
SqlHelper. ExecuteNonQuery (trans, CommandType. Text, sqlInsert, parms2 );
}
Trans. Commit ();
}
Catch (Exception e ){
Trans. Rollback ();
Throw new ApplicationException (e. Message );
}
Finally {
Conn. Close ();
}
}
Else
// Delete cart
SqlHelper. ExecuteNonQuery (SqlHelper. ConnectionStringProfile, CommandType. Text, sqlDelete, parms1 );
}
4.3 Order Processing Technology
Order Processing Technology:-distributed transactions
1) Synchronization: insert orders directly into the database in the transaction and update the inventory.
2) asynchronous: Order-> Message Queue (using MSMQ)-> background processing
4.3.1 use the Wizard component
4.3.2 Distributed Transaction Processing Technology
Start the MSDTC service To support Distributed transactions. To start the MSDTC service, open Administrative Tools | Services and start the Distributed Transaction Coordinator service
4.3.3 MSMQ Message Queue Overview
1) Reference queue
There are three methods to reference a queue: reference a queue by path, format name, and tag. Here I will only introduce the simplest and most commonly used method: reference a queue by path. The queue path is in the form of machinename \ queuename. The path to the queue is always unique. The following table lists the paths used for each type of queue:
If it is sent to the local machine, you can also use "." To represent the local name.
2) message creation
However, to use MSMQ to develop your message processing program, you must install message queue on the development system and host that uses the program. The installation of message queue is the installation of Windows components, which is similar to that of general components.
It is very easy to add a queue to the system. Open [Computer Management] in [control panel], expand [services and applications], find and expand [Message Queue] (if not found, it indicates that you have not installed message queue and installed windows Components.) Right-click the type of the Message Queue you want to add and select create queue.
The message receiving service is located in System. Messaging. The code for referencing the Message Queue during initialization is very simple, as shown below:
MessageQueue Mq = new MessageQueue (". \ private $ \ jiang ");
The code for referencing a Message Queue through the Path attribute is also very simple:
MessageQueue Mq = new MessageQueue ();
Mq. Path = ". \ private $ \ jiang ";
You can use the Create method to Create a queue on a computer:
System. Messaging. MessageQueue. Create (@ ". \ private $ \ jiang ");
3) send and receive messages
Process: Message creation-send-receive-read-close
An example of sending a simple message is as follows:
Mq. Send (1000); // Send Integer Data
Mq. Send ("This is a test message !"); // Send a string
Two methods are used to Receive a message: the Receive method is used to Receive the message and permanently delete the message from the queue. The Peek method is used to retrieve the message from the queue without removing the message from the queue. If you know the message identifier (ID), you can use the ReceiveById method and the PeekById method to complete the corresponding operation.
The message receiving code is simple:
Mq. Receive (); // or Mq. ReceiveById (ID );
Mq. Peek (); // or Mq. PeekById (ID );
Read messages
Only the messages received can be read out. Therefore, you must read the messages after receiving them. Reading the messages is the most complex operation. Message serialization can be performed through Visual Studio and. NET Framework comes with three predefined formatters to complete: XMLMessageFormatter object (default formatter setting of the MessageQueue component), BinaryMessageFormatter object, and ActiveXMessageFormatter object. Because messages formatted by the latter two cannot be read by humans, we often use XMLMessageFormatter objects.
The following code uses the XMLMessageFormatter object to format a message:
String [] types = {"System. String "};
(XmlMessageFormatter) mq. Formatter). TargetTypeNames = types;
Message m = mq. Receive (new TimeSpan (0, 0, 3 ));
After the received message is sent to the Message variable, the message can be read through the Body attribute of the message variable m:
MessageBox. Show (string) m. Body );
Disable Message Queue
Closing a message queue is simple. Like other objects, you can use the Close function to achieve the following:
Mq. Close ();
4.3.4 process orders in the PetShop Program-use synchronous messages
By default, the program uses synchronous Message Processing to directly insert orders into the database and update the inventory class.
4.3.5 order processing in the PetShop Program-use asynchronous messages
1) The PetShop. BLL. Order class method is called in the Web program: Insert (OrderInfo order );
2) PetShop. BLL. Order class
// There is only one Insert order Method in the IOrderStrategy interface: void Insert (PetShop. Model. OrderInfo order );
// Obtain the PetShop. BLL. OrderAsynchronous class.
Private static readonly PetShop. IBLLStrategy. IOrderStrategy orderInsertStrategy = LoadInsertStrategy ();
// There are two methods in the IOrder interface: Send () and Receive ()-Message Queue
Private static readonly PetShop. IMessaging. IOrder orderQueue
= PetShop. MessagingFactory. QueueAccess. CreateOrder ();
Public void Insert (OrderInfo order ){
// Call credit card procesor, which uses the Randomization method to set order authentication numbers
ProcessCreditCard (order );
// Insert the order (a) synchrounously based on configuration
OrderInsertStrategy. Insert (order); // call the PetShop. BLL. OrderAsynchronous class.
}
3) PetShop. BLL. OrderAsynchronous class
// Obtain the instance of the PetShop. MSMQMessaging. Order class by using the CreateOrder () method
Private static readonly PetShop. IMessaging. IOrder asynchOrder
= PetShop. MessagingFactory. QueueAccess. CreateOrder ();
Public void Insert (PetShop. Model. OrderInfo order ){
AsynchOrder. Send (order); // call the PetShop. MSMQMessaging. Order class.
}
4) PetShop. MSMQMessaging project-Key (send/receive messages)
PetShopQueue base class: Creates a message queue, sends and receives messages.
Order class: inherited from PetShopQueue class
Public new OrderInfo Receive () {// receives messages from the queue
Base. transactionType = MessageQueueTransactionType. Automatic;
Return (OrderInfo) (Message) base. Receive (). Body;
}
Public void Send (OrderInfo orderMessage) {// Send a message to the queue
Base. transactionType = MessageQueueTransactionType. Single;
Base. Send (orderMessage );
}
5) PetShop. OrderProcessor project-process orders in the background and insert them into the database
Program class: multi-threaded background order processing Program, which can be written into a console Program and enabled as a windows Service
Process batch asynchronous orders in the queue and submit them to the database within the transaction Scope

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.