2014年10月20日 星期一

練習題 - ASP.NET MVC 資料列表顯示 + 分頁 + 查詢 + FormMethod.Post

這是一個蠻常見的功能,使用 ASP.NET MVC 開發,將某一個資料以列表方式顯示,並且加上分頁功能,另外還要有查詢功能,而希望顯示分頁的時候可以保留查詢的條件(也就是查詢結果也要能夠分頁顯示),因為有可能查詢的欄位會有相當多個,所以不希望是以 Get 的方式讓查詢條件以 QueryString 的方式傳遞到後端,而是使用 Post 的方式來做傳遞(因為這不是用在一般的前台頁面,而是常見於後台的操作頁面)。

其實這樣的功能也不是相當複雜,我在之前的資料分頁文章也曾經做過說明,例如以下這一篇:

ASP.NET MVC 資料分頁 MVCPaging 2.0 應用 Part.1:一般、表單(Form)

不過這一次會有不一樣的方式來實作,分頁套件會使用「PagedList.Mvc」,因為查詢條件可能會有相當多個的情況,所以會建立一個 ViewModel 來使用,藉由這樣的一個範例說明可以讓初學者能夠瞭解類似這樣的需求應該要如何處理。

 


開發環境:Visual Studio 2013 Update 3, LocalDB, ASP.NET MVC 5

 

首先在 VS2013 裡建立了一個 ASP.NET MVC 5 網站專案,加入使用 Entity Framework 6.1.1 以及 PagedList.Mvc,

image

建立 LocalDB,使用的範例資料庫是 Northwind,

image

使用 Entity Fremework 建立 Model,使用的建立方式為「來自資料庫的 Code First」,

SNAGHTMLb58b70e

image

 

接著 ViewModels 目錄,在目錄中建立了兩個等一下會使用到的 ViewModel 類別,一個是用來作為查詢欄位使用的 Model,另一個則是頁面顯示所使用的 Model,頁面顯示的 ViewModel 會包含分頁資料、查詢、分頁 Index 的資料,

ProductSearchModel.cs

image

ProductListViewModel.cs

image

 

接著建立 ProductController.cs

image

上面所看到的的程式內容,可以與一般大家所做的資料分頁方是有所不同,不過做法大同小異,例如要做為頁面裡的下拉選單資料,以往很多人都會直接使用 ViewBag,不過我不是很喜歡使用太多的 ViewBag,因為既然要將資料從 Controller 傳遞給後端,就應該直接使用 Model,而這邊有很多初學者會有個疑問,在 ASP.NET MVC 裡,一個頁面只能使用一個 Model 類別,而這個 Model 類別大多是直接使用 Entity Framework 所建立的其中一個 Model 類別,所以很多人就會卡在這邊,都會認為只能使用一個 Model 類別,所以其他的資料都用 ViewBag 傳遞給 View。

其實 Model 類別只是一個 class,功能就是裝載資料,從 Controller 到 View 或是 View 到 Controller,既然一個頁面只能使用一個 Model 類別,所以我們可以另外建立 ViewModel 類別,在這個 ViewModel 裡的成員就可以包含其他的類別,那麼我們就可以不受一個頁面只能使用一個 Model 類別的限制,有關 ViewModel 的說明與使用,請看我所寫的 ViewModel 幾篇文章,

ASP.NET MVC 的 ViewModel - 基礎篇

ASP.NET MVC - 為什麼不建議在 ViewModel 裡加入行為

ASP.NET MVC - ViewModel 參考文章與其他說明

 

接著再來建立頁面 Post 回到後端的處理,因為頁面有查詢功能,所以要依據 Model 裡的 SearchParameter 內的各種查詢條件是否有值然後增加查詢的判斷,

