記一次艱難的jquery easy-ui ajax post 體驗


分享的經驗和教訓是:

1、jquery easy-ui ajax post 復雜的Json給后端解析,后端如果接收和解析

2、asp.net webform jquery easy-ui datagrid通用excel導出轉asp.net mvc

3、asp.net mvc 2 + jquery easy-ui搭建內部信息管理系統框架

由於本大叔超強的自學和動手能力,第一次正式玩asp.net mvc,由於mvc2不是使用Razor視圖引擎,有webform的開發經驗就不需要花很多時間去學習Razor語法,時間也很緊就選擇了MVC2. 在玩ajax get的時候玩得很爽,不想在需要前端頁面給后端Controller傳遞復雜Json時遇到get的url值超過長度的問題,那么搜索解決方案下來,需要使用Post方式來傳遞,Post簡單啊,一番調試,傻眼了Request里我上下左右翻了個遍,就是找不到如何接收前端頁面在HttpContext里如何取值。因為不是Post的是表單,而是復雜的Json字符串。看了很多文章還是不得要領啊,所以說是艱難的體驗。整整2天才搞定,唉,苦啊,同事那里我是不指望可以獲取幫助的,因為他們都是傳統webform的擁護者。

很多老碼農都以為啥技術想用就能用,稍微摸索一下就直接可以上手。其實也太自以為是了。基礎知識其實真心很重要,別看搞了那么多年c/s,轉b/s就是難,隨便能搞定,門都沒有!要不是一年前看過“[ASP.NET.MVC.2開發實戰][黃保翕]“那本書,真的不能那么順利就搞成了。

很多朋友喜歡說: no picture say g jb.或者說:我褲子都脫了,你給我看這個...  呵呵,上圖了,高s清哦!

 

 

 

 

 

前戲太長,立即轉入正題,艱難的ajax Post經歷:

 

上源碼咯(js):

//導出結果集到Excel
        function exportGrid() {
            if (getGridDataToExcelExport("StoreGrid").length == 0) {
                parent.$.messager.alert("系統提示", "記錄數為0,不需要導出!", "error");
                return;
            }
            var entity = new Object();
            entity.GridRows = getGridDataToExcelExport("StoreGrid");
            entity.GridColumnOptions = getGridColumnFieldsOptions("StoreGrid");
            entity.ExportFileName = $("#RDC_Name").combobox('getValue') + '倉庫收發貨訂單清單.xls';
            $.ajax({
                async: false,
                url: '/Home/SaveGridDataToExcelFile',
                type: 'POST',
                dataType: 'json',
                data: $.toJSON(entity),
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    if (data) {
                        window.location = '/Home/StreamFileFromDB/?fileID=' + data.fileID.toString();
                    }
                }
            });
        }

上面有截圖頁面傳遞的Json那是相當的復雜啊,而且想要實現通用,就是datagrid的行和列這些是變化的,網上找的大都是后端拿到傳遞的參數是反序列化成DTO對象的例子,但是抄了代碼發現也跟原文實現的不一致,比如:

單不說這種方式多么麻煩了,就是滿足不了我需要通用的要求。於是我跳過了這種方式,繼續找到下面的例子:

$("#create").click(function () {
    var contact = {
        UserName: "I love jQuery",
        Website: "http://www.google.com",
        Content: "Nice to meet you."
    };

    $.ajax({
        url: "/Contact",
        type: "POST",
        data: contact,
        dataType: "json",
        success: function (req) {
            $("#userTemplate").render(req).appendTo("#Contact");
        }
    });
});

  

[HttpPost]
public ActionResult Index(Contact contact)
{
    if (ModelState.IsValid)
    {
        android.Contact.AddObject(contact);
        android.SaveChanges();
    }
    var contacts = from c in android.Contact
                    where c.IsValid == 1
                    select c;
    return Json(contacts);
}

我測試下來斷點調試發現傳遞的參數contact始終是null,不得要領啊。

后來我又搜啊搜,發現一篇文章,測試下來終於拿到頁面的Json並反序列化了,“ASP.Net MCV 1.0 在Controller的Action Method中接收客戶端發送的JSON對象”,

 終於知道原來前端傳過來的值是藏在HttpContext.Request.InputStream里啊,天啊,沒有基礎知識咋辦啊!還好終於明白真相了。於是改寫了JsonParamFilter為

JsonStringFilter達到了我只需要Json字符串的目的。

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;   
using System.Runtime.Serialization.Json;   
using System.Web;
using System.Web.Mvc;

namespace BP_RFID_WMS.Controllers
{
    public class JsonParamFilter : ActionFilterAttribute
    {
        ///<summary>
        ///類型名稱
        ///</summary>
        public Type TargetType 
        { 
            get; 
            set; 
        } 

        /// <summary>
        /// 參數
        /// </summary>
        public string Param
        {
            get;
            set;
        }

