Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 天堂中文字幕在线观看,成人18在线视频播放,国产精品综合久成人

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          ASP.NET MVC知識(shí)盤點(diǎn):驗(yàn)證、授權(quán)與安全

          ASP.NET MVC知識(shí)盤點(diǎn):驗(yàn)證、授權(quán)與安全

          驗(yàn)證

          一般采用表單驗(yàn)證完成登陸驗(yàn)證,建議結(jié)合SSL使用。為限制控制器只能執(zhí)行HTTPS,使用RequireHttpsAttribute

          2 授權(quán)

          對賬戶的權(quán)限的控制可以通過在控制器或控制器操作上加AuthorizeAttribute 屬性。

          擴(kuò)展授權(quán)過濾器

          擴(kuò)展授權(quán)過濾器可以定義繼承自AuthorizeAttribute的類,也可以定義同時(shí)繼承自FilterAttribute, IAuthorizationFilter接口的類。

          擴(kuò)展AuthorizeAttribute

           [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited=true, AllowMultiple=true)]
           public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
           {
           public AuthorizeAttribute(); 
           
           // 獲取或設(shè)置有權(quán)訪問控制器或操作方法的用戶角色
           public string Roles { get; set; }
           
           //獲取此特性的唯一標(biāo)識(shí)符。
           public override object TypeId { get; }
           
           // 獲取或設(shè)置有權(quán)訪問控制器或操作方法的用戶。
           public string Users { get; set; }
           
           //重寫時(shí),提供一個(gè)入口點(diǎn)用于進(jìn)行自定義授權(quán)檢查
           // 返回結(jié)果: 
           // 如果用戶已經(jīng)過授權(quán),則為 true;否則為 false。
           // 異常: 
           // System.ArgumentNullException:
           // httpContext 參數(shù)為 null。
           protected virtual bool AuthorizeCore(HttpContextBase httpContext);
           
           //處理未能授權(quán)的 HTTP 請求。
           protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext);
           
           //在過程請求授權(quán)時(shí)調(diào)用。
           // 異常: 
           // System.ArgumentNullException:
           // filterContext 參數(shù)為 null。
           public virtual void OnAuthorization(AuthorizationContext filterContext);
           
           //
           // 返回結(jié)果: 
           // 對驗(yàn)證狀態(tài)的引用。
           //
           // 異常: 
           // System.ArgumentNullException:
           // httpContext 參數(shù)為 null。
           protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
          	}
          

          AuthorizeAttribute提供了三個(gè)可重新的虛方法AuthorizeCore,HandleUnauthorizedRequest,OnAuthorization,那么在執(zhí)行授權(quán)動(dòng)作的過程中他們是如何被調(diào)用的呢?

          看下源碼的OnAuthorization方法,發(fā)現(xiàn)在這個(gè)方法中先調(diào)用AuthorizeCore,然后調(diào)用HandleUnauthorizedRequest被調(diào)用了。

          public virtual void OnAuthorization(AuthorizationContext filterContext)
           {
           if (filterContext==null)
           {
           throw new ArgumentNullException("filterContext");
           }
          //如果子操作的緩存處于活動(dòng)狀態(tài),那么就拋出異常
           if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
           {
           throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
           }
          

          //判斷控制器或控制器操作是否允許匿名訪問,如果可以就return

           bool skipAuthorization=filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);
           
           if (skipAuthorization)
           {
           return;
           }
          //進(jìn)行權(quán)限驗(yàn)證
           if (AuthorizeCore(filterContext.HttpContext))
           {
           HttpCachePolicyBase cachePolicy=filterContext.HttpContext.Response.Cache;
           cachePolicy.SetProxyMaxAge(new TimeSpan(0));
           cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
           }
           else
           {//處理未通過權(quán)限驗(yàn)證的情形
           HandleUnauthorizedRequest(filterContext);
           }
           }
          

          綜合以上分析,擴(kuò)展AuthorizeAttribute要注意:

          1)在子類AuthorizeCore中,調(diào)用父類的AuthorizeCore方法

          base.OnAuthorization(filterContext);

          2)在子類的AuthorizeCore方法中驗(yàn)證用戶的權(quán)限。

          3)通過子類的構(gòu)造函數(shù)傳入用戶的權(quán)限值

          代碼示例如下:

          public class CustomAuthorizeAttribute : AuthorizeAttribute
           {
           private UserRole role;
           public CustomAuthorizeAttribute(UserRole role)
           {
           this.role=role;
           }
           protected override bool AuthorizeCore(HttpContextBase httpContext)
           {
           bool ret=false;
           
           //獲得用戶信息(從本地Session或分布式緩存中獲取)
           var userInfo=......
           if(userInfo==null)
           {
           //信息為null,一般認(rèn)為登陸超時(shí)或沒有登陸
           }
           
           if(userInfo.Role==UserRole.Org)
           {
           ret=true;
           }
           else
           {
           //提示無權(quán)限
           }
           
           return ret;
           }
           protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
           {
           if (filterContext==null)
           {
           throw new ArgumentNullException("filterContext");
           }
           
           if (filterContext.HttpContext.Request.IsAjaxRequest())
           {//針對ajax請求進(jìn)行處理
           
           }
           else
           {//非aiax進(jìn)行處理
           
           //跳轉(zhuǎn)到指定頁面
           string strUrl=......;
           filterContext.Result=new RedirectResult(strUrl);
           }
           }
           public override void OnAuthorization(AuthorizationContext filterContext)
           {
           base.OnAuthorization(filterContext);
           }
           }
           public enum UserRole
           {
           Org=1,
           Vip=2,
           Guest=3
          	}
          

          3 安全

          總的原則:

          • 所有層或各個(gè)子系統(tǒng)各自負(fù)責(zé)好自己的安全。
          • 任何用戶數(shù)據(jù)和來自其他系統(tǒng)的數(shù)據(jù)都要經(jīng)過檢驗(yàn)。
          • 在滿足需求的情況下,盡量縮小賬戶的權(quán)限。
          • 減少暴露的操作數(shù)量和操作參數(shù)。
          • 關(guān)閉服務(wù)器不需要的功能。

          4 防范攻擊

          4.1跨站腳本攻擊(XSS)

          被動(dòng)注入:用戶的輸入含有惡意腳本,而網(wǎng)站又能夠不加檢驗(yàn)地接受這樣的輸入,進(jìn)而保存到數(shù)據(jù)庫中。

          主動(dòng)注入:用戶將含有惡意腳本的內(nèi)容輸入到頁面文本框中,然后在屏幕上顯示出來。

          防御方法:

          1)使用Razor語法輸出的內(nèi)容已經(jīng)被編碼,可以不做任何其他處理

          例如:

          <h4>@Model.Field</h4>
          

          Html.ActionLink,Html.Action等方法會(huì)將路由參數(shù)編碼輸出

          2)大部分的XSS攻擊可通過對輸入內(nèi)容進(jìn)行編碼來阻止:Html.Encode,Html.AttributeEncode,Url.Encode

          3)對Js進(jìn)行編碼

          使用Ajax.JavaScriptStringEncode

          4)將AntiXSS庫作為默認(rèn)的編碼器(不建議使用,不靈活)

          ASP.NET 4.5 集成Anti-XSS Library,可以通過配置來對整個(gè)網(wǎng)站的輸出進(jìn)行編碼。

          <system.web>
           <httpRuntime targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder,System.Web"/>
           </system.web> 
          

          4.2跨站請求偽造(CSRF/XSRF)

          防御方法:

          1)使用Html隱藏域存儲(chǔ)用戶令牌,令牌可以存儲(chǔ)在Session里或者cookie里

          2)在視圖表單中使用@Html.AntiForgeryToken(),在控制器操作上添加屬性[ValidateAntiForgeryToken],注意表單一定要使用@Html.BeginForm生成

          實(shí)現(xiàn)機(jī)制:AntiForgeryToken方法向用戶瀏覽器cookie中寫入一個(gè)加密的數(shù)據(jù),并在表單內(nèi)插入一個(gè)隱藏欄位,每次刷新頁面時(shí)隱藏欄位的值都不同,每次執(zhí)行控制器操作前,都會(huì)驗(yàn)證隱藏欄位和瀏覽器cookie中的值是否相同,只有相同才允許執(zhí)行控制器操作。

          使用限制:

          • 客戶端瀏覽器不能禁用cookie
          • 只對post請求有效
          • 若有XSS漏洞,則可輕易獲取令牌
          • 對Ajax請求不能傳遞令牌,即對Ajax無效

          3)使用冪等的Get請求,僅使用Post請求修改數(shù)據(jù)(僅僅是一定程度上限制這種攻擊而已)

          4)使用動(dòng)作過濾器,驗(yàn)證UrlReferrer

          擴(kuò)展的動(dòng)作過濾器:

          public class CSRFFilter:AuthorizeAttribute
           {
           public override void OnAuthorization(AuthorizationContext filterContext)
           {
           if (filterContext.HttpContext==null)
           {
           throw new HttpException("請求無效");
           }
           
           if (filterContext.HttpContext.Request.UrlReferrer==null)
           {
           throw new HttpException("請求無效");
           }
           
           if (filterContext.HttpContext.Request.UrlReferrer.Host !="sit.com")
           {
           throw new HttpException("來自非法網(wǎng)站");
           }
           }
          	}
          

          4.3 cookie盜竊

          cookie有兩種形式

          1)會(huì)話cookie:存儲(chǔ)在瀏覽器內(nèi)存中,瀏覽器每次請求通過Http頭進(jìn)行傳遞

          2)持久性cookie:存儲(chǔ)在硬盤上,同樣通過Http頭進(jìn)行傳遞

          二者的區(qū)別:會(huì)話cookie常在會(huì)話結(jié)束時(shí)失效,而持久性cookie在下一次訪問站點(diǎn)時(shí)仍然有效。

          被竊取的原因:依賴于XSS漏洞,注入一段惡意腳本就能竊取。

          防御方法:

          1)在web.config對cookie進(jìn)行設(shè)置

          <httpCookies httpOnlyCookies="true"/>,httpOnlyCookies指定為true表達(dá)僅服務(wù)器可以訪問,瀏覽器無法訪問

          2)在編寫代碼時(shí)為每個(gè)cookie單獨(dú)設(shè)置

          Response.Cookies["cok"].Value=Guid.NewGuid().ToString();

          Response.Cookies["cok"].HttpOnly=true;

          4.4重復(fù)提交

          防御方法:

          1)使用bind特性,設(shè)置想要綁定的屬性來,防止這種攻擊。也可以設(shè)置不要綁定的字屬性,但優(yōu)先選擇設(shè)置要綁定的屬性。

          例:

          可以指定多個(gè)字段,用逗號(hào)分隔

          public ActionResult TestViewData([Bind(Include="Field,Field1,Field1")]ModelF mf)
          {
          	......
          }
          

          2)使用UpdateModel或TryUpdateModel

          3)使用ViewModel,明確規(guī)定View使用的數(shù)據(jù)模型

          4.5開放重定向

          防御方法:

          使用Url.IsLocalUrl檢測是否為本地url

          4.6 SQL注入攻擊

          防御方法:

          通過參數(shù)注入非法獲得或修改網(wǎng)站數(shù)據(jù)。

          使用參數(shù)化查詢來防止SQL注入攻擊。

          這篇文章中,Web開發(fā)人員和DZone MVB介紹了如何通過驗(yàn)證數(shù)組來啟用和禁用一組元素的技術(shù)。

          今天,我們介紹如何通過驗(yàn)證數(shù)組來啟用和禁用一組元素的技術(shù)。

          當(dāng)涉及到前端的復(fù)雜業(yè)務(wù)邏輯時(shí),Web應(yīng)用程序變得越來越難以編寫。

          根據(jù)復(fù)雜性,可能需要您在提交之前接受一組輸入并驗(yàn)證這些元素。

          我提交的最近一個(gè)屏幕需要多個(gè)DOM元素在啟用提交或“操作”按鈕之前處于特定狀態(tài)。

          當(dāng)一組DOM元素處于特定狀態(tài)時(shí),我們希望觸發(fā)其他元素。

          我知道你在想什么。為什么不使用jQuery進(jìn)行驗(yàn)證?

          原因如下:

          1. 對于這個(gè)任務(wù),我們需要jQuery和不顯眼的驗(yàn)證庫。這是我們真正不需要的兩個(gè)大型圖書館。

          2. 借助最新的JavaScript特性,您會(huì)驚訝于瀏覽器中已有多少功能,以及您甚至可能不再需要jQuery。

          3. 我想要一個(gè)快速和整潔的解決方案來解決這個(gè)問題。

          據(jù)說,我著手尋找一種更簡單的方式來有條件地驗(yàn)證DOM元素組。

          一個(gè)簡單的例子

          讓我們用一個(gè)網(wǎng)格來設(shè)置一個(gè)簡單的場景。

          Views/Home/Index.cshtml

          @model EventViewModel

          @{

          ViewData["Title"]="Grouped Validations";

          }

          <style>

          th:nth-child(1) {

          width: 20px

          }

          </style>

          <h2>Events</h2>

          @using (Html.BeginForm())

          {

          <div class="btn-toolbar mb-3" role="toolbar" aria-label="Toolbar with button groups">

          <div class="btn-group mr-2" role="group" aria-label="First group">

          <button id="enabled-button" type="button" disabled="disabled" class="btn btn-info disabled">Enable</button>

          <button id="disabled-button" type="button" disabled="disabled" class="btn btn-info disabled">Disable</button>

          </div>

          </div>

          <table class="table table-condensed table-bordered table-striped">

          <thead>

          <tr>

          <th><input type="checkbox" id="select-all" /></th>

          <th>Event</th>

          <th>Begin Date</th>

          <th>End Date</th>

          </tr>

          </thead>

          <tbody>

          @foreach (var eventModel in Model.Events)

          {

          <tr>

          <td><input name="select" class="event-checkbox" type="checkbox" value="@eventModel.EventId" /></td>

          <td><a title="Go to @eventModel.Title" href="@eventModel.Url.AbsoluteUri">@eventModel.Title</a></td>

          <td>@eventModel.BeginDate.ToShortDateString()</td>

          <td>@eventModel.EndDate.ToShortDateString()</td>

          </tr>

          }

          </tbody>

          </table>

          }

          這個(gè)網(wǎng)格在左邊有復(fù)選框,帶有批按鈕來啟用和禁用事件。點(diǎn)擊標(biāo)題中的復(fù)選框?qū)⑦x擇所有這些選項(xiàng)。

          首先,我們需要受用戶操作影響的元素。

          this.enabledButton=document.getElementById("enabled-button");

          this.disabledButton=document.getElementById("disabled-button");

          接下來,我們需要我們的驗(yàn)證。這些驗(yàn)證存儲(chǔ)在包含以下項(xiàng)目的數(shù)組中:

          1. 要啟用/禁用的元素。

          2. 一個(gè)簡單的條件。

          3. 條件為真時(shí)的lambda。

          4. 條件為false時(shí)的lambda。

          我們的驗(yàn)證數(shù)組看起來像這樣:

          // Custom validations for enabling/disabling DOM elements based on conditions.

          this.validations=[

          {

          // When should the enable button be active?

          element: this.enabledButton,

          condition: ()=> {

          var checkedCheckboxes=areChecked();

          var valid=(

          // Do we have even one checkbox selected?

          checkedCheckboxes.length > 0

          );

          return valid;

          },

          trueAction: (elem)=> {

          elem.removeAttribute("disabled");

          elem.classList.remove("disabled");

          },

          falseAction: (elem)=> {

          elem.setAttribute("disabled", "disabled");

          elem.classList.add("disabled");

          }

          },

          // Second validation

          {

          // When should the disable button be active?

          element: this.disabledButton,

          condition: ()=> {

          var checkedCheckboxes=areChecked();

          var valid=(

          // No checkboxes are available, time to disable.

          checkedCheckboxes.length > 0

          );

          return valid;

          },

          trueAction: (elem)=> {

          elem.removeAttribute("disabled");

          elem.classList.remove("disabled");

          },

          falseAction: (elem)=> {

          elem.setAttribute("disabled", "disabled");

          elem.classList.add("disabled");

          }

          }

          ];

          我們基本上建立了一個(gè)“編碼陣列”。這個(gè)數(shù)組擁有我們編寫數(shù)據(jù)驅(qū)動(dòng)代碼所需的一切。

          如果您發(fā)現(xiàn) trueAction并且 falseAction,我們正在建立的拉姆達(dá)接收的元素。一旦我們收到元素,我們就會(huì)將某些屬性應(yīng)用到DOM元素,當(dāng)它是真或假操作時(shí)。

          我們的條件可以像我們需要的那樣復(fù)雜,以啟用或禁用某些DOM元素。

          啟用/禁用元素

          為了使我們的DOM元素可用或禁用,我們需要遍歷我們的驗(yàn)證并對其執(zhí)行操作; 所以,我們將使用該 map功能。

          function updateValidations() {

          Array.from(validations).map( (item, index, array)=> {

          if (item.condition()) {

          item.trueAction(item.element);

          } else {

          item.falseAction(item.element);

          }

          });

          }

          一旦我們有我們的功能來啟用或禁用DOM元素,我們需要將我們的事件附加到復(fù)選框。

          // Set the "select all" checkbox.

          var checkAll=document.getElementById("select-all");

          checkAll.addEventListener("change", checkAllCheckbox);

          我們的變化事件 checkAllCheckbox當(dāng)然會(huì)稱為我們的 updateValidations();功能。

          function checkAllCheckbox() {

          var allCheckbox=document.getElementById("select-all");

          var eventCheckboxes=Array.from(

          document.getElementsByClassName("event-checkbox")

          );

          eventCheckboxes.map( (elem, index, array)=> {

          elem.checked=allCheckbox.checked;

          });

          updateValidations();

          }

          所有這些都不使用jQuery或驗(yàn)證庫。

          瀏覽器阻斷

          當(dāng)然,總會(huì)遇到一些......呃......某些瀏覽器。

          一些用戶報(bào)告了復(fù)選框單擊不與其他復(fù)選框一起工作的問題。

          我想知道=>舊版瀏覽器的arrow()語法。

          所以我去了caniuse.com以確認(rèn)這是否可以與其他瀏覽器一起使用。

          你不知道嗎?我去了箭頭語法,發(fā)現(xiàn)這個(gè):caniuse.com/#search=arrow

          由于我們不能使用箭頭語法,所以修復(fù)非常簡單。

          而不是這樣做:

          {

          // When should the enable button be active?

          element: this.enabledButton,

          condition: ()=> {

          var checkedCheckboxes=areChecked();

          var valid=(

          // Do we have even one checkbox selected?

          checkedCheckboxes.length > 0

          );

          return valid;

          },

          trueAction: (elem)=> {

          elem.removeAttribute("disabled");

          elem.classList.remove("disabled");

          },

          falseAction: (elem)=> {

          elem.setAttribute("disabled", "disabled");

          elem.classList.add("disabled");

          }

          },

          我們做得到:

          {

          // When should the enable button be active?

          element: this.enabledButton,

          condition: function () {

          var checkedCheckboxes=areChecked();

          var valid=(

          // Do we have even one checkbox selected?

          checkedCheckboxes.length > 0

          );

          return valid;

          },

          trueAction: function (elem) {

          elem.removeAttribute("disabled");

          elem.classList.remove("disabled");

          },

          falseAction: function (elem) {

          elem.setAttribute("disabled", "disabled");

          elem.classList.add("disabled");

          }

          },

          請記住,拉姆達(dá)只是匿名代表。用一個(gè)簡單的函數(shù)替換箭頭語法可以實(shí)現(xiàn)向后兼容性的奇跡。

          對于項(xiàng)目來源,請查看我的GitHub存儲(chǔ)庫。

          結(jié)論

          一旦建立起來,我就可以在多個(gè)頁面上使用這個(gè)功能,以便“引導(dǎo)”用戶在屏幕上可以或不可以執(zhí)行的操作。當(dāng)一個(gè)DOM元素被啟用時(shí),它觸發(fā)另外兩個(gè)元素供用戶在屏幕上進(jìn)行交互。

          這可以很容易地修改為使用提交按鈕。如果滿足所有這些條件,請啟用提交按鈕。如果不是,則禁用它直到滿足所有條件。

          再次,您可以根據(jù)需要將其設(shè)置為復(fù)雜或簡單。

          、點(diǎn)擊引用右鍵,管理NuGet程序包,輸入NPIO,選擇紅框選中的下載

          2、創(chuàng)建一個(gè) ExcelController 控制器,將Index 方法生成視圖

          3、批量導(dǎo)入excel的頁面源碼:

          <h2>批量導(dǎo)入excel</h2>

          <div>

          @using (Html.BeginForm("Import", "Excel", FormMethod.Post, new { enctype="multipart/form-data" }))

          {

          <input name="files" type="file" multiple="multiple" id="=file" />

          <br />

          <br />

          <input name="submit" id="submit" type="submit" value="批量導(dǎo)入" />

          }

          </div>

          這里需要注意:file 的multiple屬性是能多個(gè)文件選中,enctype="multipart/form-data" 是上傳必須的表單屬性

          4、在ExcelController 控制器里面添加方法

          [HttpPost]

          public ActionResult Import(IEnumerable<HttpPostedFileBase> files)

          {

          // var fileName=file.FileName;

          var filePath=Server.MapPath(string.Format("~/{0}", "Files"));


          foreach (var file in files)

          {

          if (file !=null && file.ContentLength > 0)

          {

          var path=Path.Combine(filePath, file.FileName);

          file.SaveAs(path);

          DataTable excelTable=new DataTable();

          excelTable=ImportExcel.GetExcelDataTable(path);

          DataTable dbdata=new DataTable();

          dbdata.Columns.Add("ids");

          dbdata.Columns.Add("users");

          dbdata.Columns.Add("area");

          dbdata.Columns.Add("school");

          dbdata.Columns.Add("classes");

          dbdata.Columns.Add("name");

          dbdata.Columns.Add("phone");

          dbdata.Columns.Add("integration");

          dbdata.Columns.Add("states");

          dbdata.Columns.Add("createDate");

          dbdata.Columns.Add("refreshDate");

          for (int i=0; i < excelTable.Rows.Count; i++)

          {

          DataRow dr=excelTable.Rows[i];

          DataRow dr_=dbdata.NewRow();

          dr_["ids"]=dr["ID"];

          dr_["users"]=dr["用戶"];

          dr_["area"]=dr["區(qū)域"];

          dr_["school"]=dr["學(xué)校"];

          dr_["classes"]=dr["班級(jí)"];

          dr_["name"]=dr["姓名"];

          dr_["phone"]=dr["手機(jī)"];

          dr_["integration"]=dr["積分"];

          dr_["states"]=dr["狀態(tài)"];

          dr_["createDate"]=dr["創(chuàng)建時(shí)間"];

          dr_["refreshDate"]=dr["更新時(shí)間"];

          dbdata.Rows.Add(dr_);

          }

          RemoveEmpty(dbdata);

          string constr=System.Configuration.ConfigurationManager.AppSettings["cool"];

          SqlBulkCopyByDatatable(constr, "student", dbdata);

          }

          }


          return RedirectToAction("Index", "DataRefsh");

          }

          /// <summary>

          /// 大數(shù)據(jù)插入

          /// </summary>

          /// <param name="connectionString">目標(biāo)庫連接</param>

          /// <param name="TableName">目標(biāo)表</param>

          /// <param name="dtSelect">來源數(shù)據(jù)</param>

          public static void SqlBulkCopyByDatatable(string connectionString, string TableName, DataTable dtSelect)

          {

          using (SqlConnection conn=new SqlConnection(connectionString))

          {

          using (SqlBulkCopy sqlbulkcopy=new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction))

          {

          try

          {

          sqlbulkcopy.DestinationTableName=TableName;

          sqlbulkcopy.BatchSize=20000;

          sqlbulkcopy.BulkCopyTimeout=0;//不限時(shí)間

          for (int i=0; i < dtSelect.Columns.Count; i++)

          {

          sqlbulkcopy.ColumnMappings.Add(dtSelect.Columns[i].ColumnName, dtSelect.Columns[i].ColumnName);

          }

          sqlbulkcopy.WriteToServer(dtSelect);

          }

          catch (System.Exception ex)

          {

          throw ex;

          }

          }

          }

          }

          protected void RemoveEmpty(DataTable dt)

          {

          List<DataRow> removelist=new List<DataRow>();

          for (int i=0; i < dt.Rows.Count; i++)

          {

          bool IsNull=true;

          for (int j=0; j < dt.Columns.Count; j++)

          {

          if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim()))

          {

          IsNull=false;

          }

          }

          if (IsNull)

          {

          removelist.Add(dt.Rows[i]);

          }

          }

          for (int i=0; i < removelist.Count; i++)

          {

          dt.Rows.Remove(removelist[i]);

          }

          }

          這里需要注意:IEnumerable<HttpPostedFileBase> 是讀取多個(gè)文件的名稱,HttpPostedFileBase只能讀取一個(gè),還有就是files 是file 控件name 相對應(yīng)的

          5、string constr=System.Configuration.ConfigurationManager.AppSettings["cool"]; 需要在web.config 里面的appSettings 里面添加數(shù)據(jù)庫連接字符串的配置

          6、控制器import 方法里面有用到GetExcelDataTable 和GetCellValue 方法

          這里創(chuàng)建一個(gè)ImportExcel 類,創(chuàng)建以下兩個(gè)方法

          using System;

          using System.Collections.Generic;

          using System.Linq;

          using System.Web;

          using NPOI;

          using System.Data;

          using NPOI.SS.UserModel;

          using NPOI.HSSF.UserModel;

          using NPOI.XSSF.UserModel;

          using System.IO;

          namespace Cool{

          public class ImportExcel

          {

          public static DataTable GetExcelDataTable(string filePath)

          {

          IWorkbook Workbook;

          DataTable table=new DataTable();

          try

          {

          using (FileStream fileStream=new FileStream(filePath, FileMode.Open, FileAccess.Read))

          {

          //XSSFWorkbook 使用XLSX格式,HSSFWorkbook 使用XLS格式

          string fileExt=Path.GetExtension(filePath).ToLower();

          if (fileExt==".xls")

          {

          Workbook=new HSSFWorkbook(fileStream);

          }

          else if (fileExt==".xlsx")

          {

          Workbook=new XSSFWorkbook(fileStream);

          }

          else

          {

          Workbook=null;

          }

          }

          }

          catch (Exception ex)

          {

          throw ex;

          }

          //定位在第一個(gè)sheet

          ISheet sheet=Workbook.GetSheetAt(0);

          //第一行為標(biāo)題行

          IRow headerRow=sheet.GetRow(0);

          int cellCount=headerRow.LastCellNum;

          int rowCount=sheet.LastRowNum;

          //循環(huán)添加標(biāo)題列

          for (int i=headerRow.FirstCellNum; i < cellCount; i++)

          {

          DataColumn column=new DataColumn(headerRow.GetCell(i).StringCellValue);

          table.Columns.Add(column);

          }

          //數(shù)據(jù)

          for (int i=(sheet.FirstRowNum + 1); i <=rowCount; i++)

          {

          IRow row=sheet.GetRow(i);

          DataRow dataRow=table.NewRow();

          if (row !=null)

          {

          for (int j=row.FirstCellNum; j < cellCount; j++)

          {

          if (row.GetCell(j) !=null)

          {

          dataRow[j]=GetCellValue(row.GetCell(j));

          }

          }

          }

          table.Rows.Add(dataRow);

          }

          return table;

          }

          private static string GetCellValue(ICell cell)

          {

          if (cell==null)

          {

          return string.Empty;

          }

          switch (cell.CellType)

          {

          case CellType.Blank:

          return string.Empty;

          case CellType.Boolean:

          return cell.BooleanCellValue.ToString();

          case CellType.Error:

          return cell.ErrorCellValue.ToString();

          case CellType.Numeric:

          case CellType.Unknown:

          default:

          return cell.ToString();

          case CellType.String:

          return cell.StringCellValue;

          case CellType.Formula:

          try

          {

          HSSFFormulaEvaluator e=new HSSFFormulaEvaluator(cell.Sheet.Workbook);

          e.EvaluateInCell(cell);

          return cell.ToString();

          }

          catch

          {

          return cell.NumericCellValue.ToString();

          }

          }

          }

          }}

          這里需要注意:NPOI 只支持93-2007的offcie 的excel文件,如果是高版本的excel文件,需要降級(jí),打開excel文件,另存為93-2007 的.xls 文件即可


          這樣就可以批量把文件數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫中了!!!


          主站蜘蛛池模板: 亚洲一区二区三区深夜天堂| 欧洲精品码一区二区三区免费看 | 夜夜爽一区二区三区精品| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 国产亚洲综合一区二区三区 | 精品一区二区三区在线观看l| 国产精品乱码一区二区三区| 亚洲日韩AV无码一区二区三区人| 久久国产午夜一区二区福利 | 精品国产福利在线观看一区| 人妻体体内射精一区二区| 久久影院亚洲一区| 国产情侣一区二区三区| 卡通动漫中文字幕第一区| 精品日韩一区二区三区视频| 麻豆AV无码精品一区二区 | 久久无码人妻一区二区三区午夜| 国产亚洲情侣一区二区无| 东京热无码一区二区三区av | 国产乱人伦精品一区二区在线观看 | 日韩在线不卡免费视频一区| 日本一区精品久久久久影院| a级午夜毛片免费一区二区| 日韩人妻无码一区二区三区久久99| 精品人妻一区二区三区四区| 无码人妻精品一区二| 视频一区二区在线播放| asmr国产一区在线| 久久国产高清一区二区三区| 成人免费av一区二区三区| 亚洲一区二区三区偷拍女厕| 国产在线一区二区三区| 一区二区三区在线|欧| 亚洲视频一区二区三区四区| 久热国产精品视频一区二区三区| 无码人妻精品一区二区三区9厂| 在线视频亚洲一区| 精品无码人妻一区二区三区不卡| 国产午夜精品一区二区三区漫画| 久久久国产精品亚洲一区 | 狠狠做深爱婷婷综合一区|