程式存取web.config注意事項

在學習或使用ADO.NET的過程裡,常常會需使用程式來讀取web.config裡的資料庫連線字串,原因無他,因為連線字串"LoLo長",沒有人背得起來,背的起來的人也太…不長進,寫在web.config的美意不只要心領,像我們走過ASP到ASP.NET的路,所以能了解光一個web.config就讓我高興不知道多久!

程式碼裡的連線字串

Dim conn As New System.Data.SqlClient.SqlConnection("Data Source=192.168.1.10\SQLEXPRESS;Initial Catalog=Northwind;Persist Security Info=True;User ID=bruce;Password=1234567890")

這種寫在程式碼的缺點是,萬一連線字串有任何修改,例如:資料庫伺服器修改IP,你必須找出"所有"有寫連線字串的程式,然後一行一行修改。這無疑是走回頭路,不可取也。

web.config裡的連線字串(for .NET Framework 4.0)

<?xml version="1.0"?>

<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
    <appSettings >
        <key="CopyRight" value ="(c) Copyright 2008 KingKong Bruce Technology Inc."/>
    </appSettings>
    <connectionStrings>
        <add name="NorthwindConnectionString" connectionString="Data Source=192.168.1.10\SQLEXPRESS;Initial Catalog=Northwind;Persist Security Info=True;User ID=bruce;Password=1234567890"
            providerName="System.Data.SqlClient" />
    </connectionStrings>
    <system.web>
        <compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
    </system.web>

</configuration>

透過web.config集中統一的管理,而且我們可以新增多組連線字串,我們只需要在程式端使用程式碼取得web.config裡連線字串(<connectionStrings>)中的name屬性值(<add name="..." ...>),程式會自動幫我們對應相對的連線字串。想想,今天不管我們要進行任何連線字串的修改,只要修改web.config中的連線字串,*.aspx中的程式碼"立即"跟著變動,也就是說:「牽一髮而動全身」,這種設計及使用,才是正確的方向。

程式存取web.config

能work,但錯誤的方式

我不只一次,而且還很常在各大作者的書,各大討論區、論壇中看到以下此種寫法,這種做法我不說你一定不知道是錯誤的,因為「它」能非常非常正常的work,這也是標準的「能動就好」,管它對不對!

錯誤但能正確運作的程式:
Imports System.Configuration
Imports System.Data.SqlClient

Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString.ToString())
        'Do Something
    End Sub

End Class


正確版程式碼--使用System.Web.Configuration

Imports System.Web.Configuration
Imports System.Data.SqlClient

Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim conn As New SqlConnection(WebConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString.ToString())
        'Do Something
    End Sub

End Class

有沒有看出來差異點?
錯誤確能運作是「Imports System.Configuration」,而正確版是「Imports System.Web.Configuration」,而程式碼也只有一點點差異,錯誤確能運作的程式碼是使用「ConfigurationManager」來取得連線字串,而正確版本是使用「WebConfigurationManager」來取得連線字串。

那這兩個命名空間有什麼差,反正都能動。我想,許多書的作者都是從寫WinForm來改寫WebForm,而他們在改寫的過程裡,因為沒有發生任何錯誤訊息,而且程式都能正常運作,所以也就沒發現這一點點的差異。第一個System.Configuration命名空間是WinForm來存取app.config使用,第二個System.Web.Configuration命名空間是WebForm來存取web.config使用。而讀者也就進行了無差別式的吸收與應用。

說真的,要不是我看到有人使用了正確的方式,我也還在使用錯誤但能運作的方式在寫這方面的ASP.NET程式,早期的文章都是使用錯誤的方式。只是很難說,那天.NET Framework改版後,如果System.Configuration命名空間的方法與System.Web.Configuration命名空間的方法不能共用時,那不就是又是一陣「大改」,把所有使用錯誤命名空間的網頁一頁一頁找出來改,結果還是要走回頭路。

所以最好的方法就是,一開始就使用正確的命名空間,使用正確的方法,最保險,最沒有問題。各位也可以Check ASP.NET Book內容,如果有以上的問題,寫封信提醒一下作者這個問題。

