牛腩购物网28:购物车中商品转换为订单,asp.net 页面间传值,asp.net 事务,ToString("D5")填充到5位数,同时插入订单表和订单详情表
asp.net 的页面间,如何进行传值呢?网上写了有3个方法
1:querystring 这个简单 例如 http://www.xx.com/product.aspx?id=10 这个就是传值过去了
2:session 和 application 传值,这个也简单
3:Cookie 传值
4:Server.Transfer()方式
在这里,我遇到的是,在订单修改页面,向订单确认页面确定的时候,需要填写收件人的信息,而我的 form 已经是放在了 toopfoot.master 母版页里面了,所以这里用到session 传值
如何保存呢?如果是asp的话,就很好做了吧,弄一个表单 form ,然后接收值的页面 一个一个的 request.form 就可以了 呵呵。
废话少说,我们把这些 文本,放到一个 model 的实体类里面,然后把这个实体类,保存到 session里面,这样后面的订单页面就可以接收session的实体类的值了。
//确定订单的时候,要判断购物车是不是空的 protected void btnAdd_Click(object sender, EventArgs e) { if (Session["cart"] != null) { Model.ShopCart sc = Session["cart"] as Model.ShopCart; if (sc.GetItemCount() == 0) { Utility.Tool.alert("购物车为空,请先添加商品", "/default.aspx", this.Page); return; } else { //还要判断收件人等等字段是否为空 string RevName = txtRevName.Text.Trim(); string sex = ddlSex.SelectedValue.Trim(); string RevAddress = txtRevAddress.Text.Trim(); string PostCode = txtPostCode.Text.Trim(); string Tel = txtTel.Text.Trim(); string email = txtEmail.Text.Trim(); string kuaidi = rblKuaiDi.SelectedValue; string paytype = rblPayType.SelectedValue; if (RevName.Length == 0 || sex.Length == 0 || RevAddress.Length == 0 || PostCode.Length == 0 ||
Tel.Length == 0 || email.Length == 0 || kuaidi.Length == 0 || paytype.Length==0) { Utility.Tool.alert("请填写完毕收货人的信息", this.Page); return; } else { //为了传值,我们把上面的收件人信息,放到一个 model实体类里面,然后把这个实体类保存到 session 里面 Model.Order order = new Model.Order { recname=RevName, sex=sex, address=RevAddress, postcode=PostCode, phone=Tel, email=email, sendtype=kuaidi, paytype=paytype }; Session["order"] = order; Response.Redirect("/order_confirm.aspx"); } } } else { Utility.Tool.alert("购物车为空,请先添加商品", "/default.aspx", this.Page); return; } }
然后在我们的 订单确认页面,我们把 session里面的值,再传给页面。
protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { decimal shopprice = 0; //商品价格 if (Session["cart"] != null) { Niunan.Shop.Model.ShopCart sc = Session["cart"] as Model.ShopCart; rep.DataSource = sc.GetItemList(); rep.DataBind(); //商品种类数量 litShopCount.Text = sc.GetItemCount().ToString(); //商品的总的数量(不是计算总类,而是计算总共有多少商品) litTotalCount.Text = sc.getItemTotalCount().ToString(); //总共的价格 litShopPriceCount.Text = sc.GetTotalPrice().ToString(); shopprice = sc.GetTotalPrice(); } else { Utility.Tool.alert("购物车为空,请先添加商品", "/default.aspx", this.Page); return; } if (Session["order"] != null) { Model.Order order = Session["order"] as Model.Order; litRevName.Text = order.recname + "(" + order.sex + ")"; litPostCode.Text = order.postcode; litRevAddress.Text = order.address; litTel.Text = order.phone; litEmail.Text = order.email; litSendType.Text = order.sendtype; litPayType.Text = order.paytype; //运费 litSendMoney.Text = GetSendMoney(order.sendtype).ToString("c2"); //商品价格 litShopPrice.Text = shopprice.ToString("c2"); //商品+运费 litAllPrice.Text =( GetSendMoney(order.sendtype) + shopprice).ToString("c2"); } else { Utility.Tool.alert("定单信息为空,请填写订单信息", "/order_modify.aspx", this.Page); return; } } } private decimal GetSendMoney(string p) { decimal money = 0; switch (p) { case "普通平邮": money = 12; break; case "顺风快递": money = 20; break; case "EMS/普通快递": money = 25; break; default: break; } return money; } //当rep循环绑定的时候,执行的事件 protected void rep_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) { string proid = (e.Item.FindControl("hfProid") as HiddenField).Value; Model.Product pt = new DAL.ProductDAO().GetModel(int.Parse(proid)); if (pt != null) { //再在 rep 里面找控件 HyperLink hlProName = e.Item.FindControl("hlProName") as HyperLink; Literal litMember = e.Item.FindControl("litMember") as Literal; Literal litVip = e.Item.FindControl("litVip") as Literal; Literal litXiaoJi = e.Item.FindControl("litXiaoJi") as Literal; hlProName.Text = pt.proname; hlProName.NavigateUrl = "/pro.aspx?id=" + pt.id; hlProName.Target = "_blank"; litMember.Text = pt.memberprice.ToString("c2"); litVip.Text = pt.vipprice.ToString("c2"); } } }
接下来,我们在订单确认页面,点击完成, 将会把订单的所有信息,分别插入到 订单详情表和订单表,因为是分别插入到2张表,所以我们用到“事务”
当我们点击完成的时候,需要生产一个订单编号
//生成订单编号 格式为 年月日+5位数 例如 20120304 00001 public string GetOrderBh() { //获取今天的最大的单号 例如查询 2012年12月3日开头的编号里面最大的 string sql = "select max(orderbh) from shop_order where orderbh like '" + DateTime.Now.ToString("yyyyMMdd") + "%'"; Database db = DatabaseFactory.CreateDatabase(); object result = db.ExecuteScalar(CommandType.Text, sql); //如果今天的最大值,不为空,我们就不要前面的年月日这8位数(20121008),只保留后面的00001 if (result != null && result != DBNull.Value) { string tem = result.ToString().Substring(8); //这里的截取, 我们截取前面的8位数 //获取到了最后的5位数字之后,我们给这5位数+1,然后再合并今天的日期 return DateTime.Now.ToString("yyyyMMdd") + (int.Parse(tem) + 1).ToString("D5");
//这里的D5是指按照十进制,填充到5位数,例如 120 填充的话就是 00120 } else { //如果当天没有订单,也就是今天没有最大的订单编号,我们手动创建一个编号 return DateTime.Now.ToString("yyyyMMdd") + "00001"; } }
最后,在这个点击完成按钮的代码是
//点击完成按钮,分别插入订单表和 订单详情表,注意,在插入到订单详情表的时候,需要一个外键,也就是 订单表的ID,所以要先插入到订单表 protected void btnDone_Click(object sender, EventArgs e) { //先判断 购物车,和订单信息 if (Session["cart"]==null) { Utility.Tool.alert("购物车为空,请先添加商品", "/default.aspx", this.Page); return; } if (Session["order"]==null) { Utility.Tool.alert("定单信息为空,请填写订单信息", "/order_confirm.aspx", this.Page); return; } //获取订单信息,由于Session["order"]里面的收件人信息都是有的,所以我们只需要额外加入Session里面没有的信息,例如用户名,订单时间等等 Model.Order order = Session["order"] as Model.Order; //商品总共的价格(这个不是订单总的价格,仅仅是商品的总价格。订单的总价是=订单运费+商品总价的,而且数据库无订单总价字段) Model.ShopCart sc = Session["cart"] as Model.ShopCart; order.detailsmoney = sc.GetTotalPrice(); order.fp = chkFp.Checked ? 1 : 0; order.remark = txtRemark.Text.Trim(); order.sendmoney = GetSendMoney(order.sendtype); order.username = User.Identity.Name; DAL.OrderDAO orderdao = new DAL.OrderDAO(); string orderbh = orderdao.GetOrderBh();//定单编号,当前日期+5位数字 order.orderbh = orderbh; //开始插入到两张表,用到事务。需要在项目上添加引用 System.Transactions ,而且还需要写 using System.Transactions; using (TransactionScope scope = new TransactionScope()) //这里有创建一个 TransactionScope 表示事务性代码,因为用到using会自动释放 { try { //如果这里报错的话,整个scope 都会自动 回滚的 int orderid = orderdao.Add(order); if (orderid > 0) { DAL.OrderdetailsDAO oddao = new DAL.OrderdetailsDAO(); foreach (Model.ShopItem item in sc.GetItemList()) { oddao.Add(new Model.Orderdetails { //这里是添加订单详情表 orderid=orderid, price=item.price, proid=item.proid, quantity=item.quantity }); } scope.Complete(); } else { Utility.Tool.alert("订单添加失败,请联系管理员", this.Page); } } catch (Exception re) { Response.Write("事务错误,具体报错信息是:"+re.Message); Response.End(); } } Session["cart"] = null; Session["order"] = null; Utility.Tool.alert("下单成功", "order_ok.aspx?bh=" + orderbh, this.Page); }
在这里,我们用到了事务提交,关于事务的具体解释,我在下一篇文章里面会详细介绍
asp.net 事务的处理,dts 的设置,asp.net三种事务处理方法,三层架构,微软企业库,动软生成器生成的代码下如何使用事务
http://www.cnblogs.com/1727050508/archive/2012/04/18/2455728.html