Ado.net 三[SQL註入,DataAdapter,sqlParameter,DataSet]

来源:http://www.cnblogs.com/wangwangwangMax/archive/2016/06/02/5551614.html
-Advertisement-
Play Games

1.SQL註入:SQL註入攻擊是web應用程式的一種安全漏洞,可以將不安全的數據提交給運用程式,使應用程式在伺服器上執行不安全的sql命令。使用該攻擊可以輕鬆的登錄運用程式。 例如:該管理員賬號密碼為xiexun,該sql的正確語句應該為: 如果在沒有做任何處理的情況下,在登錄名文本框中輸入(xux ...


1.SQL註入:SQL註入攻擊是web應用程式的一種安全漏洞,可以將不安全的數據提交給運用程式,使應用程式在伺服器上執行不安全的sql命令。使用該攻擊可以輕鬆的登錄運用程式。

   例如:該管理員賬號密碼為xiexun,該sql的正確語句應該為:

select * from Users where userName='xiexun'

   如果在沒有做任何處理的情況下,在登錄名文本框中輸入(xuxian' delete users--),單擊"登錄"按鈕之後,相當於傳了兩句sql語句,一句執行查詢之後,另外一句執行delete users之後整個表就沒數據了,這樣網站相當的不安全。

select * from Users where userName='xiexun'  delete users--sql語句的註釋,相當於把後面註釋了

 

 解決辦法:

 ①.通過@傳參的方式[存儲過程也是通過@傳參],sqlParameter方法

eg:

 public string Getswhere() 
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("select ID,username,PWD,loginname,qq,classname from Users  where 1=1");
            //獲取到它的用戶名
            string username = TxtUserName.Text.Trim();
            if (!string.IsNullOrEmpty(username))
            {
                //sb.Append(string.Format("and username='{0}'", username));
                //防SQL註入,通過@傳參的方式
                sb.Append(string.Format("and username=@username"));
                //怎麼把值傳進去,通過sqlParameter數組
                //SqlParameter[] para = new SqlParameter[]
                //{
                //    //創建一個SqlParameter對象(第一個傳名稱,第二個傳值)
                //    new SqlParameter("@username",username)
                //};
                // para[0]表示數組對象的第一個裡面添加
                //para[0] = new SqlParameter("@username",username);
para.Add(new SqlParameter("@username", username));
}
if(ddlsclass.SelectedIndex>0) { //sb.Append(string.Format("and ClassName='{0}'", ddlsclass.SelectedValue)); sb.Append(string.Format("and ClassName=@ClassName")); //para[1] = new SqlParameter("@ClassName",ddlsclass.SelectedValue);
 para.Add(new SqlParameter("@ClassName", ddlsclass.SelectedValue)); }
return sb.ToString(); }

         List<SqlParameter> para = new List<SqlParameter>();

        //我們把它放在list<>里,就有add方法

         private void openDB()
         {
          con = new SqlConnection(conStr);
          con.Open();//和資料庫建立起了連接
          //我們單獨把這兩句話封裝起來直接調用就好
         }
        //頁面一運行就執行這裡面的內容
        protected void Page_Load(object sender, EventArgs e)
        {
          BindUser();
        }

       public void BindUser()
        {
            try
            {
                openDB();
                //得到sql語句
                //string sql = "select loginid,name,loginpwd,address,ClassName,mail from Users";
                string sql = Getswhere();
                //執行sql語句
                using (cmd = new SqlCommand(sql, con))
                //對象有了,我們要通過對象去執行sql語句
                {
                    //調用它,通過遍歷加到cmd裡面去,我們把下麵的值給cmd
                    //如果它裡面有內容,我們就對它做一個迴圈
                    if (para.Count() > 0)
                    { 
                        foreach(var p in para)
                        {
                            cmd.Parameters.Add(p);
                        }
                    }
                    using (dr = cmd.ExecuteReader())
                    {
                        IdGridView.DataSource = dr;
                        IdGridView.DataBind();
                    }
                }
            }
            catch 
            {
                Response.Write("網站正在維護中.......!");
            }
        }

 這裡,我們簡單用一個圖描述一下它的運行原理:前面的是沒有通過@傳參直接通過cmd與資料庫交互的結果,不安全;後面一種是加了"Parameter"

      

   我們現在是把這個值new SqlParameter("@username",username)給sqlParameter數組,sqlparameter給cmd,cmd再執行,這樣就可以避免SQL註入。

 

2.DataAdapter數據適配器

  ①.工作原理:DataAdapter數據適配器相當於中間環節[中間人]

       

     ⅰ.前端頁面委托數據適配器去實現和資料庫的交互;

     ⅱ.資料庫交互之後,再通過資料庫適配器再把數據放記憶體里;

     ⅲ.然後我們的網頁直接對記憶體里的東西讀和寫。(讀的話可以直接讀,寫的話要再通過適配器把它加進去),這樣資料庫處於非正常連接的情況下也可以操作數據。

    而之前的寫法:

      1.前端頁面要和資料庫交互,首先要建立起連接(資料庫連接);

      2.用完之後要釋放資源

     

  最大的好處就是:沒有必要每一個頁面都要與資料庫進行連接,降低了資料庫的壓力。

  

  ②用數據適配器做一個查詢[在程式中加存儲過程]     

<div>
          <asp:GridView ID="IdGridView" runat="server" AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="id" HeaderText="ID" />
                <asp:BoundField DataField="username" HeaderText="用戶名" />
                <asp:BoundField DataField="PWD" HeaderText="密碼" />
                <asp:BoundField DataField="loginname" HeaderText="姓名" />
                <asp:BoundField DataField="qq" HeaderText="QQ" />
                <asp:BoundField DataField="classname" HeaderText="班級" />
                <asp:TemplateField HeaderText="詳情">
                    <ItemTemplate>
                        <a href="UserInfo.aspx?id=<%#Eval("ID") %>" target="_blank">詳情</a>
                        <%--<a href='UserInfo.aspx?userid=<%#Eval("UserId") %>' target="_blank">詳情</a
                       <%-- <a href="one.aspx?">詳情</a>--%>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </div>
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace _20160520
{
    public partial class egDataAp : System.Web.UI.Page
    {
        private string conStr = ConfigurationManager.ConnectionStrings["mySchool"].ToString();
        SqlConnection con = null;//相當於是電話
        SqlCommand cmd = null;//執行sql語句
        SqlDataReader dr = null;//用於儲存查詢結果
        //首先創建一個DataSet
        DataSet ds = new DataSet();
        protected void Page_Load(object sender, EventArgs e)
        {
            //用數據適配器的方式做一個查詢
             con = new SqlConnection(conStr);
            string ssql = "select ID,username,PWD,loginname,qq,classname from Users";
            using(cmd = new SqlCommand(ssql, con))
            {
                //創建一個DataAdapter,傳一個cmd
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                //應用數據適配器進行填充,填充到ds里
                da.Fill(ds);
                //指定一下數據源,.Tables[0]添加第一個table表
                //IdGridView.DataSource = ds;
                IdGridView.DataSource=ds.Tables[0];
                IdGridView.DataBind();
            }
        }
    }
}

 

  ③.DataAdapter調用存儲過程[在資料庫中加入存儲過程調用]

 private string conStr = ConfigurationManager.ConnectionStrings["mySchool"].ToString();
        SqlConnection con = null;//相當於是電話
        SqlCommand cmd = null;//執行sql語句
        SqlDataReader dr = null;//用於儲存查詢結果
        //首先創建一個DataSet
        DataSet ds = new DataSet();
        protected void Page_Load(object sender, EventArgs e)
        {
            //用數據適配器的方式做一個查詢
            con = new SqlConnection(conStr);
            //string ssql = "select ID,username,PWD,loginname,qq,classname from Users";
            //以上是之前的寫法,這裡我們直接傳一個存儲過程名
            using (cmd = new SqlCommand("procegDataAp", con))
            {
                //指定一個sqlcommand的CommandType(預設情況下等於CommandType.text)為CommandType的存儲過程名
                cmd.CommandType = CommandType.StoredProcedure;
                List<SqlParameter> para = new List<SqlParameter>() 
                {
                    //通過sqlParameter數組把它加到cmd裡面去,需指定名稱,類型,值
                    //模糊查詢
                    new SqlParameter("@UserName","%"+TxtsUserName.Text.Trim()+"%")
                };
                foreach(var a in para)
                {
                    cmd.Parameters.Add(a);
                }
                //創建一個DataAdapter,傳一個cmd
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                //應用數據適配器進行填充,填充到ds里
                da.Fill(ds);
                //指定一下數據源,.Tables[0]添加第一個table表
                //IdGridView.DataSource = ds;
                IdGridView.DataSource = ds.Tables[0];
                IdGridView.DataBind();
            }
        }

 

3.DataSet,DataTable,DataReader,DataAdapter的區別:

   ⅰ.DtaSet是用來做sql連接的一種方法,意思是把資料庫的副本存在應用程式里,相當於存在記憶體中的資料庫,應用程式開始運行時,把資料庫相關數據保存到DataSet.

   ⅱ.DataTable表示記憶體中數據的一個表,常和DefaultView使用獲取可能包括篩選視圖或游標位置的表的自定義視圖。

   ⅲ.DataReader對象是用來讀取資料庫最簡單的方式,它只能讀取不能寫入,而且是從頭至尾往下讀,無法只讀某條數據,但它占用記憶體小,速度快.

   ⅳ.DataAdapter對象是用來讀取資料庫,可讀取寫入數據,某條數據操作強,但它占用記憶體比DataReader大,速度慢,一般和DataSet連用

   註.DataSet表示一個數據集,是數據在記憶體中的緩存。可以包含多個表DataTable,DataSet連接數據時是非面向連接的,把表全部讀到sql中的緩存池,並斷開於資料庫的連接,DataReader連接資料庫是面向連接的。讀表時,只能向前讀取,讀完數據後友用戶決定是否斷開連接。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 過濾器 過濾器(Filter)把附加邏輯註入到MVC框的請求處理,實現了交叉關註。所謂交叉關註(Cross-Cutting Concerns),是指可以用於整個應用程式,而又不適合放置在某個局部位置的功能,否則會打破關註分離模式。典型的例子有:登錄、授權、緩存等等。 使用過濾器 如果希望動作方法只能 ...
  • 一 什麼是LINQ? 二 簡單的Linq例子。(簡單形式我就不介紹了,主要以Lambda形式介紹)。 1 首先創建一個實體對象類並賦值。 public class Person { public int PId { get; set; } // 自增Id public string Name { g ...
  • 到達應用程式的每一個請求都是由控制器處理的。但要註意,不要把事務或數據存儲邏輯放到控制器中,也不要生成用戶界面。 在ASP.NET MVC框架中,控制器是含有請求處理邏輯的.NET類。其作用是封裝應用程式邏輯。也就是說,控制器要負責處理輸入請求、執行域模型上的操作,並選擇渲染給用戶的視圖。 控制器的 ...
  • 最近有客戶反饋系統導入EXECL進行數據處理超時了,我當時的第一反應,不可能啊我明明是做過性能優化的啊,怎麼還會超時呢,這是要有多少條數據才可能發生啊!於是找客戶要來了EXECL,發現有7500多條數據,備份完客戶資料庫進行代碼調試找出性能差的地方。都是一些平時老生常談的東西,可是又是很容易忽略的地 ...
  • Table中合併相同內容列的方法比較好辦,網上代碼也很多,參照了一些把它封裝成jquery 插件,調用起來還是蠻好用的。 這個地方稍微修改了下,有的時候td中內容雖然一樣,但是資料庫中的value卻是不一樣的,比如不同的公司,都有人事部,財務部, 公司A的財務部和公司B的財務部不能合併起來,所以我就 ...
  • .NET提供了很多序列化對象的方法,瞭解他們之間的區別才能更好地確定使用哪一種序列化方式並正確地使用。本文從下麵幾個方面對標題中的三種序列化方法進行了分析。 範圍:Property Or Field Or Both 可見性:Public or Private Or All 可訪問性:Readonly ...
  • 聲明:本系列為原創,分享本人現用框架,未經本人同意,禁止轉載!http://yuangang.cnblogs.com 希望大家好好一步一步做,所有的技術和項目,都毫無保留的提供,希望大家能自己跟著做一套,還有,請大家放心,只要大家喜歡,有人需要,絕對不會爛尾,我會堅持寫完~ 如果你感覺文章有幫助,點 ...
  • 1.參數化查詢模糊查詢 sql語句: create proc procegDataAp( @UserName nvarchar(50))asselect * from users where userName=@UserName 給參數賦值 1 <%@ Page Language="C#" Auto ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...