17 則留言:

  1. 原來如此XD
    一直以來我也是用ConfigurationManager來取得連線字串的@@
    看來我也要來review一下之前寫的程式囉

    回覆刪除
  2. Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim conn As New SqlConnection(WebConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString.ToString())
    'Do Something
    End Sub

    IF WebConfigurationManager.ConnectionStrings <> Nothing Then
    IF WebConfigurationManager.ConnectionStrings("NorthwindConnectionString") <> Nothing Then

    語法不勝正確,重點是,必須檢核,以防無此設定

    回覆刪除
  3. Dear 匿名
    感謝你提供的意見。

    本篇的重點在WebConfigurationManager上,而非語法上,且實務上多使用「Using + Try」語法來進行資料庫部份,很少有人使用IF來判斷。

    回覆刪除
  4. 請問如果是mysql的話New SqlConnection()如何引用web.config呢...一直引用不了...拜託了

    回覆刪除
  5. .NET本身不支援MySql,你必須安裝「http://www.mysql.com/products/connector/」裡的「ADO.NET Driver for MySQL (Connector/NET)」之後,才有辦法在開發工具中連結使用MySql。

    一般是使用"MySqlConnection"來連結存取。

    http://www.dotblogs.com.tw/jeff377/archive/2008/03/17/1709.aspx
    http://developer.51cto.com/art/200901/107167.htm

    這兩篇你參考看看。

    記得,上線的那台伺服器一樣要安裝Mysql Connector,才有辦法存取MySql。

    回覆刪除
  6. 作者已經移除這則留言。

    回覆刪除
  7. 謝謝大大提供的參考 ,
    我是可以使用mysql並抓取資料了 , 且每業有用MySqlConnection來驅動mysql抓資料....
    但我現在把MySqlConnection後面LOLO長的驅動寫在web.config內 , 可是要怎麼將它拿出來MySqlConnection上用...找很多資料還是沒有個很正確的解答...
    New MySqlConnection()內的帳密我寫在web.config了...引用方式大大有建意嗎....再次感恩阿......^^

    以下是我的程式碼 :
    ====web.config=====






    ====aspx.vb======

    Imports MySql.Data
    Imports MySql.Data.MySqlClient
    Partial Class _Default
    Inherits System.Web.UI.Page


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Dim myConn As MySqlConnection
    Dim myDataAdapter As MySqlDataAdapter
    Dim myDataSet As Data.DataSet

    myConn = New MySqlConnection("server=server-sc1web;user id=root;password=1234;database=cim")
    myConn.Open()

    回覆刪除
  8. 我沒有安裝MySql,不過這是我的驗證方式,由web.config讀入MySql連線字串,應該沒有問題:

    在web.config中下新增



    Default.aspx.vb

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim cs As String = WebConfigurationManager.ConnectionStrings("MySqlCS").ConnectionString.ToString()
    Response.Write(cs)
    End Sub

    我能正確讀出相關連線字串(server=server-sc1web;user id=root;password=1234;database=cim)。

    看看是不是那字串前後要加上"(雙引號),因為預設產出的字串是沒有雙引號。

    回覆刪除
  9. 在web.config中下新增

    add name="MySqlCS" connectionString ="server=server-sc1web;user id=root;password=1234;database=cim" providerName="MySql.Data.MySqlClient"/

    大角括號會讓字不見,請自行加上。

    回覆刪除
  10. 老師你提供的方式可以撈出來了 ,超感謝的啦
    但我發現
    add name="ConnectionString" connectionString="Dsn=CIM;uid=root;pwd=1234" providerName="System.Data.Odbc"/
    我是用ODBC方式來連的話,丟入New MySqlConnection()內好像不可使用 , 我該用什麼方式來導入它呢....
    sorry , 我初學mysql .所以很多地方請老師多指教,超感謝你

    回覆刪除
  11. 一、
    Sorry, MySQL與ASP.NET的合作,我無研究,如果不行的話,我想還有其他很多方式,如果只是要保護連線字串,也可以在App_Data下新增一個TXT或XML檔案,需要時讀出給

    myConn = New MySqlConnection(ConnectionString)

    即可。

    二、
    一般而言,

    PHP + MySql
    ASP/ASP.NET + MS SQL

    這樣的學習比較好,因為資源多,但你挑 ASP.NET + MySql就會比較幸苦,且未來在一些進階應該還會有更多挑戰,除非是不得以(工作必須),不然實在不建議這樣的組合。

    回覆刪除
  12. ASP.NET + MySql 不得以(工作必須), 哎哎哎~~~心酸...
    老師我自己try 也有點心得了...
    簡單分享 = 希望初學者也可運用
    Dim myConn As OdbcConnection
    Dim myDataAdapter As OdbcDataAdapter
    Dim myDataSet As Data.DataSet
    Dim m_txt As String
    Dim cs As String = WebConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString.ToString()

    m_txt = TextBox1.Text
    Label1.Text = cs

    myConn = New OdbcConnection(cs)
    myConn.Open()

    Dim strsql As String

    If m_txt <= "" Then
    Label2.Text = "NO SQL"
    MsgBox("無輸入")
    strsql = "select userid,username from user "
    Else
    MsgBox("有輸入")
    strsql = "select userid,username from user where userid ='" & m_txt & "'"
    Label2.Text = strsql
    End If

    myDataAdapter = New OdbcDataAdapter(strsql, myConn)
    myDataSet = New Data.DataSet()
    myDataAdapter.Fill(myDataSet, "a1")

    GridView1.DataSource = myDataSet.Tables("a1").DefaultView
    GridView1.DataBind()
    myConn.Close()

    ps : 再請問gridview如何正確的使用份頁呢, allowpaging=turn後 , 第二頁就無法使用了..我該如何使用它呢...感謝老師

    回覆刪除
  13. GridView1.AllowPaging = True
    GridView1.PageSize = 10

    在BridView1.DataSource = ... 前加上去看看。

    你把資料集(DataSet)與GridView繫結後,應該能正常分頁才是。

    http://msdn.microsoft.com/zh-tw/library/system.web.ui.webcontrols.gridview_members%28VS.80%29.aspx

    把MSDN的GridView看一篇。

    回覆刪除
  14. 想請教bruce , 如果系統是跑asp他會去讀web.config嗎?
    最近工作上接手了一個asp網站, 裡面有web.config檔,這個站有用到rewrite isapi元組件, 他就是把rewrite敘述式寫在web.config裡頭, 我覺得很奇怪,web.config不是asp.net才會用到的東西嗎??

    回覆刪除
  15. web.config是一個「XML組態檔」,網站架構者可能把asp.net的觀念帶進去asp去使用,並無不可。

    應該是:
    web.config這個"檔名",是asp.net在使用沒錯,
    但XML拿來當組態,可就不是asp.net的專利。

    回覆刪除
  16. 我有一個關於web.config的問題不知道如何解決
    寫了一個很簡單的程式
    在VS 2010的File system 上跑没問題
    所以就Publish 到本機的IIS 7
    用編譯後的default.aspx 跑也没問題
    可是一上傳到外部網站上跑就錯了(編譯碼)
    不信邪把原始碼上傳上去
    一跑又對了
    這是什麼原因?
    請測試
    http://jason557.com/WebTest1/ <------原始碼
    http://jason557.com/WebTest2/ <------編譯碼

    就說Could not load the assembly 'App_Web_bfzuzhxc'.
    但 App_Web_bfzuzhxc.dll就明明在\Bin 裏項
    真是搞不懂
    請指點迷津
    jason557@gmail.com

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Parser Error
    Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

    Parser Error Message: Could not load the assembly 'App_Web_bfzuzhxc'. Make sure that it is compiled before accessing the page.

    Source Error:


    Line 1: <%@ page language="C#" autoeventwireup="true" inherits="_Default, App_Web_bfzuzhxc" %>

    回覆刪除
    回覆
    1. 1. 你應該使用【安裝或部署】或【發行】來上傳設定至外部 IIS。
      2. 將外部 IIS 上的 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\ 暫存目錄下所有內容刪除。 (也許還有 4.0 的目錄,也一併刪除)
      3. http://blog.kkbruce.net/p/net-framework.html#webdp 可參考這幾篇。

      刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。