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
 
原文地址:https://www.cnblogs.com/caofangsheng/p/5675831.html