[HttpPost]
public ActionResult Index(ProductListViewModel model)
{
    var query = _db.Products.AsQueryable();
 
    if (!string.IsNullOrWhiteSpace(model.SearchParameter.ProductName))
    {
        query = query.Where(
            x => x.ProductName.Contains(model.SearchParameter.ProductName));
    }
    if (!string.IsNullOrWhiteSpace(model.SearchParameter.QuantityPerUnit))
    {
        query = query.Where(
            x => x.QuantityPerUnit.Contains(model.SearchParameter.QuantityPerUnit));
    }
 
    int supplierId;
    if (!string.IsNullOrWhiteSpace(model.SearchParameter.Supplier)
        &&
        int.TryParse(model.SearchParameter.Supplier, out supplierId))
    {
        query = query.Where(x => x.SupplierID == supplierId);
    }
 
    int categoryId;
    if (!string.IsNullOrWhiteSpace(model.SearchParameter.Category)
        &&
        int.TryParse(model.SearchParameter.Category, out categoryId))
    {
        query = query.Where(x => x.CategoryID == categoryId);
    }
 
    query = query.OrderBy(x => x.ProductID);
 
    int pageIndex = model.PageIndex < 1 ? 1 : model.PageIndex;
 
    var result = new ProductListViewModel
    {
        SearchParameter = model.SearchParameter,
        PageIndex = model.PageIndex < 1 ? 1 : model.PageIndex,
        CategoryItems = new SelectList(
            items: this.Categories,dataValueField: "CategoryID",
            dataTextField: "CategoryName",
            selectedValue: model.SearchParameter.Category),
        Suppliers = new SelectList(
            items: this.Suppliers,
            dataValueField: "SupplierID",
            dataTextField: "CompanyName",
            selectedValue: model.SearchParameter.Supplier),
        Products = query.ToPagedList(pageIndex, PageSize)
    };
 
    return View(result);
 
}

 

前端頁面,頁面所使用的 Model 是 ProductListViewModel 類別,

image

再來就是查詢介面的 Form,要特別注意紅線標示的地方,

image

而資料的列表顯示以及分頁的 Pager 就比較沒有什麼特殊的地方,所以就直接跳過,直接看如何處理 Post,

image

上面的程式在以前的文章也出現過,所以就直接拿過來使用,稍微修改一些地方,因為 Pager 的分頁都是直接使用 HyperLink,將分頁的 Index 使用 QueryString 的方式傳遞給後端以取得分頁資料,但是我們這邊是在瀏覽每個分頁的時候也必須保留查詢條件,查詢的地方所使用的是 FormMethod.Post,但是分頁連結則是 Get,其實可以設定 PagedList.Mvc 的 Pager 可以附加指定表單欄位的資料,但這只適用於表單欄位只有幾個的情況,一旦查詢的條件欄位有相當多個的時候,就不適合使用 Get 的方式將查詢條件值附加在 QueryString 傳遞給後端。

所以在前端就使用 jQuery 去改變 Pager 連結的行為,讓使用者按下分頁連結的時候是使用 Post 的方是將查詢條件值以及分頁 Index 傳遞給後端。

 

執行

image

加入查詢條件,

image

點選分頁,可以觀察到 Post 給後端的資料是有哪些,

image

image

 

完整的 ProductController.cs 內容

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BlogDemo.ViewModels;
using BlogDemo.Models;
using PagedList;
 
namespace BlogDemo.Controllers
{
    public class ProductController : Controller
    {
        private readonly NorthwindDbContext _db = new NorthwindDbContext();
 
        private const int PageSize = 10;
 
        private IEnumerable<Category> Categories
        {
            get { return _db.Categories.OrderBy(x => x.CategoryID); }
        }
 
        private IEnumerable<Supplier> Suppliers
        {
            get { return _db.Suppliers.OrderBy(x => x.CompanyName); }
        }
 
        public ActionResult Index(int page = 1)
        {
            var query = _db.Products.OrderBy(x => x.ProductID);
 
            int pageIndex = page < 1 ? 1 : page;
 
            var model = new ProductListViewModel
            {
                SearchParameter = new ProductSearchModel(),
                PageIndex = pageIndex,
                CategoryItems = new SelectList(this.Categories, "CategoryID", "CategoryName"),
                Suppliers = new SelectList(this.Suppliers, "SupplierID", "CompanyName"),
                Products = query.ToPagedList(pageIndex, PageSize)
            };
 
            return View(model);
        }
 
