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; } } }
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; } } }
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"); } } }

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"); } } }
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); } } }
別忘了,配置文件中加上:
<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 |

文章列表