日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅析Microsoft .net PetShop程序中的购物车和订单处理模块(Profile技术,异步MSMQ消息)转...

發布時間:2025/6/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析Microsoft .net PetShop程序中的购物车和订单处理模块(Profile技术,异步MSMQ消息)转... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于Microsoft .net PetShop程序中的購物車和訂單處理模塊,文中主要分析兩種技術的應用:
  1. Profile技術在PetShop程序中用于三處:
   1) 購物車ShoppingCart -下面的例子圍繞購物車流程進行
   2) 收藏WishList
   3) 用戶信息AccountInfo
   注冊新用戶 NewUser.aspx :使用的是CreateUserWizard 控件,基于MemberShip機制,在數據庫MSPetShop4Services的表aspnet_Users中創建用戶
   修改用戶注冊信息 UserProfile.aspx: 基于Profile技術,在數據庫MSPetShop4Profile的表Profiles和Account中創建用戶信息
  2. 異步消息處理技術運用于訂單處理
  4.1 Web.config配置
  Profile可以利用數據庫存儲關于用戶的個性化信息,有點象session對象,但session對象是有生存期的,在生存期后,session對象自動失效了。而profile不同,除非顯式移除它。要實現profile功能,必須先在web.config中進行定義。
  在web.congfig中,將會定義一些屬性/值,分別存貯將要保存的變量和值,比如language屬性,定義其值是string類型,如此類推。而<group>標簽,則是將一些相同或類似功能的變量值放在一起。
  程序中使用方法: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 購物車程序流程-Profile技術
  1. 點擊“加入購物車”: http://localhost:2327/Web/ShoppingCart.aspx?addItem=EST-34
  2. ShoppingCart.aspx文件處理:在init方法之前處理
   protected void Page_PreInit(object sender, EventArgs e) {
   if (!IsPostBack) {
   string itemId = Request.QueryString["addItem"];
   if (!string.IsNullOrEmpty(itemId)) {
   Profile.ShoppingCart.Add(itemId); //注意ShoppingCart的類型是PetShop.BLL.Cart
   //Save 方法將修改后的配置文件屬性值寫入到數據源,如ShoppingCart屬性已經改變
   Profile.Save();
  
   // Redirect to prevent duplictations in the cart if user hits "Refresh"
   //防止刷新造成 多次提交
   Response.Redirect("~/ShoppingCart.aspx", true); //將客戶端重定向到新的 URL。指定新的 URL 并指定當前頁的執行是否應終止。
   }
   }
  3. PetShop.BLL.Cart類
  // 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;
  //獲取與指定的鍵相關聯的值TryGetValue(TKey key,out TValue value)
   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. 更新Profile
  //Save 方法將修改后的配置文件屬性值寫入到數據源,如ShoppingCart屬性已經改變
   Profile.Save();
  如何更新:
   根據配置中的ShoppingCartProvider類型 PetShop.Profile.PetShopProfileProvider。
  ASP.NET 配置文件提供對用戶特定屬性的持久性存儲和檢索。配置文件屬性值和信息按照由 ProfileProvider 實現確定的方式存儲在數據源中。
  每個用戶配置文件在數據庫的 Profiles 表中進行唯一標識。該表包含配置文件信息,如應用程序名稱和上次活動日期。
  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類, 繼承自ProfileProvider
  // 創建 PetShop.SQLProfileDAL.PetShopProfileProvider類-數據庫操作
   private static readonly IPetShopProfileProvider dal
  = DataAccess.CreatePetShopProfileProvider();
  /// <summary>
   /// 設置指定的屬性設置組的值
   /// </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類
  使用事務:包含兩個sql動作,先刪除,再插入
  /// <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 訂單處理技術
  訂單處理技術:――分布式事務
  1) 同步:直接在事務中 將訂單 插入到數據庫中,同時更新庫存
  2) 異步:訂單-》消息隊列(使用MSMQ)-》后臺處理
  4.3.1 使用Wizard組件
  4.3.2 分布式事務處理技術
  開啟MSDTC 服務支持分布式事務. To start the MSDTC service, open Administrative Tools | Services and start the Distributed Transaction Coordinator service
  4.3.3 MSMQ 消息隊列簡介
  1)引用隊列
   引用隊列有三種方法,通過路徑、格式名和標簽引用隊列,這里我只介紹最簡單和最常用的方法:通過路徑引用隊列。隊列路徑的形式為 machinename\queuename。指向隊列的路徑總是唯一的。下表列出用于每種類型的隊列的路徑信息:
  如果是發送到本機上,還可以使用”.”代表本機名稱。
  2)消息的創建
  不過要使用MSMQ開發你的消息處理程序,必須在開發系統和使用程序的主機上安裝消息隊列。消息隊列的安裝屬于Windows組件的安裝,和一般的組件安裝方法類似。
  往系統中添加隊列十分的簡單,打開[控制面板]中的[計算機管理],展開[服務和應用程序],找到并展開[消息隊列](如果找不到,說明你還沒有安裝消息隊列,安裝windows組件),右擊希望添加的消息隊列的類別,選擇新建隊列即可。
  消息接收服務位于System.Messaging中,在初始化時引用消息隊列的代碼很簡單,如下所示:
  MessageQueue Mq=new MessageQueue(“.\\private$\\jiang”);
  通過Path屬性引用消息隊列的代碼也十分簡單:
  MessageQueue Mq=new MessageQueue();
  Mq.Path=”.\\private$\\jiang”;
  使用Create 方法可以在計算機上創建隊列:
  System.Messaging.MessageQueue.Create(@".\private$\jiang");
  3) 發送和接收消息
  過程:消息的創建-》發送-》接收-》閱讀-》關閉
  簡單消息的發送示例如下:
   Mq.Send(1000); //發送整型數據
   Mq.Send(“This is a test message!”); //發送字符串
  接收消息由兩種方式:通過Receive方法接收消息同時永久性地從隊列中刪除消息;通過Peek方法從隊列中取出消息而不從隊列中移除該消息。如果知道消息的標識符(ID),還可以通過ReceiveById方法和PeekById方法完成相應的操作。
   接收消息的代碼很簡單:
   Mq.Receive(); //或Mq.ReceiveById(ID);
   Mq.Peek(); // 或Mq.PeekById(ID);
  閱讀消息
  接收到的消息只有能夠讀出來才是有用的消息,因此接收到消息以后還必須能讀出消息,而讀出消息算是最復雜的一部操作了。消息的序列化可以通過Visual Studio 和 .NET Framework 附帶的三個預定義的格式化程序來完成:XMLMessageFormatter 對象( MessageQueue 組件的默認格式化程序設置)、BinaryMessageFormatter 對象、ActiveXMessageFormatter 對象。由于后兩者格式化后的消息通常不能為人閱讀,所以我們經常用到的是XMLMessageFormatter對象。
  使用XMLMessageFormatter對象格式化消息的代碼如下所示:
   string[] types = { "System.String" };
   ((XmlMessageFormatter)mq.Formatter).TargetTypeNames = types;
   Message m=mq.Receive(new TimeSpan(0,0,3));
   將接收到的消息傳送給消息變量以后,通過消息變量m的Body屬性就可以讀出消息了:
  MessageBox.Show((string)m.Body);
  關閉消息隊列
   消息隊列的關閉很簡單,和其他對象一樣,通過Close函數就可以實現了:
  Mq.Close();
  4.3.4 PetShop程序中訂單處理-使用同步消息
  默認程序使用同步消息 處理,直接操作數據庫插入訂單,更新庫存類
  4.3.5 PetShop程序中訂單處理-使用異步消息
  1) Web程序中調用PetShop.BLL.Order類方法: Insert(OrderInfo order);
  2) PetShop.BLL.Order類
  //IOrderStrategy接口中只有一個插入訂單方法:void Insert(PetShop.Model.OrderInfo order);
   //得到PetShop.BLL. OrderAsynchronous類
   private static readonly PetShop.IBLLStrategy.IOrderStrategy orderInsertStrategy = LoadInsertStrategy();
   //IOrder接口中有兩種方法:Send()與Receive() -消息隊列
   private static readonly PetShop.IMessaging.IOrder orderQueue
  = PetShop.MessagingFactory.QueueAccess.CreateOrder();
  public void Insert(OrderInfo order) {
   // Call credit card procesor,采用隨機化方法設置訂單認證數字
   ProcessCreditCard(order);
   // Insert the order (a)synchrounously based on configuration
   orderInsertStrategy.Insert(order); //調用PetShop.BLL.OrderAsynchronous類
   }
  3) PetShop.BLL. OrderAsynchronous類
  // CreateOrder()方法得到PetShop.MSMQMessaging .Order類的實例
  private static readonly PetShop.IMessaging.IOrder asynchOrder
  = PetShop.MessagingFactory.QueueAccess.CreateOrder();
  public void Insert(PetShop.Model.OrderInfo order) {
   asynchOrder.Send(order); //調用PetShop.MSMQMessaging.Order類
   }
  4) PetShop.MSMQMessaging項目 -關鍵(發送/接收消息)
  PetShopQueue基類:創建消息隊列,發送和接收消息
  Order類:繼承自PetShopQueue類
  public new OrderInfo Receive() { //從隊列中接收消息
   base.transactionType = MessageQueueTransactionType.Automatic;
   return (OrderInfo)((Message)base.Receive()).Body;
   }
  public void Send(OrderInfo orderMessage) { //發送消息到隊列
   base.transactionType = MessageQueueTransactionType.Single;
   base.Send(orderMessage);
   }
  5) PetShop.OrderProcessor項目-后臺處理訂單,將它們插入到數據庫中
  Program類:多線程后臺訂單處理程序,可寫成一個控制臺程序,作為windows服務開啟
  處理隊列中的批量異步訂單,在事務范圍內把它們提交到數據庫

總結

以上是生活随笔為你收集整理的浅析Microsoft .net PetShop程序中的购物车和订单处理模块(Profile技术,异步MSMQ消息)转...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。