        [HttpPost]
        public ActionResult Index(ProductListViewModel model)
        {
            var query = _db.Products.AsQueryable();
 
            if (!string.IsNullOrWhiteSpace(model.SearchParameter.ProductName))
            {
                query = query.Where(
                    x => x.ProductName.Contains(model.SearchParameter.ProductName));
            }
            if (!string.IsNullOrWhiteSpace(model.SearchParameter.QuantityPerUnit))
            {
                query = query.Where(
                    x => x.QuantityPerUnit.Contains(model.SearchParameter.QuantityPerUnit));
            }
 
            int supplierId;
            if (!string.IsNullOrWhiteSpace(model.SearchParameter.Supplier)
                &&
                int.TryParse(model.SearchParameter.Supplier, out supplierId))
            {
                query = query.Where(x => x.SupplierID == supplierId);
            }
 
            int categoryId;
            if (!string.IsNullOrWhiteSpace(model.SearchParameter.Category)
                &&
                int.TryParse(model.SearchParameter.Category, out categoryId))
            {
                query = query.Where(x => x.CategoryID == categoryId);
            }
 
            query = query.OrderBy(x => x.ProductID);
 
            int pageIndex = model.PageIndex < 1 ? 1 : model.PageIndex;
 
            var result = new ProductListViewModel
            {
                SearchParameter = model.SearchParameter,
                PageIndex = model.PageIndex < 1 ? 1 : model.PageIndex,
                CategoryItems = new SelectList(
                    items: this.Categories,dataValueField: "CategoryID",
                    dataTextField: "CategoryName",
                    selectedValue: model.SearchParameter.Category),
                Suppliers = new SelectList(
                    items: this.Suppliers,
                    dataValueField: "SupplierID",
                    dataTextField: "CompanyName",
                    selectedValue: model.SearchParameter.Supplier),
                Products = query.ToPagedList(pageIndex, PageSize)
            };
 
            return View(result);
 
        }
 
    }
}

完整的 ~/Views/Product/Index.cshtml 內容

@using PagedList.Mvc
@model BlogDemo.ViewModels.ProductListViewModel
 
@{
    ViewBag.Title = "Product - List";
}
 
<h2>Product - List</h2>
<hr />
<div class="well">
    @using (Html.BeginForm("Index", "Product", FormMethod.Post, new { @class = "form-horizontal", role = "form", id = "ProductList" }))
    {
        <div class="row">
            <div class="col-md-6 form-group">
                <label class="col-lg-3 control-label">Product Name:</label>
                <div class="col-lg-8">
                    @Html.EditorFor(x => x.SearchParameter.ProductName, new { htmlAttributes = new { @class = "form-control" } })
                </div>
            </div>
            <div class="col-md-6 form-group">
                <label class="col-lg-3 control-label">Quantity Per Unit:</label>
                <div class="col-lg-8">
                    @Html.EditorFor(x => x.SearchParameter.QuantityPerUnit, new { htmlAttributes = new { @class = "form-control" } })
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-6 form-group">
                <label class="col-lg-3 control-label">Supplier:</label>
                <div class="col-lg-8">
                    @Html.DropDownListFor(x => x.SearchParameter.Supplier, (SelectList)Model.Suppliers, "-- select item --", new { @class = "form-control" })
                </div>
            </div>
            <div class="col-md-6 form-group">
                <label class="col-lg-3 control-label">Category:</label>
                <div class="col-lg-8">
                    @Html.DropDownListFor(x => x.SearchParameter.Category, (SelectList)Model.CategoryItems, "-- select item --", new { @class = "form-control" })
                </div>
            </div>
        </div>
        <span class="clearfix"></span>
        <div class="row">
            <div class="col-md-offset-5">
                <input type="submit" class="btn btn-primary" value="Search">
                <span></span>
                <input type="reset" class="btn btn-default" value="Cancel">
            </div>
        </div>
    }
</div>
 
@Html.PagedListPager(Model.Products, page => Url.Action("Index", new { page }))
<table class="table">
    <tr>
        <th>
            Category Name
        </th>
        <th>
            Supplier Name
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Products.FirstOrDefault().ProductName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Products.FirstOrDefault().QuantityPerUnit)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Products.FirstOrDefault().UnitPrice)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Products.FirstOrDefault().UnitsInStock)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Products.FirstOrDefault().UnitsOnOrder)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Products.FirstOrDefault().ReorderLevel)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Products.FirstOrDefault().Discontinued)
        </th>
    </tr>
 
    @foreach (var item in Model.Products)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Category.CategoryName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Supplier.CompanyName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ProductName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.QuantityPerUnit)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.UnitPrice)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.UnitsInStock)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.UnitsOnOrder)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReorderLevel)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Discontinued)
            </td>
        </tr>
    }
 
