2013年7月28日 星期日

jQuery Mobile的範例網頁

jQuery Mobile Examples - JQM Gallery

提供所有擁有行動版的網站,可以對網站的版面做一些參考

Jquery Mobile 中文API站

Jquery Mobile的中文教學網站,且擁有版面配置的功能
重點是可以看他的原始碼

2013年7月23日 星期二

Session與Global.asax相關的筆記

最近開始在做網站的瀏覽統計
所以對這些方面參考了一些資源

Session
[ASP.NET]Session詳解
Session.Clear() or Session.Abandon() ?
[ASP.NET]Session的幾個有趣現象

特別的是我在Web.config上沒有發現到有關 sessionState 的標籤,但是可以自己新增。
而我所得到的重點是
  • sessionSate內的 mode 是 InProc 的話,Session_End的執行就會有效
  • sessionSate內的 cookieless 如果是 true,IIS會自動分配給你SessionID,不過這樣會使IsNewSession沒有用處
  • Session內的Clear指令是刪除Session的數值,而本身的Session會留著
  • 而Abandon是把Session整個刪除、下次登入之後就會分發新的Session,效果就如同timeout一樣,而且會觸發Global.asax內的Session_End事件
Global.asax

主要是控制網頁開啟、網頁出錯、客戶瀏覽等事件。

  • Application_Start 是在伺服器開啟時就會啟動這個事件
  • Application_BeginRequest 是傳送檔案時(如FileUpload)就會啟動這個事件
  • Session_Start 是客戶端只要一進到網頁就會啟動的事件
  • Session_End 是 mode 為 InProc 才會觸發的事件,只要是timeout或是執行Session.Abandon()都會觸發

DataReader 與 Connection 的關係

在資料庫的讀取中,大部分的方法就是
設定 Connection、設定Commander、最後就是用DataReader讀出
不過我在之前完全不知道,為什麼要打開與關閉Connection,
只是照著網路與程式錯誤來配合開關,直到最近,遇到了一個問題

已經開啟一個與這個連接相關的 DataReader,必須先將它關閉。

碰到問題之後上網找解答時,找到了這個
DataReader關閉的問題  --  程式設計俱樂部

我才發現,其實每次執行Commander之後,Connection就會被那個Commander給獨佔,
如果其他Commander想要連結同一個Connection的話,就會顯示錯誤。

這時有幾個方法:
一、新增另一個Connection
二、如果是Select的話,改用DateTable讀取(不用再開啟Connection)
三、每執行完一個指令之後,將Connection關閉再開啟
例如:

Connection.open();
指令一
Connection.close();
Connection.open();
指令二
Connection.close();


不過VS 2012上測試之後,發現這問題似乎解決了...
所以給用VS 2010寫的人一些解決方法。

2013年7月20日 星期六

控制項的事件問題(ListView)

在撰寫程式的途中,我在ListView中分別加入了兩個按鈕,
而這兩個按鈕中,分別會有不同條件來顯示。
不過當我把程式碼寫入,Page_Load的時候

卻發現出現了Out of Range這種錯誤,
結果問題是出現在ListView裡面根本就沒有資料,
當時想到的就是網頁的生命週期的問題,


--------------以上是個人猜測,如果不正確,請婊用力一點--------------
就在這時發現,
在開始的階段內,如果IsPostBack的階段是Page_Load的話,
那在初始化階段才開始做控制項的東西,
那就代表在Page_Load的時候,控制項根本就還沒有動作。
---------------------------------------------------------------------------------

在之後的解決方法就是:
直接在Page_Load繫結ListView的資料來源

參考資料
FindControl dropdownlist in ListView ItemTemplate in Page_Load
ASP.NET 網頁生命週期概觀

2013年7月19日 星期五

ASP.NET 圖片管理員(多重上傳)

在很多上傳圖片之類的例子中,通常想到的都是用FileUpload上傳檔案。
上傳的檔案就在資料夾內,如果在之後沒有再用到的話怎麼辦?
所以我就做出了這樣的程式能夠為自己的圖片做簡單的新增與刪除。


這裡是主頁(接收圖片資料)的程式碼 protected void Page_Load(object sender, EventArgs e)
{
     if (Session["Img"] != null)
     {
        lblGetName.Text = "發現圖檔已傳送," + Session["Img"].ToString();
     }
}

這裡是圖片管理員的程式碼

protected void Page_Load(object sender, EventArgs e)
{
      // 這裡是讀取圖片資料夾,並取出資料
      // 資料夾資料
      DirectoryInfo dir = new DirectoryInfo(Server.MapPath ("Image"));
      // 檔案資料 (取出自資料夾)
      FileInfo[] file = dir.GetFiles();
      // 計算ID 流水號
      int ID = 0;

      foreach (FileInfo result in file) 
      {
            ID++;
            // 創出 CheckBox,並設定相關的數值
            CheckBox img = new CheckBox();
            img.ID = "Img" + ID;
            img.Text = "<img src='Image\\" + result.Name + "' width='100' height='100' />";
            img.InputAttributes["value"] = result.Name;
            // 加入到 PlaceHolder 內
            PlaceHolderImage.Controls.Add(img);
      }
}

