• 第5章ASP.NET MVC (模型绑定)


    模型绑定

    一、      理解模型绑定

    1、         模型绑定:把值(来源路由或视图)附加给action方法的参数上面

    2、         参数的过程,参数的类型包含值类型和引用类型(模型、对象)

    3、         原理:调用action方法时,会查看该方法是否有参数,如果有会去查找对应的方法参数名称相同的绑定器,如果没有自定义该绑定器,会调用默认的绑定器

    二、      手工使用模型绑定

    1、         绑定简单类型

    1)、参数:全部使用string或者类型?id如int?id

    三、      处理绑定错误

    四、      使用模型绑定接受文件上传

    五、      自定义模型绑定系统

    六、      综合案例

    七、      重点:在MVC中实现购物车

    八、      难点:自定义模型绑定系统

    结合第四章内容,实现购物车功能

    一、在“LinqBLL/ProductBll.cs”编辑查询方法

    如图所示

    代码示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using LinqService;  //引用
    namespace LinqBLL
    {
        public class ProductBll
        {
            public List<Product> GetProduct()
            {
                using (SportsStoreEntities se = new SportsStoreEntities())
                {
                    var products = se.Product;  //数据库里面表名称
                    return products.ToList();
                }
            }
            //通过分类名获取体育产品列表
            public List<Product> GetProductByCateName(string cate,int stIndex,int count)
            {
                using(SportsStoreEntities se=new SportsStoreEntities())
                {
                    if (string.IsNullOrEmpty(cate))  //查找所有
                    { 
                        var products=se.Product.OrderBy(x=>x.ProductID).Skip(stIndex).Take(count);
                        return products.ToList();
                    }
                      else  //查找对应分类数据
                    {
                        var books = from a in se.Product                           
                                    where a.Category.Contains(cate)
                                    select a;
                        return books.OrderBy(x=>x.ProductID).Skip(stIndex).Take(count).ToList();
                    }
                }
            }
            //获取所有记录数
            public int GetRecordCount(string cate)
            {
                using (SportsStoreEntities se = new SportsStoreEntities())
                {
                    if (string.IsNullOrEmpty(cate))  //查找所有
                    {                
                        return se.Product.Count();
                    }
                    else  //查找对应分类数据
                    {
                        var books = from a in se.Product
                                    where a.Category.Contains(cate)
                                    select a;
                        return books.Count();
                    }
                }
            }
            //获取分类名称集
            public IEnumerable<string> GetCategories()
            {
                var se = new SportsStoreEntities();
                var s = from a in se.Product
                        select new { a.Category };
                //Distinct:去掉重复分类名,OrderBy:升序
                return s.Select(x => x.Category).Distinct().OrderBy(x => x);
            }
    
            //删除方法
            public bool Delete(int id)
            {
                bool b = true;
                using (var st = new SportsStoreEntities())
                {
                    try
                    {
                        var product = st.Product.SingleOrDefault(a => a.ProductID == id);
                        st.Product.Remove(product);
                        st.SaveChanges();
                    }
                    catch
                    {
                        b = false;
                    }
                    return b;
                }
    
            }
            //信息详细
            public Product GetModel(int id)
            {
                using (SportsStoreEntities st = new SportsStoreEntities())
                {
                    Product model = st.Product.SingleOrDefault(a => a.ProductID == id);
                        return model;
                }
            }
            //信息查询
            public Product GetProductById(int id)
            {
                using (var st = new SportsStoreEntities())
                {
                    Product pro = st.Product.SingleOrDefault(a => a.ProductID == id);
                    return pro;
                }
            }
        }
    }
    View Code

    二、在“Models”文件添加一个类名为“Cart.cs”,编辑“添加购物车、删除购物车中的产品、清楚购物车的产品、计算购物车中求和、获取购物车所有的产品”方法

    如图所示(上部分):

    如图所示(下部分):

    代码示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    using LinqService;
    using LinqBLL;
    namespace MvcProduct.Models
    {
        public class Cart
        {
              //定义列表存储购物车数据
            private Dictionary<string, CartLine> dic = new Dictionary<string,CartLine>();
            //添加购物车
            public void AddCart(string itemId, int quantity)
            {
                CartLine cart=null;
                if (dic.TryGetValue(itemId, out cart))
                {
                    cart.Quantity += quantity;
                }
                else
                {
                    Product pro= new ProductBll().GetProductById(Convert.ToInt32(itemId));
                    cart = new CartLine { Products = pro, Quantity = 1 };
                    dic.Add(itemId, cart);
                }
            }
            //删除购物车中的产品
            public void Remove(string itemId)
            {
                dic.Remove(itemId);
            }
            //清楚购物车的产品
            public void Clear()
            {
                dic.Clear();
            }
            //计算购物车中求和
            public decimal Total
            {
                get 
                {
                    return dic.Values.Sum(e => e.Products.Price * e.Quantity);
                }
            }
            //获取购物车所有的产品
            public IEnumerable<CartLine> CartItem
            {
                get { return dic.Values; }
            }
        
        }
        //包含产品的数量
        public class CartLine
        {
            public Product Products { get; set; }
            public int Quantity { get; set; }  //数量
        }
    }
    View Code

     三、继续在“Models”文件添加一个类名为"CartModelBinder.cs"编辑存储方法”

    如图所示:

    代码示例

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    using System.Web.Mvc;
    namespace MvcProduct.Models
    {
        public class CartModelBinder:IModelBinder
        {
            private const string sessionKey = "Cart";
    
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                Cart cart = (Cart)controllerContext.HttpContext.Session[sessionKey];
                if (cart == null)
                {
                    cart = new Cart();
                    controllerContext.HttpContext.Session[sessionKey] = cart;
                }
                return cart;
            }
        }
    }
    View Code

    四、完成后,到"Global.asax"路由器里面"Application_Start()"方法"注册购物车"(注意引用命名空间)

    1、如图所示(引用命名空间):

    2、如图所示(注册):

     

    代码示例

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    using MvcProduct.Models;
    namespace MvcProduct
    {
        // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
        // 请访问 http://go.microsoft.com/?LinkId=9394801
    
        public class MvcApplication : System.Web.HttpApplication
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
            }
    
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
                routes.MapRoute(
                 "cate", // 路由名称
                 "{controller}/{action}/{cate}", // 带有参数的 URL
                 new { controller = "Home", action = "Index", cate = UrlParameter.Optional }, // 参数默认值
                 new[] { "MvcProduct.Controllers" }
             );
    
                routes.MapRoute(
                    "Default", // 路由名称
                    "{controller}/{action}/{id}", // 带有参数的 URL
                    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // 参数默认值
                    new[] { "MvcProduct.Controllers" }
                );
    
            }
    
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                // 默认情况下对 Entity Framework 使用 LocalDB
                Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)v11.0; Integrated Security=True; MultipleActiveResultSets=True");
    
                RegisterGlobalFilters(GlobalFilters.Filters);
                RegisterRoutes(RouteTable.Routes);
    
                //注册购物车模型绑定类
                ModelBinders.Binders.Add(typeof(Cart), new CartModelBinder());
            }
        }
    }
    View Code

    五、在”Controllers“文件添加一个控件名为”CartController.cs“并调用添加方法

    如图所示:

     代码示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    using MvcProduct.Models;
    namespace MvcProduct.Controllers
    {
        public class CartController : Controller
        {
            //
            // GET: /Cart/
    
            public ActionResult Index()
            {
                return View();
            }
            //添加到购物车
            [HttpPost]
            public ActionResult AddToCart(Cart cart, string Id, string returnUrl)
            {
                cart.AddCart(Id, 1);
                return RedirectToAction("Index", new { returnUrl });
            }
        }
    }
    View Code

    六、编辑完成后,在”Index“添加视图,选择强类型并编辑前台代码

    1、如图所示

    2、如图所示(前台代码):

    代码示例:

    @model IEnumerable<MvcProduct.Models.CartLine>
    
    @{
        ViewBag.Title = "Index";
    }
    
    <h2>我的购物车</h2>
    <table>
         <tr>
            <td>图片</td>
            <th>体育名称</th>
            <th>价格</th>
            <th>数量</th>
            <th>小计</th>
            <th>删除</th>
        </tr>
    
    @foreach (var item in Model) 
    {
         <tr>
            <td><img src="@item.Products.Image" alt="" /></td>
            <td>@item.Products.Name</td>
            <td>@item.Products.Price.ToString("F2")</td>
            <td>@item.Quantity</td>
            <td>@((item.Products.Price*item.Quantity).ToString("F2"))</td>
            <td>
               @Html.ActionLink("删除", "Delete", new { id=item.Products.ProductID  })
            </td>
        </tr>
    }
          <tfoot>
            <tr>
                <td colspan="3" align="right">总计:</td>
                <td>@ViewBag.Total</td>
            </tr>
        </tfoot>
    </table>
    <p style="text-align:center" class="actionButtons">
        <a href="/Home/List">继续购物</a> 
        @Html.ActionLink("马上结账", "Checkout")
    </p>
    View Code

    七、完成后,回到“Controllers/CartControllers”编辑删除方法和把编辑对象方法

    1、如图所示(对象):

     2、如图所示(删除方法):

    代码示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    using MvcProduct.Models;
    namespace MvcProduct.Controllers
    {
        public class CartController : Controller
        {
            //
            // GET: /Cart/
    
            public ActionResult Index(Cart cart)
            {
                //总数格式
                ViewBag.Total = cart.Total.ToString("F2");
                return View(cart.CartItem);        
            }
            //添加到购物车
            [HttpPost]
            public ActionResult AddToCart(Cart cart, string Id, string returnUrl)
            {
                cart.AddCart(Id, 1);
                return RedirectToAction("Index", new { returnUrl });
            }
            //删除购物车
            public ActionResult Delete(Cart cart, string id)
            {
                cart.Remove(id);
                return RedirectToAction("Index");
            }
        }
    }
    View Code

    八、到”Views/Home/List.cshtml“修改”购物车“代码

    如图所示:

    代码示例:

    @model MvcProduct.Models.ProducrsListViewModel
    
    @{
        ViewBag.Title = "List";
    }
    
    <h2>体育产品</h2>
    
    
        @foreach (var p in Model.Producrs)
        {
           <div class="warp clearfix">
             <div id="left">
               <img alt="@p.Name" src="../../@p.Image" width="135" height="155" border="0" />
              </div> 
                 <div class="item">
                  <h3>@p.nDescription</h3><br />                   
                      @p.Category                     
                  <h4>@string.Format("{0:F}",p.Price)</h4><br />  
                      
                     @using (Html.BeginForm("AddToCart","Cart"))
                     {        
                         @Html.Hidden("Id",p.ProductID)  
                          @Html.Hidden("returnUrl",Request.Url.PathAndQuery)      
                        <input type="submit" value="加入购物车" />
                     }
                    </div>
                     </div>
                   <hr  style="border-style:inset"/>        
        }
    <div class="pager">
        @Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page=x,cate=Model.CurrentCategory }))
    </div>
    View Code

     注意:到“Global.asax”注释掉”路由器之前里面RegisterRoutes“方法代码,否则会报错

    如图所示:

    代码示例:

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    using MvcProduct.Models;
    namespace MvcProduct
    {
        // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
        // 请访问 http://go.microsoft.com/?LinkId=9394801
    
        public class MvcApplication : System.Web.HttpApplication
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
            }
    
            public static void RegisterRoutes(RouteCollection routes)
            {
             //   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
             //   routes.MapRoute(
             //    "cate", // 路由名称
             //    "{controller}/{action}/{cate}", // 带有参数的 URL
             //    new { controller = "Home", action = "Index", cate = UrlParameter.Optional }, // 参数默认值
             //    new[] { "MvcProduct.Controllers" }
             //);
    
                routes.MapRoute(
                    "Default", // 路由名称
                    "{controller}/{action}/{id}", // 带有参数的 URL
                    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // 参数默认值
                    new[] { "MvcProduct.Controllers" }
                );
    
            }
    
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                // 默认情况下对 Entity Framework 使用 LocalDB
                Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)v11.0; Integrated Security=True; MultipleActiveResultSets=True");
    
                RegisterGlobalFilters(GlobalFilters.Filters);
                RegisterRoutes(RouteTable.Routes);
    
                //注册购物车模型绑定类
                ModelBinders.Binders.Add(typeof(Cart), new CartModelBinder());
            }
        }
    }
    View Code

    运行效果:

  • 相关阅读:
    CSS效果:CSS实用技巧制作三角形以及箭头效果
    JS之this应用详解
    JS之iscroll.js的使用详解
    一个测试人员眼中的创业团队七宗罪
    一个WEB应用的开发流程
    一个年薪一百万的程序员:技术进阶之路
    一个十年IT从业者的职场感言:为什么不要自称是“程序员”
    一位程序员工作10年总结的13个忠告,却让很多人惋惜
    当个好的测试经理不容易,懂得这些很重要
    测试经理岗位职责及应具备的能力
  • 原文地址:https://www.cnblogs.com/xuyangyang/p/6392793.html
Copyright © 2020-2023  润新知