文章出處

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
 

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()