zoukankan      html  css  js  c++  java
  • [Asp.Net]最近一个项目的总结

    引言

    项目到目前告一段落,目前进入测试阶段,下周就要去部署了。虽然项目不大,但是从头到尾都是自己一个人负责,在完成编码之后,对代码进行走查,命名规范,业务逻辑,代码优化等,能负责一个项目的整个编码,非常的兴奋啊。

    技术

    用到的技术:

    技术 项目中使用该技术目的
    ASP.NET 使用asp.net进行web端用户信息管理,对用户的增删改查,对签名样本的上传,下载Excel模版,导入用户信息。
    webService 为签名客户端提供修改用户密码接口服务,下载签名样本接口服务,
    windows服务 轮询数据库,对满足条件的dwg文件,从ftp服务器下载dwg文件至c盘缓存,获取签名样本文件,调用c++签名接口,对dwg文件进行签名。
    ftp 使用serv-u进行ftp服务器搭建,对dwg文件进行上传下载。serv-u配置教程。[工具]Serv-U配置教程
    jquery 使用ajax对用户信息的无刷新校验,主要用在登录页面,添加用户页面对信息的校验。
    js 回车键触发登录事件。
    jqueryui 上传前面样本,excel人员信息excel文件的弹出框。
    uploadify上传组件 上传.sign文件和.xlsx文件。
    NHibernate

    对象/关系数据库映射工具

    多层

    IData:数据库操作接口

    Data:数据库操作类

    Business:业务逻辑层

    Domain:简单领域层,包括Entities(数据库映射实体类)和Mapping(NHibernate映射xml文件)

    Ui:人员信息管理web端

    NHibernate

    对象/关系数据库映射工具

    NPOI

    项目中用到com组件进行读取excel的,但是测试的时候,在x64系统上读取不了,没办法采用了NPOI组件。

    AspNetPager

    对人员列表进行分页。

    工具

    工具 目的
    VS2012 代码编写
    动软代码生成器 根据NHibernate模版生成IData,Data,Business,Entities,Mapping代码生成
    Serv-U ftp服务器搭建
    SqlServer2012

    数据库

    windows server2008 服务器环境虚拟机,测试用
    Dependency Walker 查看dll依赖,

    [工具]推荐一款查看dll依赖工具

    web端界面

    该项目,为管理员使用,类似一个简单的管理工具。对样式要求不高就从网上找了一个样式,扒取的样式。

     登录界面:

    页面主要代码:

      1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="PYC.SignatureNX.Login" %>
      2 
      3 <!DOCTYPE html>
      4 
      5 <html xmlns="http://www.w3.org/1999/xhtml">
      6 <head runat="server">
      7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      8     <title>登录</title>
      9     <link href="CSS/admin_login.css" rel="stylesheet" />
     10     <script type="text/javascript" src="Scripts/jquery-1.10.2.js"></script>
     11     <script type="text/javascript">
     12         $(function () {
     13             //页面加载,用户名文本框获得焦点
     14             $("#txtCode").focus();
     15             //密码框获得焦点,断用户是否存在
     16             $("#txtPwd").focus(function () {
     17                 var strCode = $("#txtCode").val();
     18                 if (strCode == "") {
     19                     alert("请输入用户名");
     20                     $("#txtCode").focus();
     21                     return;
     22                 } else {
     23                     AjaxRequest(strCode, "", "Exist");
     24                 }
     25 
     26             });
     27             //单击登录按钮,验证密码是否存在,存在则登录,不存在重新输入用户密码
     28             $("#btnLogin").click(function () {
     29                 var strCode = $("#txtCode").val();
     30                 var strPwd = $("#txtPwd").val();
     31                 if (strCode == "") {
     32                     alert("请输入用户名");
     33                     return;
     34                 } else if (strPwd == "") {
     35                     alert("请输入密码");
     36                     return;
     37                 } else {
     38                     AjaxRequest(strCode, strPwd, "SignIn");
     39                 }
     40 
     41             });
     42 
     43         });
     44         //ajax请求,验证用户名,密码
     45         function AjaxRequest(code, pwd, method) {
     46             //拼接参数
     47             var strData = "strCode=" + code
     48             if (pwd != "") {
     49                 strData += "&strPwd=" + pwd;
     50             }
     51             $.ajax({
     52                 type: "POST",
     53                 url: "Ashx/Login.ashx?action=" + method,
     54                 data: strData,
     55                 contentType: "application/x-www-form-urlencoded",
     56                 dataType: "text",
     57                 success: function (data) {
     58                     if (data == "-1") {
     59                         alert("该用户不存在,请重新输入");
     60                         $("#txtCode").val("");
     61                         $("#txtCode").focus();
     62                         return false;
     63                     } else if (data == "0") {
     64                         alert("密码不正确,请重新输入");
     65                         $("#txtPwd").val("");
     66                         $("#txtPwd").focus();
     67                         return false;
     68                     } else if (data == "1") {
     69                         window.location.href = "Main.aspx";
     70                     }
     71                 },
     72                 //参数:XMLHttpRequest 对象、错误信息、(可选)捕获的异常对象。
     73                 error: function (XMLHttpRequest, textStatus, errorThrown) {
     74                     //请求失败,弹出错误状态码
     75                     alert(textStatus);
     76                 }
     77             });
     78         }
     79     </script>
     80     <script type="text/javascript">
     81         //回车触发登录事件
     82         function keyLogin() {
     83             //获得用户名和密码
     84             var strCode = $("#txtCode").val();
     85             var strPwd = $("#txtPwd").val();
     86             //如果按下回车键,此时用户名为空,则提示,用户名文本框获得焦点,并阻止提交
     87             if (event.keyCode == 13 && strCode == "") {
     88                 alert("请输入用户名");
     89                 $("#txtCode").val("");
     90                 $("#txtCode").focus();
     91                 return;
     92             } else if (event.keyCode == 13 && strPwd == "") {
     93                 //如果按下回车键,此时密码为空,则提示,密码文本框获得焦点,并阻止提交
     94                 alert("请输入密码");
     95                 $("#txtPwd").val("");
     96                 $("#txtPwd").focus();
     97                 return;
     98             }
     99             //如果按下回车键,并且用户名和密码都不为空,触发登录按钮的单击事件,进行提交验证
    100             if (event.keyCode == 13 && strCode != "" && strPwd != "")   //回车键的键值为13
    101                 document.getElementById("btnLogin").click(); //调用登录按钮的登录事件
    102         }
    103     </script>
    104 </head>
    105 <body onkeyup="keyLogin();">
    106     <form id="form1" runat="server">
    107         <div class="admin_login_wrap">
    108             <h1>系统登录窗口</h1>
    109             <div class="adming_login_border">
    110                 <div class="admin_input">
    111                    
    112                         <ul class="admin_items">
    113                             <li>
    114                                 <label for="user">用户名:</label>
    115                                 <input type="text" name="txtCode" value="" id="txtCode" size="40" class="admin_input_style" />
    116                             </li>
    117                             <li>
    118                                 <label for="pwd">密码:</label>
    119                                 <input type="password" name="txtPwd" value="" id="txtPwd" size="40" class="admin_input_style" />
    120                             </li>
    121                             <li>
    122                                 <input type="button" tabindex="3" id="btnLogin" value="登录" class="btn btn-primary" />
    123                             </li>
    124                         </ul>
    125                    
    126                 </div>
    127             </div>
    128         </div>
    129 
    130     </form>
    131 </body>
    132 </html>
    Login.aspx

    业务逻辑:用户名失去焦点时,进行用户名是否存在。使用ajax进行无刷新登录。
    人员信息模版:

    人员信息列表页面:

    导入过程:

    结果:

    上传签名人样本:

    单击人员列表中的上传,弹出上传签名样本的窗口。

    页面主要代码:

      1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Main.aspx.cs" Inherits="PYC.SignatureNX.Main" %>
      2 
      3 <!DOCTYPE html>
      4 <%@ Register Assembly="AspNetPager" Namespace="Wuqi.Webdiyer" TagPrefix="webdiyer" %>
      5 <html xmlns="http://www.w3.org/1999/xhtml">
      6 <head runat="server">
      7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      8     <title>用户信息</title>
      9     <link href="CSS/common.css" rel="stylesheet" />
     10     <link href="CSS/main.css" rel="stylesheet" />
     11     <style type="text/css">
     12         /*隐藏上传的进度条*/
     13         .uploadify-queue
     14         {
     15             display: none;
     16         }
     17         /*查询框中灰色字体样式*/
     18         .search
     19         {
     20             color: gray;
     21         }
     22     </style>
     23     <script type="text/javascript" src="Scripts/jquery-1.10.2.js"></script>
     24     <link href="Scripts/uploadify/css/uploadify.css" rel="stylesheet" />
     25     <script type="text/javascript" src="Scripts/uploadify/js/uploadify3.2.1/jquery.uploadify.js"></script>
     26     <link href="Scripts/JqueryUI/css/redmond/jquery-ui-1.10.4.custom.css" rel="stylesheet" />
     27     <script type="text/javascript" src="Scripts/JqueryUI/js/jquery-ui-1.10.4.custom.js"></script>
     28     <script type="text/javascript">
     29         $(function () {
     30             //初始化批量导入弹出框
     31             OpenDialog("dialogxls", "上传批导人员信息", false);
     32 
     33             //初始化dialog
     34             OpenDialog("dialog", "上传签名样本", true);
     35         });
     36         function OpenDialog(id, title, isContainsUpload) {
     37             //弹出框的初始化方法
     38             $("#" + id).dialog({
     39 
     40                 // 初始化之后,是否立即显示对话框,默认为 true
     41                 autoOpen: false,
     42 
     43                 //设置弹出框的高度 400px
     44                  400,
     45 
     46                 //是否模式对话框,默认为 false
     47                 modal: true,
     48 
     49                 //是否允许拖动,默认为 true
     50                 draggable: true,
     51 
     52                 //是否可以调整对话框的大小,默认为 true
     53                 resizable: true,
     54 
     55                 //弹出框的标题
     56                 title: title,
     57                 position: "center",
     58                 close: function () {
     59                     if (isContainsUpload == true) {
     60                         //注意jquery下检查一个元素是否存在必须使用 .length >0 来判断
     61                         if ($('#btnUpload').length > 0) {
     62                             //如果存在,则将其销毁
     63                             $('#btnUpload').uploadify('destroy');
     64                         }
     65                     } else {
     66                         //注意jquery下检查一个元素是否存在必须使用 .length >0 来判断
     67                         if ($('#btnUploadXLS').length > 0) {
     68                             //如果存在,则将其销毁
     69                             $('#btnUploadXLS').uploadify('destroy');
     70                         }
     71 
     72                     }
     73                 }
     74             });
     75         }
     76     </script>
     77 </head>
     78 <body>
     79     <div class="result-wrap">
     80 
     81         <form id="form1" runat="server">
     82             <div>
     83                 <table style=" 100%;">
     84                     <tr>
     85                         <td>
     86                             <asp:Button ID="btnAdd" runat="server" Text="添加" CssClass="btn btn6" OnClick="btnAdd_Click" />&nbsp;&nbsp;<asp:Button CssClass="btn btn6" ID="btnDeleteMore" runat="server" Text="批量删除" OnClientClick="SelectUsers();" OnClick="btnDeleteMore_Click" />&nbsp;&nbsp;<input class="btn btn6" type="button" name="name" id="btnMoreImport" value="批量导入" />&nbsp;&nbsp;<asp:Button CssClass="btn btn6" ID="btnTemlpalteLoad" runat="server" Text="批导模版下载" OnClick="btnTemlpalteLoad_Click" />&nbsp;&nbsp;<%--<a href="SignTest.aspx">签名信息列表</a>--%><asp:Button Text="批量启用" runat="server" ID="btnStartMore" CommandName="Start" CssClass="btn btn6" OnClientClick="SelectUsers();" OnClick="btnStartMore_Click" />&nbsp;&nbsp;<asp:Button Text="批量停用" runat="server" OnClick="btnStartMore_Click" CssClass="btn btn6" OnClientClick="SelectUsers();" CommandName="Stop" ID="btnStopMore" /></td>
     87                         <td align="right">
     88                             <asp:TextBox runat="server" Text="请输入查询关键字" ID="txtSearch" CssClass="search" />&nbsp;&nbsp;<asp:Button Text="查询" runat="server" CssClass="btn btn6" ID="btnSearch" OnClick="btnSearch_Click" /></td>
     89                     </tr>
     90                 </table>
     91                 <asp:HiddenField runat="server" ID="hdFieldIds" Value="" />
     92                 <br />
     93 
     94                 <div class="result-content">
     95                     <asp:Repeater ID="RptUserList" runat="server" OnItemDataBound="RptUserList_ItemDataBound">
     96                         <HeaderTemplate>
     97                             <table class="result-tab" style=" 100%; text-align: center;" id="tbUsers">
     98                                 <tr>
     99                                     <th width="5%">
    100                                         <a href="javascript:void(0)" id="lnkSelectAll">全选</a> </th>
    101                                     <th width="5%">序号</th>
    102                                     <th>用户名</th>
    103                                     <th>签名人姓名</th>
    104                                     <th>签名人样本</th>
    105                                     <th>状态</th>
    106                                     <th>操作</th>
    107                                 </tr>
    108                         </HeaderTemplate>
    109                         <ItemTemplate>
    110                             <tr>
    111                                 <td>
    112                                     <input type="checkbox" name="name" value='<%#Eval("Sign_Code") %>' />
    113                                 </td>
    114                                 <td>
    115                                     <asp:Literal ID="ltlItemNo" runat="server" />
    116                                 </td>
    117                                 <td><%#Eval("Sign_Code") %></td>
    118                                 <td><%#Eval("Sign_Name") %></td>
    119                                 <td id="td<%#Eval("Sign_Code") %>">
    120                                     <asp:Literal Text="" ID="ltlSignSample" runat="server" />
    121                                 </td>
    122                                 <td>
    123                                     <asp:LinkButton OnClick="lnkState_Click" ID="lnkState" Text="" runat="server" /></td>
    124                                 <td>
    125                                     <asp:LinkButton CommandArgument='<%#Eval("Sign_Code") %>' CommandName="Edit" Text="编辑" ID="lnkBtn" OnClick="lnkBtn_Click" runat="server" />&nbsp;&nbsp;
    126                                     <asp:LinkButton Text="删除" CommandArgument='<%#Eval("Sign_Code") %>' CommandName="Delete" OnClick="lnkBtn_Click" runat="server" />
    127                                 </td>
    128 
    129                             </tr>
    130                         </ItemTemplate>
    131                         <FooterTemplate>
    132                             </table>
    133                         </FooterTemplate>
    134                     </asp:Repeater>
    135                 </div>
    136                 <div id="dialogxls" title="上传Excel文件" style="text-align: center; display: none;">
    137                     <input type="button" name="name" id="btnUploadXLS" value="上传" />
    138                     <span id="spanMsg">(只能上传.xlsx格式文件)</span>
    139                 </div>
    140                 <div id="dialog" title="上传签名样本" style="text-align: center; display: none;">
    141                     <input type="button" name="name" id="btnUpload" value="上传样本" />
    142                     <span>(只能上传.sign格式文件)</span>
    143                 </div>
    144 
    145             </div>
    146 
    147 
    148             <div class="list-page">
    149                 <%-- 分页样式一 首页 上一页 下一页 尾页--%>
    150                 <webdiyer:AspNetPager ID="AspNetPager1" runat="server"
    151                     CustomInfoHTML="共%PageCount%页,当前为第%CurrentPageIndex%页,每页%PageSize%条,共%RecordCount%条"
    152                     FirstPageText="首页"
    153                     LastPageText="尾页"
    154                     NextPageText="下一页"
    155                     PageIndexBoxType="TextBox"
    156                     PrevPageText="上一页"
    157                     ShowCustomInfoSection="Left"
    158                     ShowPageIndex="true"
    159                     ShowPageIndexBox="Always"
    160                     SubmitButtonText="Go"
    161                     SubmitButtonClass="right_d_btn"
    162                     TextAfterPageIndexBox="页"
    163                     TextBeforePageIndexBox="转到"
    164                     OnPageChanging="AspNetPager1_PageChanging"
    165                     AlwaysShow="True"
    166                     PageSize="10"
    167                     ShowMoreButtons="false"
    168                     HorizontalAlign="Center">
    169                 </webdiyer:AspNetPager>
    170 
    171             </div>
    172         </form>
    173     </div>
    174 </body>
    175 </html>
    176 <script type="text/javascript">
    177 
    178     //全选,全不选
    179     $("#lnkSelectAll").click(function () {
    180         var txt = $(this).text();
    181         var flag = false;
    182         var strIds = "";
    183         if (txt == "全选") {
    184             $(this).text("全不选");
    185             flag = true;
    186         } else {
    187             $(this).text("全选");
    188             flag = false;
    189         }
    190         $("#tbUsers td :checkbox").each(function () {
    191             this.checked = flag;
    192         });
    193         if (flag) {
    194             $("#tbUsers td :checkbox").each(function (index) {
    195                 strIds += $(this).val() + ",";
    196             });
    197         } else {
    198             strIds = "";
    199         }
    200         $("#hdFieldIds").val(strIds)
    201 
    202     });
    203     //选中的用户
    204     function SelectUsers() {
    205         var strIds = "";
    206         $("#tbUsers td :checked").each(function (index) {
    207             strIds += $(this).val() + ",";
    208         });
    209         $("#hdFieldIds").val(strIds)
    210 
    211     }
    212     //批量导入
    213     $("#btnMoreImport").click(function () {
    214         $("#dialogxls").dialog("open");
    215         //上传
    216         //上传插件初始化方法
    217         $('#btnUploadXLS').uploadify({
    218 
    219             //选择文件后是否自动上传,默认为true
    220             'auto': true,
    221             //选择文件按钮   
    222             'buttonClass': 'some-class',
    223             //是否开启调试模式
    224             // 'debug': true,
    225             //设置按钮文本
    226             'buttonText': '上传人员信息文件',
    227             //以get方式提交,默认post
    228             'method': 'post',
    229             //单个文件大小,0为无限制,可接受KB,MB,GB等单位的字符串值 上传大文件               
    230             'fileSizeLimit': '0',
    231             'queueSizeLimit': 1,
    232             //文件描述
    233             'fileTypeDesc': 'Files',
    234             'multi': false,
    235             //允许上传的文件类型 以分号分割
    236             'fileTypeExts': '*.xlsx',
    237             //当浏览文件对话框关闭触发
    238             'onDialogClose': function (queueData) {
    239                 if (queueData.filesSelected>0) {
    240                     $("#spanMsg").html("正在处理上传的文件,请稍等....");
    241                 }
    242             },
    243             //FLash文件路径
    244             'swf': '/Scripts/uploadify/js/uploadify3.2.1/uploadify.swf',
    245             //上传文件处理后台页面
    246             'uploader': '/Ashx/SampleUp.ashx?action=xlsUpload',
    247             //上传成功后触发,每个文件都触发
    248             'onUploadSuccess': function (file, data, response) {
    249                 if (data == "0") {
    250                     alert("人员信息有不合法数据,请检查后再次上传");
    251                     return false;
    252                 } else {
    253                     window.location = window.location;
    254                 }
    255             }
    256         });
    257     });
    258     var strSignCode = "";
    259     function Upload(strCode) {
    260         strSignCode = strCode;
    261         //打开弹出框的按钮
    262         //单击按钮 调用弹出框的open方法
    263         $("#dialog").dialog("open");
    264         //上传
    265         //上传插件初始化方法
    266         $('#btnUpload').uploadify({
    267 
    268             //选择文件后是否自动上传,默认为true
    269             'auto': true,
    270             //选择文件按钮   
    271             'buttonClass': 'some-class',
    272 
    273             //设置按钮文本
    274             'buttonText': '上传样本',
    275             'method': 'post',
    276             //单个文件大小,0为无限制,可接受KB,MB,GB等单位的字符串值 上传大文件 可参考使用手册说明               
    277             'fileSizeLimit': '0',
    278             'queueSizeLimit': 1,
    279             //文件描述
    280             'fileTypeDesc': 'Files',
    281             'multi': false,
    282             //允许上传的文件类型 以分号分割
    283             'fileTypeExts': '*.sign',
    284             'onUploadStart': function (file) {
    285                 $("#btnUpload").uploadify("settings", "formData", { 'code': strSignCode });
    286             },
    287             //FLash文件路径
    288             'swf': '/Scripts/uploadify/js/uploadify3.2.1/uploadify.swf',
    289             //上传文件处理后台页面
    290             'uploader': '/Ashx/SampleUp.ashx?action=mainUpload',
    291             //上传成功后触发,每个文件都触发
    292             'onUploadSuccess': function (file, data, response) {
    293                 // window.location = window.location;
    294                 //上传成功,改变单元格内容,并停留在当前页面,可以避免刷新回到首页的情况。
    295                 $("#td" + strSignCode).html("<span>" + data + "</span>");
    296                 $("#dialog").dialog("close");
    297             }
    298         });
    299     }
    300 
    301     //查询相关方法
    302     //获得焦点时,将文本框清空,并移除样式。
    303     //失去焦点时,判断是否为空,为空则将提示信息重新填回,并添加样式。
    304     $("#txtSearch").focus(function () {
    305         if ($(this).val() == "请输入查询关键字") {
    306             $(this).val("");
    307             $(this).removeClass("search");
    308         }
    309     }).blur(function () {
    310         if ($(this).val() == "") {
    311             $(this).val("请输入查询关键字");
    312             $(this).addClass("search");
    313         }
    314     });
    315 
    316 </script>
    Main.aspx

    添加人员信息页面:
    业务逻辑:签名样本应跟签名人编号相同。只有输入了编号,才允许上传,并且保证上传后的签名样本名称为只读的。

    关于只读框和密码框应注意的地方:[Asp.net]说说密码框和只读框

    输入用户名后:

    用户编辑页面:

    由于添加和编辑页面代码较简单,就不再贴代码,需注意的就是只读框的取值。

    辅助类

      1   public class ExcelHelper
      2     {
      3         /// <summary>
      4         /// 将Excel文件中的数据读出到DataTable中
      5         /// </summary>
      6         /// <param name="strFile">文件路径</param>
      7         /// <returns>datatable</returns>
      8         public static DataTable Excel2DataTable(string strFile, string strSheetName, string strTableName)
      9         {
     10             DataTable dt = new DataTable();
     11             IWorkbook workbook = null;
     12             using (FileStream fs = new FileStream(strFile, FileMode.Open, FileAccess.Read))
     13             {
     14                 //office2003 HSSFWorkbook
     15                 //office2007 XSSFWorkbook初始化
     16                 workbook = new XSSFWorkbook(fs);
     17             }
     18             ISheet sheet = workbook.GetSheet(strSheetName);
     19             //
     20             dt = Export2DataTable(sheet, 0, false);
     21             return dt;
     22 
     23         }
     24         /// <summary>
     25         /// 将指定sheet中的数据导入到datatable中
     26         /// </summary>
     27         /// <param name="sheet">指定需要导出的sheet</param>
     28         /// <param name="HeaderRowIndex">列头所在的行号,-1没有列头</param>
     29         /// <param name="needHeader">是否需要列头</param>
     30         /// <returns>DataTable</returns>
     31         private static DataTable Export2DataTable(ISheet sheet, int HeaderRowIndex, bool needHeader)
     32         {
     33             DataTable dt = new DataTable();
     34             XSSFRow headerRow = null;
     35             int cellCount;
     36             try
     37             {
     38                 if (HeaderRowIndex < 0 || !needHeader)
     39                 {
     40                     headerRow = sheet.GetRow(0) as XSSFRow;
     41                     cellCount = headerRow.LastCellNum;
     42                     for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
     43                     {
     44                         DataColumn column = new DataColumn(Convert.ToString(i));
     45                         dt.Columns.Add(column);
     46                     }
     47                 }
     48                 else
     49                 {
     50                     headerRow = sheet.GetRow(HeaderRowIndex) as XSSFRow;
     51                     cellCount = headerRow.LastCellNum;
     52                     for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
     53                     {
     54                         ICell cell = headerRow.GetCell(i);
     55                         if (cell == null)
     56                         {
     57                             break;//到最后 跳出循环
     58                         }
     59                         else
     60                         {
     61                             //创建列
     62                             DataColumn column = new DataColumn(headerRow.GetCell(i).ToString());
     63                             //将列添加到datatable中
     64                             dt.Columns.Add(column);
     65                         }
     66 
     67                     }
     68                 }
     69                 //保存最后一行的索引
     70                 int intRowCount = sheet.LastRowNum;
     71                 for (int i = HeaderRowIndex + 1; i <= sheet.LastRowNum; i++)
     72                 {
     73                     XSSFRow xSSFRow = null;
     74                     if (sheet.GetRow(i) == null)
     75                     {
     76                         xSSFRow = sheet.CreateRow(i) as XSSFRow;
     77                     }
     78                     else
     79                     {
     80                         xSSFRow = sheet.GetRow(i) as XSSFRow;
     81                     }
     82                     DataRow dtRow = dt.NewRow();
     83                     for (int j = xSSFRow.FirstCellNum; j <= cellCount; j++)
     84                     {
     85                         //j=-1表示没有数据了
     86                         if (j != -1 && xSSFRow.GetCell(j) != null)
     87                         {
     88                             switch (xSSFRow.GetCell(j).CellType)
     89                             {
     90                                 case CellType.Boolean:
     91                                     dtRow[j] = Convert.ToString(xSSFRow.GetCell(j).BooleanCellValue);
     92                                     break;
     93                                 case CellType.Error:
     94                                     dtRow[j] = ErrorEval.GetText(xSSFRow.GetCell(j).ErrorCellValue);
     95                                     break;
     96                                 case CellType.Formula:
     97                                     switch (xSSFRow.GetCell(j).CachedFormulaResultType)
     98                                     {
     99 
    100                                         case CellType.Boolean:
    101                                             dtRow[j] = Convert.ToString(xSSFRow.GetCell(j).BooleanCellValue);
    102 
    103                                             break;
    104                                         case CellType.Error:
    105                                             dtRow[j] = ErrorEval.GetText(xSSFRow.GetCell(j).ErrorCellValue);
    106 
    107                                             break;
    108                                         case CellType.Numeric:
    109                                             dtRow[j] = Convert.ToString(xSSFRow.GetCell(j).NumericCellValue);
    110 
    111                                             break;
    112                                         case CellType.String:
    113                                             string strFORMULA = xSSFRow.GetCell(j).StringCellValue;
    114                                             if (strFORMULA != null && strFORMULA.Length > 0)
    115                                             {
    116                                                 dtRow[j] = strFORMULA.ToString();
    117                                             }
    118                                             else
    119                                             {
    120                                                 dtRow[j] = null;
    121                                             }
    122                                             break;
    123                                         default:
    124                                             dtRow[j] = "";
    125                                             break;
    126                                     }
    127                                     break;
    128                                 case CellType.Numeric:
    129                                     if (DateUtil.IsCellDateFormatted(xSSFRow.GetCell(j)))
    130                                     {
    131                                         dtRow[j] = DateTime.FromOADate(xSSFRow.GetCell(j).NumericCellValue);
    132                                     }
    133                                     else
    134                                     {
    135                                         dtRow[j] = Convert.ToDouble(xSSFRow.GetCell(j).NumericCellValue);
    136                                     }
    137                                     break;
    138                                 case CellType.String:
    139                                     string str = xSSFRow.GetCell(j).StringCellValue;
    140                                     if (!string.IsNullOrEmpty(str))
    141                                     {
    142 
    143                                         dtRow[j] = Convert.ToString(str);
    144                                     }
    145                                     else
    146                                     {
    147                                         dtRow[j] = null;
    148                                     }
    149                                     break;
    150                                 default:
    151                                     dtRow[j] = "";
    152                                     break;
    153                             }
    154                         }
    155                         else
    156                         {
    157                             break;
    158                         }
    159                     }
    160                     //将行加入datatable中
    161                     dt.Rows.Add(dtRow);
    162                 }
    163             }
    164             catch (Exception ex)
    165             {
    166                 throw ex;
    167             }
    168             return dt;
    169         }
    170         /// <summary>
    171         /// 将DataTable中的数据导入Excel文件中
    172         /// </summary>
    173         /// <param name="dt"></param>
    174         /// <param name="strFile"></param>
    175         public static void DataTable2Excel(DataTable dt, string strFile, string strSheetName)
    176         {
    177             IWorkbook workbook = new XSSFWorkbook();
    178             ISheet sheet = workbook.CreateSheet(strSheetName);
    179             IRow header = sheet.CreateRow(0);
    180             for (int i = 0; i < dt.Columns.Count; i++)
    181             {
    182                 ICell cell = header.CreateCell(i);
    183                 cell.SetCellValue(dt.Columns[i].ColumnName);
    184             }
    185             //数据
    186             for (int i = 0; i < dt.Rows.Count; i++)
    187             {
    188                 IRow row = sheet.CreateRow(i + 1);
    189                 for (int j = 0; j < dt.Columns.Count; j++)
    190                 {
    191                     ICell cell = row.CreateCell(j);
    192                     cell.SetCellValue(dt.Rows[i][j].ToString());
    193                 }
    194             }
    195             MemoryStream stream = new MemoryStream();
    196             workbook.Write(stream);
    197             byte[] buffer = stream.ToArray();
    198             using (FileStream fs = new FileStream(strFile, FileMode.Create, FileAccess.Write))
    199             {
    200                 fs.Write(buffer, 0, buffer.Length);
    201                 fs.Flush();
    202             }
    203         }
    204         /// <summary>
    205         /// 获取单元格类型
    206         /// </summary>
    207         /// <param name="xSSFCell">单元格</param>
    208         /// <returns>object</returns>
    209         private static object GetValueType(XSSFCell xSSFCell)
    210         {
    211             if (xSSFCell == null)
    212             {
    213                 return null;
    214             }
    215             switch (xSSFCell.CellType)
    216             {
    217                 case CellType.Blank:
    218                     return null;
    219                 case CellType.Boolean:
    220                     return xSSFCell.BooleanCellValue;
    221                 case CellType.Error:
    222                     return xSSFCell.ErrorCellValue;
    223 
    224                 case CellType.Numeric:
    225                     return xSSFCell.NumericCellValue;
    226                 case CellType.String:
    227                     return xSSFCell.StringCellValue;
    228                 case CellType.Formula:
    229                 default:
    230                     return "=" + xSSFCell.StringCellValue;
    231             }
    232         }
    233 
    234     }
    ExcelHelper
      1   public class FTPHelper
      2     {
      3         #region 字段
      4         /// <summary>
      5         /// ftp地址,带ftp协议
      6         /// </summary>
      7         private string strFtpURI;
      8         /// <summary>
      9         /// ftp用户名
     10         /// </summary>
     11         private string strFtpUserID;
     12         /// <summary>
     13         /// ftp的ip地址
     14         /// </summary>
     15         private string strFtpServerIP;
     16         /// <summary>
     17         /// ftp用户登录密码
     18         /// </summary>
     19         private string strFtpPassword;
     20         /// <summary>
     21         /// ftp目录路径
     22         /// </summary>
     23         private string strFtpRemotePath;
     24         #endregion
     25 
     26         /// <summary>  
     27         /// 连接FTP服务器
     28         /// </summary>  
     29         /// <param name="strFtpServerIP">FTP连接地址</param>  
     30         /// <param name="strFtpRemotePath">指定FTP连接成功后的当前目录, 如果不指定即默认为根目录</param>  
     31         /// <param name="strFtpUserID">用户名</param>  
     32         /// <param name="strFtpPassword">密码</param>  
     33         public FTPHelper(string strFtpServerIP, string strFtpRemotePath, string strFtpUserID, string strFtpPassword)
     34         {
     35             this.strFtpServerIP = strFtpServerIP;
     36             this.strFtpRemotePath = strFtpRemotePath;
     37             this.strFtpUserID = strFtpUserID;
     38             this.strFtpPassword = strFtpPassword;
     39             this.strFtpURI = "ftp://" + strFtpServerIP + strFtpRemotePath;
     40         }
     41 
     42         /// <summary>
     43         /// 上载
     44         /// </summary>
     45         /// <param name="strFilename">本地文件路径</param>
     46         /// <param name="strSavePath">ftp服务器文件保存路径</param>
     47         public void Upload(string strFilename, string strSavePath)
     48         {
     49             FileInfo fileInf = new FileInfo(strFilename);
     50             FtpWebRequest reqFTP;
     51             reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strSavePath + fileInf.Name));
     52             reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
     53             reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
     54             reqFTP.KeepAlive = false;
     55             reqFTP.UseBinary = true;
     56             reqFTP.Proxy = null;
     57             reqFTP.ContentLength = fileInf.Length;
     58             int buffLength = 2048;
     59             byte[] buff = new byte[buffLength];
     60             int contentLen;
     61             FileStream fs = fileInf.OpenRead();
     62             try
     63             {
     64                 Stream strm = reqFTP.GetRequestStream();
     65                 contentLen = fs.Read(buff, 0, buffLength);
     66                 while (contentLen != 0)
     67                 {
     68                     strm.Write(buff, 0, contentLen);
     69                     contentLen = fs.Read(buff, 0, buffLength);
     70                 }
     71                 strm.Close();
     72                 fs.Close();
     73             }
     74             catch (Exception ex)
     75             {
     76                 throw new Exception(ex.Message);
     77             }
     78         }
     79         /// <summary>
     80         /// 上载
     81         /// </summary>
     82         /// <param name="strFilename">本地文件路径</param>
     83         /// <param name="strSavePath">ftp服务器文件保存路径</param>
     84         /// <param name="strStrOldName">ftp服务器文件保存的名字</param>
     85         public void Upload(string strFilename, string strSavePath, string strStrOldName)
     86         {
     87             FileInfo fileInf = new FileInfo(strFilename);
     88             FtpWebRequest reqFTP;
     89             reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strSavePath + strStrOldName));
     90             reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
     91             reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
     92             reqFTP.KeepAlive = false;
     93             reqFTP.UseBinary = true;
     94             reqFTP.Proxy = null;
     95             reqFTP.ContentLength = fileInf.Length;
     96             int buffLength = 2048;
     97             byte[] buff = new byte[buffLength];
     98             int contentLen;
     99             FileStream fs = fileInf.OpenRead();
    100             try
    101             {
    102                 Stream strm = reqFTP.GetRequestStream();
    103                 contentLen = fs.Read(buff, 0, buffLength);
    104                 while (contentLen != 0)
    105                 {
    106                     strm.Write(buff, 0, contentLen);
    107                     contentLen = fs.Read(buff, 0, buffLength);
    108                 }
    109                 strm.Close();
    110                 fs.Close();
    111             }
    112             catch (Exception ex)
    113             {
    114                 throw new Exception(ex.Message);
    115             }
    116         }
    117         /// <summary>
    118         /// 下载
    119         /// </summary>
    120         /// <param name="strFilePath">本地保存路径</param>
    121         /// <param name="strFileName">文件名</param> 
    122         /// <param name="strFileName">本地临时名称</param>
    123         public void Download(string strFilePath, string strFileName, string strLocalName)
    124         {
    125             try
    126             {
    127                 FileStream outputStream = new FileStream(strFilePath + strLocalName, FileMode.Create);
    128                 FtpWebRequest reqFTP;
    129                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFileName));
    130                 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
    131                 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
    132                 reqFTP.UseBinary = true;
    133                 reqFTP.UsePassive = true;
    134                 reqFTP.Proxy = null;
    135                 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
    136                 Stream ftpStream = response.GetResponseStream();
    137                 long cl = response.ContentLength;
    138                 int bufferSize = 2048;
    139                 int readCount;
    140                 byte[] buffer = new byte[bufferSize];
    141                 readCount = ftpStream.Read(buffer, 0, bufferSize);
    142                 while (readCount > 0)
    143                 {
    144                     outputStream.Write(buffer, 0, readCount);
    145                     readCount = ftpStream.Read(buffer, 0, bufferSize);
    146                 }
    147                 ftpStream.Close();
    148                 outputStream.Close();
    149                 response.Close();
    150             }
    151             catch (Exception ex)
    152             {
    153                 //记录日志
    154                 Common.LogHelper.WriteLog("文件下载异常:" + ex.Message);
    155             }
    156         }
    157         /// <summary>
    158         /// 下载
    159         /// </summary>
    160         /// <param name="strFilePath">本地保存路径</param>
    161         /// <param name="strFileName">文件名</param>
    162         public void Download(string strFilePath, string strFileName)
    163         {
    164             try
    165             {
    166                 FileStream outputStream = new FileStream(strFilePath + strFileName, FileMode.Create);
    167                 FtpWebRequest reqFTP;
    168                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFileName));
    169                 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
    170                 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
    171                 reqFTP.UseBinary = true;
    172                 reqFTP.UsePassive = true;
    173                 reqFTP.Proxy = null;
    174                 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
    175                 Stream ftpStream = response.GetResponseStream();
    176                 long cl = response.ContentLength;
    177                 int bufferSize = 2048;
    178                 int readCount;
    179                 byte[] buffer = new byte[bufferSize];
    180                 readCount = ftpStream.Read(buffer, 0, bufferSize);
    181                 while (readCount > 0)
    182                 {
    183                     outputStream.Write(buffer, 0, readCount);
    184                     readCount = ftpStream.Read(buffer, 0, bufferSize);
    185                 }
    186                 ftpStream.Close();
    187                 outputStream.Close();
    188                 response.Close();
    189             }
    190             catch (Exception ex)
    191             {
    192                 //记录日志
    193                 Common.LogHelper.WriteLog("文件下载异常:" + ex.Message);
    194             }
    195         }
    196         /// <summary>
    197         /// 删除文件
    198         /// </summary>
    199         /// <param name="strFileName">文件名</param>
    200         public void Delete(string strFileName)
    201         {
    202             try
    203             {
    204                 FtpWebRequest reqFTP;
    205                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFileName));
    206                 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
    207                 reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
    208                 reqFTP.KeepAlive = false;
    209                 string result = String.Empty;
    210                 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
    211                 long size = response.ContentLength;
    212                 Stream datastream = response.GetResponseStream();
    213                 StreamReader sr = new StreamReader(datastream);
    214                 result = sr.ReadToEnd();
    215                 sr.Close();
    216                 datastream.Close();
    217                 response.Close();
    218             }
    219             catch (Exception ex)
    220             {
    221                 throw new Exception(ex.Message);
    222             }
    223         }
    224 
    225         /// <summary>
    226         /// 获取当前目录下明细(包含文件和文件夹)  
    227         /// </summary>
    228         /// <returns></returns>
    229         public string[] GetFilesDetailList()
    230         {
    231             try
    232             {
    233                 StringBuilder result = new StringBuilder();
    234                 FtpWebRequest ftp;
    235                 ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI));
    236                 ftp.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
    237                 ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    238                 WebResponse response = ftp.GetResponse();
    239                 StreamReader reader = new StreamReader(response.GetResponseStream());
    240                 string line = reader.ReadLine();
    241                 line = reader.ReadLine();
    242                 line = reader.ReadLine();
    243                 while (line != null)
    244                 {
    245                     result.Append(line);
    246                     result.Append("
    ");
    247                     line = reader.ReadLine();
    248                 }
    249                 result.Remove(result.ToString().LastIndexOf("
    "), 1);
    250                 reader.Close();
    251                 response.Close();
    252                 return result.ToString().Split('
    ');
    253             }
    254             catch (Exception ex)
    255             {
    256                 throw new Exception(ex.Message);
    257             }
    258         }
    259 
    260         /// <summary>
    261         ///  获取FTP文件列表(包括文件夹)
    262         /// </summary>
    263         /// <param name="strUrl"></param>
    264         /// <returns></returns>
    265         private string[] GetAllList(string strUrl)
    266         {
    267             List<string> list = new List<string>();
    268             FtpWebRequest req = (FtpWebRequest)WebRequest.Create(new Uri(strUrl));
    269             req.Credentials = new NetworkCredential(strFtpPassword, strFtpPassword);
    270             req.Method = WebRequestMethods.Ftp.ListDirectory;
    271             req.UseBinary = true;
    272             req.UsePassive = true;
    273             try
    274             {
    275                 using (FtpWebResponse res = (FtpWebResponse)req.GetResponse())
    276                 {
    277                     using (StreamReader sr = new StreamReader(res.GetResponseStream()))
    278                     {
    279                         string s;
    280                         while ((s = sr.ReadLine()) != null)
    281                         {
    282                             list.Add(s);
    283                         }
    284                     }
    285                 }
    286             }
    287             catch (Exception ex)
    288             {
    289                 throw (ex);
    290             }
    291             return list.ToArray();
    292         }
    293 
    294         /// <summary>  
    295         /// 获取当前目录下文件列表(不包括文件夹)  
    296         /// </summary>  
    297         public string[] GetFileList(string strUrl)
    298         {
    299             StringBuilder result = new StringBuilder();
    300             FtpWebRequest reqFTP;
    301             try
    302             {
    303                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strUrl));
    304                 reqFTP.UseBinary = true;
    305                 reqFTP.Credentials = new NetworkCredential(strFtpPassword, strFtpPassword);
    306                 reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    307                 WebResponse response = reqFTP.GetResponse();
    308                 StreamReader reader = new StreamReader(response.GetResponseStream());
    309                 string line = reader.ReadLine();
    310                 while (line != null)
    311                 {
    312 
    313                     if (line.IndexOf("<DIR>") == -1)
    314                     {
    315                         result.Append(Regex.Match(line, @"[S]+ [S]+", RegexOptions.IgnoreCase).Value.Split(' ')[1]);
    316                         result.Append("
    ");
    317                     }
    318                     line = reader.ReadLine();
    319                 }
    320                 result.Remove(result.ToString().LastIndexOf('
    '), 1);
    321                 reader.Close();
    322                 response.Close();
    323             }
    324             catch (Exception ex)
    325             {
    326                 throw (ex);
    327             }
    328             return result.ToString().Split('
    ');
    329         }
    330 
    331         /// <summary>  
    332         /// 判断当前目录下指定的文件是否存在  
    333         /// </summary>  
    334         /// <param name="strRemoteFileName">远程文件名</param>  
    335         public bool FileExist(string strRemoteFileName)
    336         {
    337             string[] fileList = GetFileList("*.*");
    338             foreach (string str in fileList)
    339             {
    340                 if (str.Trim() == strRemoteFileName.Trim())
    341                 {
    342                     return true;
    343                 }
    344             }
    345             return false;
    346         }
    347 
    348         /// <summary>
    349         /// 创建文件夹  
    350         /// </summary>
    351         /// <param name="strDirName">目录名</param>
    352         public void MakeDir(string strDirName)
    353         {
    354             FtpWebRequest reqFTP;
    355             try
    356             {
    357                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strDirName));
    358                 reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
    359                 reqFTP.UseBinary = true;
    360                 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
    361                 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
    362                 Stream ftpStream = response.GetResponseStream();
    363                 ftpStream.Close();
    364                 response.Close();
    365             }
    366             catch (Exception ex)
    367             { Common.LogHelper.WriteLog("ftp服务器创建目录异常:" + ex.Message); }
    368         }
    369 
    370         /// <summary>  
    371         /// 获取指定文件大小  
    372         /// </summary>  
    373         public long GetFileSize(string strFilename)
    374         {
    375             FtpWebRequest reqFTP;
    376             long fileSize = 0;
    377             try
    378             {
    379                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFilename));
    380                 reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
    381                 reqFTP.UseBinary = true;
    382                 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
    383                 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
    384                 Stream ftpStream = response.GetResponseStream();
    385                 fileSize = response.ContentLength;
    386                 ftpStream.Close();
    387                 response.Close();
    388             }
    389             catch (Exception ex)
    390             { throw ex; }
    391             return fileSize;
    392         }
    393 
    394         /// <summary>  
    395         /// 更改文件名  
    396         /// </summary> 
    397         public void ReName(string strCurrentFilename, string strNewFilename)
    398         {
    399             FtpWebRequest reqFTP;
    400             try
    401             {
    402                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strCurrentFilename));
    403                 reqFTP.Method = WebRequestMethods.Ftp.Rename;
    404                 reqFTP.RenameTo = strNewFilename;
    405                 reqFTP.UseBinary = true;
    406                 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword);
    407                 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
    408                 Stream ftpStream = response.GetResponseStream();
    409                 ftpStream.Close();
    410                 response.Close();
    411             }
    412             catch (Exception ex)
    413             { throw ex; }
    414         }
    415 
    416         /// <summary>  
    417         /// 移动文件  
    418         /// </summary>  
    419         public void MovieFile(string strCurrentFilename, string strNewDirectory)
    420         {
    421             ReName(strCurrentFilename, strNewDirectory);
    422         }
    423 
    424         /// <summary>  
    425         /// 切换当前目录  
    426         /// </summary>  
    427         /// <param name="bIsRoot">true:绝对路径 false:相对路径</param>   
    428         public void GotoDirectory(string strDirectoryName, bool bIsRoot)
    429         {
    430             if (bIsRoot)
    431             {
    432                 strFtpRemotePath = strDirectoryName;
    433             }
    434             else
    435             {
    436                 strFtpRemotePath += strDirectoryName + "/";
    437             }
    438             strFtpURI = "ftp://" + strFtpServerIP + "/" + strFtpRemotePath + "/";
    439         }
    440     }
    FTPHelper

    Windows服务轮询

    代码很简单,这里说明一下需要注意的地方,由于要调用c++动态链接库,并不是所有的异常信息都能catch到,所以在遇到bug的时候,比如dwg文件错误,就会造成服务停止,为了不让用户手动进入服务器进行手动启用,弄了一个exe程序,监听该服务是否启用,如果停用了,隔一段时间进行再次启用。

    总结

    由于该项目,客户只有管理员一个人使用,所以对项目的要求并不高,便宜我了,通过该项目,学到很多东西,之前也就负责功能模块,很没意思,不过这种从前端,到后台到数据库,都是自己弄的还是很有成就感的。

    下周要去给客户部署了,最近一直在测试,一直在优化代码,轮询这块本来就是很费性能的,所以能想到的优化都用上了。

    项目很小,也没什么要求只要能实现就可以,所以就随意发挥了。就当练练手了。

  • 相关阅读:
    【sqli-labs】 less23 Error based
    【sqli-labs】 less22 Cookie Injection- Error Based- Double Quotes
    【sqli-labs】 less21 Cookie Injection- Error Based- complex
    【sqli-labs】 less20 POST
    【sqli-labs】 less19 POST
    【sqli-labs】 less18 POST
    【sqli-labs】 less17 POST
    【sqli-labs】 less16 POST
    【sqli-labs】 less15 POST
    nginx.conf(centos7 1.14)主配置文件修改
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/3778594.html
Copyright © 2011-2022 走看看