你的位置:首页 > ASP.net教程

[ASP.net教程]MVC学习系列6


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 TypeHeaderBodyTotal (Byte)
text/html434375809
application/ json398197595
 
circle graph