第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

运行效果:

原文地址:https://www.cnblogs.com/xuyangyang/p/6392793.html