        /// <summary>
        /// 將ActionExecutingContext上下文對象里的Request.InputStream流反序列化為DTO對象
        /// 將 JSON 數據反序列化為對象
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if ((filterContext.HttpContext.Request.ContentType ?? string.Empty).Contains("application/json"))
            {
                try
                {
                    object o = new DataContractJsonSerializer(TargetType).ReadObject(filterContext.HttpContext.Request.InputStream);
                    filterContext.ActionParameters[Param] = o;
                }
                catch (Exception ex)
                {
                    Com.DataCool.DotNetExpand.LogHelper.Error(ex);
                }
            }
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Runtime.Serialization.Json;

namespace BP_RFID_WMS.Controllers
{
    /// <summary>
    /// Request.InputStream流篩選器
    /// </summary>
    public class JsonStringFilter : ActionFilterAttribute
    {
        /// <summary>
        /// 參數
        /// </summary>
        public string Param
        {
            get;
            set;
        }

        /// <summary>
        /// 接受Request.InputStream流的POST數據Encoding為utf-8編碼的字符串
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if ((filterContext.HttpContext.Request.ContentType ?? string.Empty).Contains("application/json"))
            {
                try
                {
                    byte[] byts = new byte[filterContext.HttpContext.Request.InputStream.Length];
                    filterContext.HttpContext.Request.InputStream.Read(byts, 0, byts.Length);
                    string req = System.Text.Encoding.UTF8.GetString(byts);
                    req = filterContext.HttpContext.Server.UrlDecode(req);
                    filterContext.ActionParameters[Param] = req;
                }
                catch (Exception ex)
                {
                    Com.DataCool.DotNetExpand.LogHelper.Error(ex);
                }
            }
        }
    }
}

 

使用的代碼:

 /// <summary>
        /// 接受頁面easy-ui datagrid的行列數據並轉換成Excel文件存入數據庫
        /// </summary>
        [JsonStringFilter(Param = "entity")]
        public JsonResult SaveGridDataToExcelFile(string entity)
        {
            if (!string.IsNullOrEmpty(entity))
            {
                JObject jsonParams = JObject.Parse(entity);
                var gridRows = (JArray)jsonParams["GridRows"];
                var gridOptions = (JArray)jsonParams["GridColumnOptions"];
                var gridOptionList = (JArray)gridOptions;
                //可見的列
                List<JObject> gridCols = new List<JObject>();
                foreach (JObject j in gridOptionList)
                {
                    if (j.ToString().IndexOf("hidden") == -1)
                    {
                        gridCols.Add(j);
                    }
                }
                var fileName = jsonParams["ExportFileName"].Value<string>();
                string tempFileName = HttpContext.Server.MapPath("~/") + "TemplateFiles\\" + "CommonExcelFile.xls";
                FileStream fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read);
                var workBook = new HSSFWorkbook(fs);
                workBook.SetSheetName(0, "sheet1");
                var sheet = workBook.GetSheetAt(0);
                //表頭(列),第一行
                int newColIndex = 0;
                var titleRow = sheet.CreateRow(newColIndex);
                int cIndex = 0;
                foreach (JObject j in gridCols)
                {
                    titleRow.CreateCell(cIndex).SetCellValue(j["title"].Value<String>());
                    int width = j["width"].Value<int>() / 6;
                    if (width > 255)
                        width = 250;
                    sheet.SetColumnWidth(cIndex, width * 256);
                    cIndex++;
                }
                //行記錄
                for (int rowIndex = 0; rowIndex < gridRows.Count; rowIndex++)
                {
                    newColIndex++;
                    var row = sheet.CreateRow(newColIndex);
                    var jsonEntity = gridRows[rowIndex] as JObject;
                    for (int colIndex = 0; colIndex < gridCols.Count; colIndex++)
                    {
                        string cellValue = string.Empty;
                        JObject colOption = (JObject)gridCols[colIndex];
                        string field = colOption["field"].Value<string>();
                        if (jsonEntity[field].ToString().Length != 0)
                            cellValue = jsonEntity[field].Value<String>();
                        row.CreateCell(colIndex).SetCellValue(cellValue);
                    }
                }
                MemoryStream newFile = new MemoryStream();
                sheet.Workbook.Write(newFile);
                using (Reserve_DbEntities db = new Reserve_DbEntities())
                {
                    var resultFile = new AppExportFile();
                    resultFile.FileGuid = Guid.NewGuid();
                    resultFile.FileName = fileName;
                    resultFile.FileCreateDateTime = DateTime.Now;
                    resultFile.FileStreamByte = newFile.GetBuffer();
                    db.AddToAppExportFile(resultFile);
                    db.SaveChanges();
                    var data = new { fileID = resultFile.FileGuid.ToString() };
                    return Json(data, JsonRequestBehavior.AllowGet);
                }
            }
            else return Json(string.Empty, JsonRequestBehavior.AllowGet);
        }

OK,終於成功了,還需要補充一點ajax post默認是異步的,在回調函數里寫了很多alter類似的代碼當時都沒執行這些都難到了我,后來發現Chrome的F12開發者工具真是神器啊,OK無師自通了。當時感覺比老婆當初告訴我生的是女兒正和我意還要高興。呵呵...

 

不好意思,夜已深,就此擱筆了,后續有空再補上。

 

  

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM