zoukankan      html  css  js  c++  java
  • MVC学习系列6--使用Ajax加载分部视图和Json格式的数据

    Ajax的应用在平时的工作中,很是常见,这篇文章,完全是为了,巩固复习。

    我们先看看不使用json格式返回分部视图:

    先说需求吧:

    我有两个实体,一个是出版商【Publisher】,一个是书【Book】(很显然这是一对多的关系,一个出版商可以出版很多书籍,一本书只有一个出版商。),这里,我要实现的是,在出版商页面,使用DropDownList加载出来有哪些出版商,然后选择出版商的时候,异步加载分部视图,加载这个出版商出版的书籍的数据。

    打算使用EF来做,也当是一个复习吧:

    1.首先新建一个空白的MVC web项目:,在Model文件夹下面新建两个实体:

    BOOK实体:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace AjaxDataInMVC.Models
    {
        public class Book
        {
            public int BookID { get; set; }
    
            public string Title { get; set; }
    
            public string Auther { get; set; }
    
            public string Price { get; set; }
    
            public string Year { get; set; }
    
            public int PublisherID { get; set; }
    
            public virtual Publisher Publisher { get; set; }
        }
    }
    Book

    Punlisher实体:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace AjaxDataInMVC.Models
    {
        public class Publisher
        {
            /// <summary>
            /// 出版编号
            /// </summary>
            public int PublisherID { get; set; }
    
            /// <summary>
            /// 出版商名称
            /// </summary>
            public string PublisherName { get; set; }
    
            /// <summary>
            /// 出版日期
            /// </summary>
            public string PublisherYear { get; set; }
    
            public virtual ICollection<Book> Books { get; set; }
        }
    }
    Publisher

    2.接着,添加EF引用,然后在根目录下,新建一个Map文件夹,在里面新建两个实体:

    using AjaxDataInMVC.Models;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.ModelConfiguration;
    using System.Linq;
    using System.Web;
    
    namespace AjaxDataInMVC.Map
    {
        public class BookMap:EntityTypeConfiguration<Book>
        {
            public BookMap()
            {
                //设置主键
                this.HasKey(x => x.BookID);
    
                this.Property(x => x.BookID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
                this.Property(x => x.Price).IsRequired();
                this.Property(x => x.Auther).IsRequired().HasMaxLength(50);
                this.Property(x => x.Title);
                this.Property(x => x.Year);
    
                this.HasRequired(x => x.Publisher).WithMany(x => x.Books).HasForeignKey(x => x.PublisherID).WillCascadeOnDelete(true);
                
                this.ToTable("Books");
    
    
            }
        }
    }
    BookMap
    using AjaxDataInMVC.Models;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.ModelConfiguration;
    using System.Linq;
    using System.Web;
    
    namespace AjaxDataInMVC.Map
    {
        public class PublisherMap:EntityTypeConfiguration<Publisher>
        {
            public PublisherMap()
            {
                //主键
                this.HasKey(x => x.PublisherID);
    
                this.Property(x => x.PublisherID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
                this.Property(x => x.PublisherName).HasMaxLength(50).IsRequired();
                this.Property(x => x.PublisherYear).IsRequired();
    
                this.ToTable("Publishers");
    
    
            }
        }
    }
    PublisherMap

    3.现在就是新建数据上下文类了,在Map文件夹下:

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration;
    using System.Linq;
    using System.Reflection;
    using System.Web;
    
    namespace AjaxDataInMVC.Map
    {
        public class MyDbContext:DbContext
        {
            public MyDbContext() :
                base("name=DbConnectionString") { }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
             .Where(type => !String.IsNullOrEmpty(type.Namespace))
             .Where(type => type.BaseType != null && type.BaseType.IsGenericType
                  && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
                foreach (var type in typesToRegister)
                {
                    dynamic configurationInstance = Activator.CreateInstance(type);
                    modelBuilder.Configurations.Add(configurationInstance);
                }
               // base.OnModelCreating(modelBuilder);
            }
        }
    }
    MyDbContext

    别忘了,配置文件中加上:

    <connectionStrings>
        <add name="DbConnectionString" connectionString="server=.;database=MyBookDB;uid=sa;pwd=Password_1" providerName="System.Data.SqlClient"/>
      </connectionStrings>

    5.这里特别提到,创建下拉框,我们可以新建一个ViewModel性质的实体

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace AjaxDataInMVC.ViewModel
    {
        public class PublisherViewModel
        {
            public PublisherViewModel()
            {
                PublisherList = new List<SelectListItem>();
            }
    
            [Display(Name="PublishName")]
            public int PublisherID { get; set; }
    
            public IEnumerable<SelectListItem> PublisherList { get; set; }
    
    
        }
    }

     4.创建对应的控制器:

    using AjaxDataInMVC.Map;
    using AjaxDataInMVC.Models;
    using AjaxDataInMVC.ViewModel;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace AjaxDataInMVC.Controllers
    {
        public class PublisherController : Controller
        {
            private MyDbContext context;
            public PublisherController()
            {
                context = new MyDbContext();
            //检测到循环引用可以加上这句 context.Configuration.ProxyCreationEnabled
    = false; } // GET: Publisher public ActionResult Index() { List<Publisher> lstPublisher = context.Set<Publisher>().ToList(); PublisherViewModel model = new PublisherViewModel(); model.PublisherList = lstPublisher.Select(x => new SelectListItem() { Text = x.PublisherName, Value = x.PublisherID.ToString() }); return View(model); } } }
    using AjaxDataInMVC.Map;
    using AjaxDataInMVC.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace AjaxDataInMVC.Controllers
    {
        public class BookController : Controller
        {
            private MyDbContext context;
            public BookController()
            {
                context = new MyDbContext();
                context.Configuration.ProxyCreationEnabled = false;
            }
            // GET: Book
            public ActionResult Index()
            {
                return View();
            }
            
            //直接返回布局页的方式:HTML
            public PartialViewResult GetBookDetailsByID(int id)
            {
    
                List<Book> lstBook = context.Set<Book>().Where(x => x.PublisherID.Equals(id)).ToList();
                return PartialView(lstBook);
            }
    
            //Json方式
            //public JsonResult GetBookDetailsByID(int id)
            //{
            //    List<Book> lstBook = context.Set<Book>().Where(x => x.PublisherID.Equals(id)).ToList();
            //    return Json(lstBook,JsonRequestBehavior.AllowGet);
            //}
        }
    }

    Publisher控制器的Index视图:

    @model AjaxDataInMVC.ViewModel.PublisherViewModel
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <script src="~/Scripts/jquery-1.10.2.js"></script>
        <title>Index</title>
    </head>
    <body>
        @*思路是:在当前页面,点击下拉框,加载分部视图*@
        <div> 
            @Html.LabelFor(s=>s.PublisherID)
            @Html.DropDownListFor(s=>s.PublisherID,Model.PublisherList)
        </div>
        <div id="myDIV">
    
        </div>
        <script type="text/javascript">
            $(document).ready(function () {
                $("#PublisherID").change(function () {
                    var id=$("#PublisherID").val();
                    $.ajax({
                        url: "/Book/GetBookDetailsByID/" + id,
                        type: "get",
                        dataType: "html",
                        success: function (result) {
    
                            //html文本方式
                            $("#myDIV").html("");
                            $("#myDIV").html(result);
    
                            //二。Json方式
                            //$("#myDIV").html("");
                            //var myHTML = "<ul>";
                            //$.each(result, function (key, item) {
                            //    myHTML += "<li>编号:" + item.BookID + "</li>";
                            //    myHTML += "<li>标题:" + item.Title + "</li>";
                            //    myHTML += "<li>作者:" + item.Auther + "</li>";
                            //    myHTML += "<li>价格:" + item.Price + "</li>";
                            //    myHTML += "<li>时间:" + item.Year + "</li>";
                              
                            //})
                            //myHTML +="</ul>"
                            //$("#myDIV").html(myHTML);
                        },
                        error:function(result){
                            alert(result.responseText);
                        }
    
                    });
                });
    
            });
        </script>
    </body>
    </html>

    Book控制器的分部视图GetBookDetailsByID:

    @model IEnumerable<AjaxDataInMVC.Models.Book>
    <table style="border:1px solid thin">
        <thead>
            <tr>
                <th>BookID</th>
                <th>Title</th>
                <th>Auther</th>
                <th>Price</th>
                <th>Year</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>@item.BookID</td>
                    <td>@item.Title</td>
                    <td>@item.Auther</td>
                    <td>@item.Price</td>
                    <td>@item.Year</td>
                </tr>
            }
        </tbody>
    </table>

    在数据库中写上测试数据,然后先运行一下:

    选择:新华大学出版社,的时候,随即加载出了对应的数据。

    选择:长江日报出版社的时候,加载:

    现在看看:使用Json方式加载吧:

    修改一下Book控制器,和其相关的Publisher控制器的Index视图就可以:

    using AjaxDataInMVC.Map;
    using AjaxDataInMVC.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace AjaxDataInMVC.Controllers
    {
        public class BookController : Controller
        {
            private MyDbContext context;
            public BookController()
            {
                context = new MyDbContext();
                context.Configuration.ProxyCreationEnabled = false;
            }
            // GET: Book
            public ActionResult Index()
            {
                return View();
            }
            
            ////直接返回布局页的方式:HTML
            //public PartialViewResult GetBookDetailsByID(int id)
            //{
    
            //    List<Book> lstBook = context.Set<Book>().Where(x => x.PublisherID.Equals(id)).ToList();
            //    return PartialView(lstBook);
            //}
    
            //Json方式
            public JsonResult GetBookDetailsByID(int id)
            {
                List<Book> lstBook = context.Set<Book>().Where(x => x.PublisherID.Equals(id)).ToList();
                return Json(lstBook,JsonRequestBehavior.AllowGet);
            }
        }
    }
    @model AjaxDataInMVC.ViewModel.PublisherViewModel
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <script src="~/Scripts/jquery-1.10.2.js"></script>
        <title>Index</title>
    </head>
    <body>
        @*思路是:在当前页面,点击下拉框,加载分部视图*@
        <div> 
            @Html.LabelFor(s=>s.PublisherID)
            @Html.DropDownListFor(s=>s.PublisherID,Model.PublisherList)
        </div>
        <div id="myDIV">
    
        </div>
        <script type="text/javascript">
            $(document).ready(function () {
                $("#PublisherID").change(function () {
                    var id=$("#PublisherID").val();
                    $.ajax({
                        url: "/Book/GetBookDetailsByID/" + id,
                        type: "get",
                        dataType: "json",
                        success: function (result) {
    
                            //1.html文本方式
                            //$("#myDIV").html("");
                            //$("#myDIV").html(result);
    
                            //二。Json方式
                            $("#myDIV").html("");
                            var myHTML = "<ul>";
                            $.each(result, function (key, item) {
                                myHTML += "<li>编号:" + item.BookID + "</li>";
                                myHTML += "<li>标题:" + item.Title + "</li>";
                                myHTML += "<li>作者:" + item.Auther + "</li>";
                                myHTML += "<li>价格:" + item.Price + "</li>";
                                myHTML += "<li>时间:" + item.Year + "</li>";
                              
                            })
                            myHTML +="</ul>"
                            $("#myDIV").html(myHTML);
                        },
                        error:function(result){
                            alert(result.responseText);
                        }
    
                    });
                });
    
            });
        </script>
    </body>
    </html>

    接着运行:

    总结:这篇文章,完全为了复习巩固,另外在序列化Book实体,json 数据的时候,你可能会遇到这个错误:检测到循环依赖,因为我没有给Book实体新建一个ViewModel,这里可以这样解决:

     context.Configuration.ProxyCreationEnabled = false;
    禁用代理。
    另外,使用Json格式返回数据,很快,比直接用HTML文本加载视图快很多。
    Content Type Header Body Total (Byte)
    text/html 434 375 809
    application/ json 398 197 595
     
    
    
    circle graph
     
  • 相关阅读:
    10个用Console来Debug的高级技巧
    JS Object对象
    图解你身边的 SOLID 原则
    JavaScript判断数据类型
    三伏天里小试牛刀andriod 开发 #华为云·寻找黑马程序员#
    学习索引结构的一些案例——Jeff Dean在SystemML会议上发布的论文(下)
    开发者的福利,报名即可领取代金券,赢运动手环
    用Python调用华为云API接口发短信
    学习索引结构的一些案例——Jeff Dean在SystemML会议上发布的论文(中)
    学习索引结构的一些案例——Jeff Dean在SystemML会议上发布的论文(上)
  • 原文地址:https://www.cnblogs.com/caofangsheng/p/5675831.html
Copyright © 2011-2022 走看看