因為默認的 MVC 的樣式文件裡對於的 table 和 其他相關樣式(h1~h6) 與Coolite有沖突,會導致GridPanel走樣,大家記得先把那個table 和 h1~h6的樣式清除掉才看到GridPanel的帥臉面 …
項目文件分布:
關於Coolite在MVC中的配置文件跟一般webform是一樣的。 但在MVC的Global.asax中,需要在 RegisterRoutes 方法裡加上這一句:
routes.IgnoreRoute("{exclude}/{coolite}/coolite.axd");
另外 ScriptManager 要注明 IDMode="Static“:
<ext:ScriptManager ID="ScriptManager1" runat="server" IDMode="Static"/>
其中唯一與一般MVC不同的是,我們需要定義自己的ActionResult來返回Json結果給客戶端。因為Coolite 的JsonReader 要求的格式大致都是這樣:{data: [{…}], totalCount: …}
關於JsonReader的一般用法:
<ext:JsonReader ReaderID="CustomerID" Root="data" TotalProperty="totalCount">
所以, 要繼承MVC ActionResult 的抽象方法 public override void ExecuteResult(ControllerContext context) 來返回給 JsonReader 合適口味的 JsonResult , 不然它就不認人了。
以下代碼實現了對Json Response & Save Response 的簡單封裝。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Coolite.Ext.Web; namespace CooliteMVC.Helper { public class AjaxStoreResult : ActionResult { public AjaxStoreResult() { } public AjaxStoreResult(object data) { this.Data = data; } public AjaxStoreResult(object data, int totalCount) : this(data) { this.TotalCount = totalCount; } public AjaxStoreResult(StoreResponseFormat responseFormat) { this.ResponseFormat = responseFormat; } private object data; public object Data { get { return this.data; } set { this.data = value; } } private int totalCount; public int TotalCount { get { return this.totalCount; } set { this.totalCount = value; } } private StoreResponseFormat responseFormat = StoreResponseFormat.Load; public StoreResponseFormat ResponseFormat { get { return this.responseFormat; } set { this.responseFormat = value; } } private SaveStoreResponse saveResponse; public SaveStoreResponse SaveResponse { get { if (this.saveResponse == null) { this.saveResponse = new SaveStoreResponse(); } return this.saveResponse; } } public override void ExecuteResult(ControllerContext context) { switch (this.ResponseFormat) { case StoreResponseFormat.Load: string json = Coolite.Ext.Web.JSON.Serialize(Data); json = "{data:" + json + ", totalCount:" + 100 + "}"; context.HttpContext.Response.Write(json); break; case StoreResponseFormat.Save: Response response = new Response(true); response.Success = this.SaveResponse.Success; response.Msg = this.SaveResponse.ErrorMessage; StoreResponseData saveResponse = new StoreResponseData(); saveResponse.Confirmation = this.SaveResponse.ConfirmationList; response.Data = saveResponse.ToString(); response.Write(); break; default: throw new ArgumentOutOfRangeException(); } } } public enum StoreResponseFormat { Load, Save } public class SaveStoreResponse { private bool success = true; private string errorMessage; public bool Success { get { return this.success; } set { this.success = value; } } public string ErrorMessage { get { return this.errorMessage; } set { this.errorMessage = value; } } public ConfirmationList ConfirmationList { get; set; } } }
AjaxStoreResult 在 CustomerController 中的使用:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Ajax; using CooliteMVC.Models; using CooliteMVC.Helper; using Coolite.Ext.Web; namespace CooliteMVC.Controllers { public class CustomerController : Controller { // // GET: /Customer/ public ActionResult Index() { ViewData["Title"] = "Customer List"; ViewData["Message"] = "Welcome to Coolite MVC! My name is Bruce."; return View(); } public ActionResult List(int limit, int start, string dir, string sort) { Random rand = new Random(); IList<Customer> list = new List<Customer>(); for (int i = start; i < start + limit; i++) list.Add(new Customer { CustomerID = "Customer" + i, Address = "Address" + i, City = "City" + rand.Next(1000), CompanyName = "Com" + rand.Next(1000), ContactName = "Contract" + rand.Next(1000), ContactTitle = "Title" + rand.Next(1000), Country = "Country" + rand.Next(1000), Email = rand.Next(1000) + "@live.com", Fax = rand.Next(1000).ToString() + rand.Next(1000), Mobile = rand.Next(1000).ToString() + rand.Next(1000), Notes = "Notes" + rand.Next(1000), Phone = "Phone" + rand.Next(1000), Region = "Region" + rand.Next(1000), TranDate = DateTime.Now.AddDays(rand.Next(30)) }); return new AjaxStoreResult(list, 100); } public ActionResult Save() { AjaxStoreResult ajaxStoreResult = new AjaxStoreResult(StoreResponseFormat.Save); try { StoreDataHandler dataHandler = new StoreDataHandler(Request["data"]); ChangeRecords<Customer> data = dataHandler.ObjectData<Customer>(); foreach (Customer customer in data.Deleted) { //db.Customers.Attach(customer); //db.Customers.DeleteOnSubmit(customer); } foreach (Customer customer in data.Updated) { //db.Customers.Attach(customer); //db.Refresh(RefreshMode.KeepCurrentValues, customer); } foreach (Customer customer in data.Created) { //db.Customers.InsertOnSubmit(customer); } } catch (Exception e) { ajaxStoreResult.SaveResponse.Success = false; ajaxStoreResult.SaveResponse.ErrorMessage = e.Message; } return ajaxStoreResult; } } }
頁面的關鍵代碼:
<ext:Store ID="dsCustomers" runat="server" > <Proxy> <ext:HttpProxy Url="/Customer/List" Method ="GET" /> </Proxy> <UpdateProxy> <ext:HttpWriteProxy Url="/Customer/Save" /> </UpdateProxy> <Reader> <ext:JsonReader ReaderID="CustomerID" Root="data" TotalProperty="totalCount"> <Fields> <ext:RecordField Name="CustomerID" SortDir="ASC" /> <ext:RecordField Name="CompanyName" /> <ext:RecordField Name="ContactName" /> <ext:RecordField Name="Email" /> <ext:RecordField Name="Phone" /> <ext:RecordField Name="Fax" /> <ext:RecordField Name="Region" /> <ext:RecordField Name="TranDate" Type="Date" /> </Fields> </ext:JsonReader> </Reader> <BaseParams> <ext:Parameter Name="limit" Value="15" Mode="Raw" /> <ext:Parameter Name="start" Value="0" Mode="Raw" /> <ext:Parameter Name="dir" Value="ASC" /> <ext:Parameter Name="sort" Value="CustomerID" /> </BaseParams> <SortInfo Field="CustomerID" Direction="ASC" /> </ext:Store>
我們可以看到其實就是Url的寫法不同而已:
<ext:HttpProxy Url="/Customer/List" Method ="GET" />
<ext:HttpWriteProxy Url="/Customer/Save" />
詳細頁面代碼跟第一章差不多,這裡不列出來。