</table>
 
@section scripts
{
    <script type="text/javascript">
     $(function () {
         $('.pagination>li>a[href]').each(function (i, item) {
             var page = $(item).attr('href').replace('/Product?page=', '');
             $(item).attr('href', '#').click(function () { postPage(page); });
 
         });
     });
 
     function postPage(page) {
         var targetFormId = '#ProductList';
         if ($(targetFormId).size() > 0) {
             $('<input>')
                 .attr({ type: 'hidden', id: 'PageIndex', name: 'PageIndex', value: page })
                 .appendTo($(targetFormId));
             $(targetFormId).submit();
         }
     };
    </script>
 
}

 


這篇的內容只是再把以前的文章內容做點小修改,最主要的就是善用 ViewModel 的概念以及前端 jQuery 應用,有時候這些稍加變化的需求對於初學者會造成蠻多的疑惑,以致於會有一些「意外」的做法出現,並不是說不好,雖然這些意外的做法都可以將需求給完成,但是第一次使用意外做法所完成的,如果沒有再做檢討與改進的話,那麼往後開發的過程再遇到相同的需求就還是會繼續沿用,不好的做法就會永世流傳。

我在這一篇的做法就是比較適合的做法嗎?

其實不然,我相信還有更好的做法,這篇就當作開端,讓初學者能夠去思考如何做出更好與更適當的做法出來。

 

以上

35 則留言:

  1. Hi Kevin 大
    我有一個問題
    因為你不喜歡用 ViewBag (ViewData),所以會建立 ViewModel 去存頁面上所有需要用到的東西
    那如果所有的頁面都是有下拉式選單的話,是不是 ViewModel 就會很多
    這樣子的話會不會有什麼其它的影響,還是沒有差別??

    回覆刪除
    回覆
    1. Hello, 你好
      其實我沒有不喜歡用 ViewBag or ViewData,只是在於一個頁面如果有需要很多資料是必須從後端帶到前端的,
      過多的 ViewBag 反而不是一件好的做法,所以我會建立 ViewModel 來使用,
      因為可以讓 View 裡面對於資料的取得方式會比較簡潔,因為可以直接使用 Intellisense 將資料的拿出來使用,
      而且就是該資料原本的型別,這在於一些 Html Helper 的使用會比較方便,
      如果使用很多的 ViewBag,
      其一,在編輯 View 的時候, ViewBag 沒有 Intellisense 的支援
      其二,因為太多的 ViewBag,光是名稱就讓我很頭大,因為會記不得,
      其三,在 Html Helper 裡如果要使用 ViewBag 裡的資料時,還需要多做一次轉型
      .
      至於你說的「如果所有的頁面都是有下拉式選單的話,是不是 ViewModel 就會很多」,我不清楚這個 ViewModel 會很多是表示什麼?
      因為一個 View 只能使用一個 ViewModel,而 ViewModel 只能服務一個 View,強烈不建議與別的 View 共用,而且嚴謹的開發上,其實應該不要在 View 就直接使用原生的 Model 或 Domain Model,所以很多的 ViewModel 是理所當然的,其實沒有什麼影響,反倒是一堆的 ViewBag 才是個問題,看過很多開發者的 View,因為沒有 ViewModel 的概念,所以每一個 View 就會使用一大堆的 ViewBag,這真的不是一件好事,就像我提出的三個原因,所以盡量使用強型別的做法,這是我的建議原則。

      刪除
    2. 補充一下,其實有時候一些簡單的頁面,實在也沒必要去建立 ViewModel,所以這時候要從後端帶資料給 View 的時候,ViewBag 還是一個不錯的選擇。

      刪除
    3. 感謝Kevin大的回答
      我會這樣子問是因為之前有一個案子幾乎所有的頁面都有建 ViewModel
      剛好看到你寫的這一篇,問一下你的看法
      然後
      你上面有提到 "嚴謹的開發上,其實應該不要在 View 就直接使用原生的 Model 或 Domain Model"
      這個意思是 最好不要用 EF 建立好的 Model 在 View 使用嗎 ??
      你覺得這樣子有什麼問題嗎 ??

      刪除
    4. 我想這問題的答案就必須要你自己去思考與體會,我無法用三言兩語來告訴你,因為如果用短短幾句話就可以解釋,那麼我就是在敷衍你,因為這樣的做法是必須有親身體驗過之後才能夠瞭解,試著去設計一個大型的網站,並且將這個網站設定為可以支援抽換不同的資料庫與中間層,朝著這個方向去思考。

      刪除
    5. 了解,謝謝Kevin大的回答

      刪除
  2. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 你原本在做分頁時給 View 的 Model 型別是否為 IPagedList 呢?
      因為同樣的,我無法在沒有前因後果的狀況下去判斷你的問題,
      所以還是建議你到這一篇「ASP.NET MVC 資料分頁操作 - 使用 PagedList.Mvc @ GitHub」
      http://kevintsengtw.blogspot.tw/2014/10/aspnet-mvc-pagedlistmvc-github.html
      將文章裡所提到的使用 PagedList.Mvc 做資料分頁的文章給詳看一遍,
      然後下載位在 GitHub 的範例程式原始碼,範例程式碼裡有提供不同的使用情境,再去釐清你所遇到的問題。

      刪除
    2. 補充,ViewModel 也是 Model,先有個觀念,不管是 Model 或是 ViewModel 都是類別,
      ViewModel 是專門用在 View 與 Controller 之間傳遞資料的類別,很單純的內容,沒有太過於複雜的實作,
      會用到 ViewModel 的情境有可能是 View 會需要顯示多種類別的資料,
      有關 ASP.NET MVC 的 ViewModel 的相關資料,可以參考以下連結的內容:
      ASP.NET MVC 的 ViewModel - 基礎篇
      http://kevintsengtw.blogspot.tw/2012/12/aspnet-mvc-viewmodel.html
      ASP.NET MVC - 為什麼不建議在 ViewModel 裡加入行為
      http://kevintsengtw.blogspot.tw/2012/12/aspnet-mvc-viewmodel_26.html
      ASP.NET MVC - ViewModel 參考文章與其他說明
      http://kevintsengtw.blogspot.tw/2012/12/aspnet-mvc-viewmodel_31.html

      刪除
    3. 作者已經移除這則留言。

      刪除
    4. 謝謝版大您的回覆,我在進行查詢post然後到顯示頁面都ok,但是我點選分頁時,為何又跳回非查詢前的資料?
      例如:

      1.資料上有{11,12,3,4,15}
      2.點選查詢包含{1}字元資料
      3.頁面顯示出(一頁2筆資料) 頁1:{11,12} 頁2:{15}
      4.點選分頁2,卻是{3,4},分頁變回3個,請問這部分是否在View上需要做調整?(好像變成非post後的資料)
      圖示View部分:http://ppt.cc/Tmrn
      圖示Controller部分:http://ppt.cc/BaKQ

      是否問題點在於您最後說明需要加上script的部分?

      刪除
    5. Hello,
      我在第一次的回覆時已經請你去下載已經放在 Github 的範例程式原始碼,
      「ASP.NET MVC 資料分頁操作 - 使用 PagedList.Mvc @ GitHub」
      http://kevintsengtw.blogspot.tw/2014/10/aspnet-mvc-pagedlistmvc-github.html
      .
      你只有提供片段的截圖以及你對於你所寫程式、流程的描述,
      坦白說,我真的完全看不懂也不理解,在這樣的情況下卻要讓我去解決你的問題,
      我沒有天眼通,也沒有心電感應,
      所以請下載範例程式原始碼,然後逐一比對自己的程式,
      也請你好好的將基礎給打穩。

      刪除
    6. 不好意思,我覺得是我說明不當…造成您有聽沒有懂…
      而我問題現已解決,感謝您的耐心解答。

      刪除
  3. Dear 版大:
    在七月份上完您MVC5的實戰課程後
    最近正式投入了MVC的專案
    發現不時還是會回到這兒或是Demo大那兒求援XD
    但確實很受用啊!!!
    對於上課的內容現在開始有了些Fu
    還在努力體會中...這篇ViewModel對我幫助很大
    自己和同事想了很多旁門左道...卻這麼簡單就解決了XD!
    我要繼續加油啊~~每天MVC >"<

    回覆刪除
    回覆
    1. Hello, 你好
      很高興能為你帶來幫助,坦白說,我給我在七月教課狀況的自評為「不是很好」,
      因為只想一股腦地將有關 ASP.NET MVC 的基礎都倒給你們,
      反而忽略了聽課同學們的吸收程度,導致於很多同學的眼神就是透露「聽不懂」的訊息,
      ASP.NET MVC 的入門學習曲線要比 ASP.NET WebForm 來得高,必須要有很多基礎的觀念來配合,
      所以很多人在開發 ASP.NET MVC 專案時就會四處碰壁與撞牆,
      不管是有沒有上過相關 ASP.NET MVC 課程或是看過 MVC 的書,碰到問題的機會都是很高的,
      唯有不斷的練習以及上網找尋相關資料並且吸收不同的資訊與作法,如此才能慢慢地熟悉 MVC 的開發,
      而我的部落格不強調內容一定是最新最快的資訊,文章的內容都是以實際專案上開發會遇到的情境來做說明,
      然後最近也開始整理以往文章裡的範例程式,並且放到 GitHub 上面公開,
      這麼做是希望以本身的經驗來分享給大家,減少四處撞牆與碰壁的情況。
      .
      看到你的留言讓我覺得相當高興,也期許未來開發 MVC 時可以越來越順利,
      加油!每天 MVC!

      刪除
  4. dear k大:
    請問我在vs2012運行網頁時,分頁點選都沒問題
    放上server主機時,點選分頁卻會失效(例:點分頁2,頁面無變化,還是在第1頁)
    請問是我在server主機上,缺了什麼東西嗎?

    回覆刪除
    回覆
    1. hello, 這應該是在考驗我有沒有天眼通與隔空探物的能力...
      其實點選沒有反應,我並不知道你所使用的方式為何(一般基本的分頁或者是有加入 AJAX 方式的分頁操作等)
      如果是一般基本的分頁操作,請直接看頁面上 Pager 的 HTML 原始碼,看看有沒有加入正確的 URL
      如果是 AJAX 的分頁操作,請開啟瀏覽器的 Developer Tools,觀察那邊有出現錯誤訊息
      建議你要修正提問方式,要仔細說明你所使用的操作方式(例如程式寫法、架構等),用什麼樣的方式發佈網站,有無錯誤紀錄,提供越詳細的內容,這樣才好讓別人能夠直接理解你的問題並找到解決方式。

      刪除
    2. 我的操作方式是按照此篇如下所述
      使用 jQuery 去改變 Pager 連結的行為,讓使用者按下分頁連結的時候是使用 Post 的方是將查詢條件值以及分頁 Index 傳遞給後端。

      刪除
    3. 剛剛使用ie的開發人員工具,本機檢視與server機檢視都有此問題 (都是jquery)http://ppt.cc/Gvvt
      但本機檢視反而可以正常執行,server卻不行...(攤手)

      刪除
    4. Hello,
      你要使用瀏覽器的 Developer Tools 去對頁面裡的 Javasscript Code 下中斷點做觀察,
      主要觀察的是 postPage() 這個 function,看看有沒有抓到正確的值,
      因為我所寫的前端操作方式相當簡單,就是去抓 pager 所點的那一個頁碼,然後在 form 裡面去增加 PageIndex 的 hidden 欄位,最後就是去 submit form。
      沒有反應的話,主要的問題就是在前端程式,看看 server 上有沒有 jQuery script 檔案,再看看檔案的路徑是否正確,
      如果直接去選取搜尋表單的欄位並且送出後是可以正常執行的,那就是前端程式的問題。

      刪除
    5. Hello, 這看起來是 IE 瀏覽器的問題
      你可以去開啟其他瀏覽器(Chrome or Firefox)然後瀏覽放在 Server 上面的網站,再做觀察。
      我前面就有說過,我所使用的方式是最簡單的基本 jQuery 應用,沒有用到什麼第三方的plugins 或是自己寫個什麼套件之類的,完全就是最基本、最簡單的運作,如果還是有問題的話,我也沒辦法,因為我現在是在隔空打牛 XD

      刪除
    6. 隔空打牛 = 隔空抓藥 + 隔山打牛 XDDDD

      刪除
    7. 您好,我也使用alert測試script是否有進入到該段程式,然後網頁都有讀到,但卻在點擊分頁時,資料無變化(在server機)
      在本機上偵錯時,卻一切正常…這我也不知該如何是好…不同chrome、ie、firefox也都一樣…QAQ
      我也試過把a href="#"...替換成javascript: void(0) , 也都是本機vs偵錯無問題,放上server機卻無效…不懂是什麼情況...
      不知您是否建議我改換什麼方式來使用需要查詢條件之後,分頁的問題?

      刪除
    8. 奇怪?我剛回覆的文章不見了
      您好,我使用不同瀏灠器(google、ie、firefox)在server機皆一樣,
      也使用alert測試是否有讀取到程式,也都有讀到…
      但卻在vs偵錯階段都正常,而放上server機上卻失效......
      不知道該怎麼辦了,請問您是否有另外建議的方法解決有查詢條件的分頁問題?

      我另外有參考別篇使用viewbag方式抓取參數,但是會變url的編碼,並不像您文章所貼的圖片一樣,寫入關鍵字也在url一樣是同樣的文字,還有第2問題是,如果使用viewbag,那麼日期該如何傳遞?改變參數去除/嗎?

      刪除
    9. 打的字都不見…google好奇怪
      ======
      您好,我使用不同瀏灠器皆同樣結果(點分頁沒反應)
      我也使用alert測試程式是否正常進入,也都ok
      但就是在vs偵錯可正常執行,而放上server機上,卻不行
      不知您是否建議我使用其他方式解決有查詢條件的分頁問題?

      另我有參考別篇,使用viewbag帶入,但會出現url的編碼,並非像您貼圖是正常的編碼,請問這該如何解決?
      另有日期查詢條件,請問我是否該轉換日期參數,去除/的編號?

      刪除
    10. Hello,相關的內容已經在你使用「詢問與建議」的 Ticket 回覆囉.

      刪除
    11. 抱歉,再請您刪除以上重覆回文

      感恩您的回答,如需要放上我的解法,請回信喔^^

      刪除
  5. 作者已經移除這則留言。

    回覆刪除
  6. 作者已經移除這則留言。

    回覆刪除
  7. 你好我是MVC的初學者 想請問一下
    現在我用MVC5 直接用模組讓他跑出我資料表的新增修改刪除
    那要怎麼把它原本的輸入改成下拉選單 現在下拉選單出來 可是卻不知道控制器 怎麼修改 儲存會出錯
    我可以參考甚麼資料嗎 感謝大大

    回覆刪除
    回覆
    1. 看起來你對於 ASP.NET MVC 真的是剛剛入門沒多久
      應該也沒有對 ASP.NET MVC 做有系統的逐步學習吧?
      ASP.NET MVC 所牽涉的一些基礎是相當廣泛的,
      你的問題包含了 View 的 HtmlHelper 以及後端資料處理的相關範圍
      很難用簡短的描述為你的問題作回答,因為你有很多基礎的部分並沒有概念
      不如你先花點時間去看 ASP.NET MVC 官網的基礎入門教學(這個部落格的幾篇文章有說)
      再來就是去買本書「ASP.NET MVC 5 網站開發美學」來看
      有關 ASP.NET MVC 下拉選單的相關文章,部落格裡也有蠻多篇的,但也因為很多會讓你搞得很糊塗
      不如就先到我部落格上面的「範例程式 @ GitHub」其中有一個「ASP.NET MVC DropDownList 範例」
      我有把相關的文章範例程式都整理出來然後放到 Github 上,直接看我所寫的原始碼

      刪除
  8. 我有一個很弱的疑問想請教k大,controller 中的 method
    [HttpPost]
    public ActionResult Index(ProductListViewModel model)
    如果改為
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Index(ProductListViewModel model)
    那在 cshtml 應該怎麼呼叫呢?

    回覆刪除
    回覆
    1. 部落格裡其他文章有介紹,請再搜尋吧
      (是我文章的關鍵字下得不好而讓人找不到?還是...)

      刪除
    2. 不好意思,因為我是要想請問在 PagedList.Mvc 中的設定方法。
      我再找找,謝謝。

      刪除
  9. 作者已經移除這則留言。

    回覆刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。

最近的留言