protected void btnNew_Click(object sender, EventArgs e)
{
       // 取得檔案路徑
       string saveDir = "\\Image\\";
       string fileName, savePath;

        // 取得檔案名稱並儲存檔案
        // 這裡是.NET 4.5的多重檔案上傳(PostedFiles)
        foreach (HttpPostedFile postedFile in FuImage.PostedFiles)
       {
             fileName = postedFile.FileName;

             savePath = Server.MapPath(saveDir + fileName);
             postedFile.SaveAs(savePath);

        }
        Response.Write("<script language='javascript'>alert('上傳成功');location.href='ImageManager.aspx';</script>");
         
}

protected void btnUse_Click(object sender, EventArgs e)
{
        // 取出選取檔案的名稱
        string useimage = "";
        for (int chk = 1; chk <= PlaceHolderImage.Controls.Count; chk++)
       {
            // PlaceHolder內的Checkbox
            CheckBox chkimg = (CheckBox)PlaceHolderImage.FindControl("Img" + chk);
            // 確認是否選取
            if (chkimg.Checked)
            {
                 useimage += Request.Form["Img" + chk]+",";
            }
        }
            // 使用 Session 紀錄資料
            Session["Img"] = useimage;
            Response.Redirect("Default.aspx");
        }

protected void btnDel_Click(object sender, EventArgs e)
{
        // 刪除圖片
        bool notexist = false;
        DirectoryInfo dir = new DirectoryInfo(Server.MapPath("Image"));
        FileInfo[] file = dir.GetFiles();
        int ID = 0;
          foreach (FileInfo delfile in file)
          {
                ID ++ ;
                CheckBox chk = (CheckBox)PlaceHolderImage.FindControl("Img" + ID);
              if (chk.Checked)
              {
                  //確認檔案存在
                  if (delfile.Exists)
                  {
                      delfile.Delete();
                  }
                  else
                  {
                      notexist = true;
                  }
              }
          }

          if (notexist == true)
          {
              Response.Write("<script language='javascript'>alert('刪除失敗,圖檔不存在')</script>");
          }
          else
          {
              Response.Write("<script language='javascript'>alert('刪除成功');location.href='ImageManager.aspx';</script>");
          }
}


參考資料
FileUpload控制項「批次上傳 / 多檔案同時上傳」的範例 -- AllowMuliple屬性
[ASP.NET] 替CheckBox增加Value值

範例下載
點我

2013年7月16日 星期二

ASP NET 幾種資料庫連結方法 (Access為例)

首先在這裡介紹幾個ASP.NET連結資料庫的幾種方法
因為範例的資料庫是Access,所以就使用Access的方式來連結
(其實也差不了多少)

方法一
完全使用程式碼來操作
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|NorthWind.mdb;Persist Security Info=True"); //連結字串
conn.Open(); // 開啟連結
OleDbCommand cmd = new OleDbCommand(readcmd , conn); //指令 設定住在London的人
OleDbDataReader dr = cmd.ExecuteReader(); // 讀取到DataReader
//while (dr.Read()) // 如果有讀取到 (這裡是直接輸出)
//{
// Response.Write(dr[0].ToString() +" "+dr[1].ToString ()+" "+dr[2].ToString ()+" "+dr[3].ToString ()+" "+dr[4].ToString ()+" "+dr[5].ToString ()+ "
"); //輸出
//}
// 這裡是使用GridView輸出
GridView1.DataSource = dr;
GridView1.DataBind();
conn.Close(); //關閉連結
// 註:readcmd 是連結的指令 例如:Select * From Student...


方法二
使用控制項寫入程式碼(以AccessDataSource為例)
這個感覺就簡單多了
// 連結
AccessDataSource1.DataFile = "~/App_Data/NorthWind.mdb";
// 這是Sql的例子
SqlDataSource1.ConnectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

// 指令
AccessDataSource1.SelectCommand = "Select * From Customers Where City='London'"; GridView1.DataSourceID = "AccessDataSource1";

註:在上面的Sql連結例子中,ConnectionString 內的["ConnectionString"]是需要在web.config上設定的,也可以使用精靈設定(較簡單)
<add name connectionstring="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|NorthWind.mdb;Persist Security Info=True" name="ConnectionString" providername="System.Data.OleDb">
方法三 完全不使用程式碼
就是完全使用精靈製作啦
雖然說是精靈製作,但其實在HTML編碼上面還是能夠改屬性的
<asp:accessdatasource ID="AccessDataSource1" 控制項ID
runat="server" 在伺服器上運作
DataFile="~/App_Data/NorthWind.mdb" 實體資料庫
SelectCommand="Select * From Customers Where City = 'London'"> 指令


參考資料
不支援關鍵字: 'provider'
Can´t bind a OleDbDataReader to a GridView
[教學] 如何在 Blogger 文章裡顯示程式碼?