zoukankan      html  css  js  c++  java
  • 记一次艰难的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无师自通了。当时感觉比老婆当初告诉我生的是女儿正和我意还要高兴。呵呵...

    不好意思,夜已深,就此搁笔了,后续有空再补上。

      

  • 相关阅读:
    JS继承
    Liunx 常用命令2
    团队作业(四)
    OpenEuler树莓派基础实验(无树莓派)
    thread同步测试
    团队作业(三)
    实验二测试
    浅谈JWT。
    monolog使用 brady
    Blazor Server获取Token访问外部Web Api
  • 原文地址:https://www.cnblogs.com/datacool/p/datacool_jqeasyui_post_aspnetmvc.html
Copyright © 2011-2022 走看看