[轉貼] Asp.Net Cookie 讀取中文變亂碼的解決方法(IE8 會發生 chrome 卻不會發生)

出至:http://tgw1029.blogspot.tw/2010/04/aspnet-cookie.html

Asp.Net -Cookie讀取中文變亂碼的解決方法

有時我的可能因為特別需求,必須使用Cookie來存放簡短的中文字。但中文字的編碼與Cookie預設的編碼方式不同,因此必須先行在URL傳輸過程中經過一道編碼、解碼的程序,才不會發生中文字在Cookie中讀取出來為亂碼的情況。

一般建立Cookie的寫法為:

Dim cookie As New HttpCookie(“UserInfo")
cookie.Values.Add(“Login", “OK")
cookie.Values.Add(“No", dr(“員工編號"))
cookie.Values.Add(“Name", (dr(“員工姓名"))
Response.Cookies.Add(cookie)

由於其中"Name"的Cookie內容存放的是中文字員工姓名,讀取時使用Request.Cookies(“UserInfo")(“Name")後,會發現讀到的中文已經變為亂碼

我們將原本的寫法加入HttpUtility.UrlEncode(編碼)HttpUtility.UrlDecode(解碼),在URL中傳輸而進行編碼的字串轉換來解決亂碼的問題。修改後程式碼如下:

建立Cookie時編碼:

Dim cookie As New HttpCookie(“UserInfo")
cookie.Values.Add(“Login", “OK")
cookie.Values.Add(“No", dr(“員工編號"))
cookie.Values.Add(“Name", HttpUtility.UrlEncode(dr(“員工姓名")))
Response.Cookies.Add(cookie)

讀取時解碼:

HttpUtility.UrlDecode(Request.Cookies(“UserInfo")(“Name"))

Easyflow ISO 直接開啟文件PDF發佈檔(自訂網頁程式)

在 Easyflow ISO 模組上,把開放給使用者能列印(直接開啟PDF)的表單,文件權限等級為標記「9」。

建立後端程式碼處理pdf,由資料庫讀取PDF字串並輸出到前端。

using System;
using System.Collections.Generic;
//using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;

public partial class functions_readStream : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //Response.Write("功能尚未開放,請耐心等候。");
        //Response.End();
        try
        {
            string DocNO = Request.QueryString["DocNO"];
            string DocVer = Request.QueryString["DocVer"];

            using (SqlConnection myConnection = new SqlConnection("User ID=sa;Password = qwe19735;Data Source=192.168.128.219;DataBase=EFNETDB;"))
            {
                if (Session["IsFromLoginPage"] == null || Session["IsFromLoginPage"].ToString() != "Y")
                {
                    Response.Write("你尚未登入Easyflow或是Session已逾時。<br/>如有任何疑問請聯繫資訊課人員。");
                    Response.End();
                }

                const string SQL = @"select isoebb005,isoebb006,isoebb009,isoebb010,isoebf003,isoebf004
                from isoebb join isoebf on isoebb005=isoebf001 and isoebb006=isoebf002
                where isoebb005=@DocNO and isoebb006=@DocVer
                and (isoebf003='0' or (isoebf003='1' and isoebf004 in (select resan001 from resan where resan003=@UserId)))
                and isoebf005='9'
                and isoebb015='1'
                    ;";
                SqlCommand myCommand = new SqlCommand(SQL, myConnection);
                myCommand.Parameters.AddWithValue("@DocNO", DocNO);
                myCommand.Parameters.AddWithValue("@DocVer", DocVer);
                myCommand.Parameters.AddWithValue("@UserId", Session["strUserID"].ToString());

                myConnection.Open();
                SqlDataReader myReader = myCommand.ExecuteReader();

                if (myReader.Read())
                {
                    //Response.ContentType = myReader["MIME"].ToString();
                    Response.ContentType = "application/pdf";
                    Response.BinaryWrite((byte[])myReader["isoebb010"]);
                    Response.End();
                }
                else{
                    Response.Write("你沒有權限瀏覽與列印所選取的文件。<br/>如有任何疑問請聯繫資訊課人員。");
                }

                myReader.Close();
                myConnection.Close();
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.ToString());
        }
    }
}

修改一般第三階表單判斷文件權限等級是否為 “9″ ,來產生列印的文件的連結。

using System;
using System.Collections.Generic;
//using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;

public partial class MIS_ISO_Doc_Index : System.Web.UI.Page
{
    SqlConnection myConEFnet;
    SqlDataAdapter myISOAdapter;
    public string tmpstring, isoType, SessionValues;
    string sqlstring1 = @"
select
a.isoebe003,a.isoebe004,a.isoead003,a.isoeba003, a.isoebe001,a.isoeba002,
b.isoeba003 as isoeba003x,b.isoeba001 as isoeba001x,b.isoeba002 as isoeba002x ,b.isoebd003,isoebf005,in_groups
from
(select isoebe002,isoebe003, isoebe004,isoead003,isoebe001,isoeba002,isoeba003,isoeba012 from
(isoebe join isoead on isoebe003=isoead001 and isoebe004=isoead002 ) join isoeba on isoebe001=isoeba001
and isoebe002=isoeba002 where isoebe001 not like '%-%-%'  and isoeba099='2'
) as a left join
(select substring(isoeba001,0,LEN(isoeba001)-CHARINDEX('-',reverse(isoeba001))+1) as isoeba000,
isoeba001,isoeba002,isoeba003,isoebd003,isoebf005,
in_groups=(case when (isoebf003='0' or (isoebf003='1' and isoebf004 in (select resan001 from resan where resan003=@UserId))) then '1' else '0' end)
from isoeba left join isoebd on isoeba001=isoebd001 and isoeba002=isoebd002 left join isoebf on isoeba001=isoebf001 and isoeba002=isoebf002
where isoeba001 like '%-%-%' and isoeba099='2'
) as b on a.isoebe001=b.isoeba000
where a.isoebe003=@isoType
order by isoebe003,isoebe004,isoebe001,isoeba001x
";
    string sqlstring2 = @"
select
a.isoebe003,a.isoebe004,a.isoead003,a.isoeba003, a.isoebe001,a.isoeba002,
b.isoeba003 as isoeba003x,b.isoeba001 as isoeba001x,b.isoeba002 as isoeba002x ,b.isoebd003,isoebf005,in_groups
from
(select isoebe002,isoebe003, isoebe004,isoead003,isoebe001,isoeba002,isoeba003,isoeba012 from
(isoebe join isoead on isoebe003=isoead001 and isoebe004=isoead002 ) join isoeba on isoebe001=isoeba001
and isoebe002=isoeba002 where isoebe001 not like '%-%-%'  and isoeba099='2'
) as a left join
(select substring(isoeba001,0,LEN(isoeba001)-CHARINDEX('-',reverse(isoeba001))+1) as isoeba000,
isoeba001,isoeba002,isoeba003,isoebd003,isoebf005,
in_groups=(case when (isoebf003='0' or (isoebf003='1' and isoebf004 in (select resan001 from resan where resan003=@UserId))) then '1' else '0' end)
from isoeba left join isoebd on isoeba001=isoebd001 and isoeba002=isoebd002 left join isoebf on isoeba001=isoebf001 and isoeba002=isoebf002
where isoeba001 like '%-%-%' and isoeba099='2'
) as b on a.isoebe001=b.isoeba000
where a.isoebe003='ISO'
order by isoebe003,isoebe004,isoebe001,isoeba001x
";

    DataTable myDataTable1,myDataTable2;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["IsFromLoginPage"] == null || Session["IsFromLoginPage"].ToString() != "Y")
        {
            Response.Write("你尚未登入Easyflow或是Session已逾時。<br/>如有任何疑問請聯繫資訊課人員。");
            Response.End();
        }

        isoType="14001";
        if (Request.QueryString["isoType"] != null)
        {
            isoType = Request.QueryString["isoType"];
        }

        myConEFnet = new SqlConnection("User ID=sa;Password = password;Data Source=192.168.128.219;DataBase=EFNETDB;");
        SqlCommand myCommand1 = new SqlCommand(sqlstring1, myConEFnet);
        myCommand1.Parameters.AddWithValue("@isoType",isoType);
        myCommand1.Parameters.AddWithValue("@UserId", Session["strUserID"].ToString());
        SqlCommand myCommand2 = new SqlCommand(sqlstring2, myConEFnet);
        myCommand2.Parameters.AddWithValue("@UserId", Session["strUserID"].ToString());

        myConEFnet.Open();
        myISOAdapter = new SqlDataAdapter(myCommand1);
        myDataTable1 = new DataTable();
        myISOAdapter.Fill(myDataTable1);
        myISOAdapter = new SqlDataAdapter(myCommand2);
        myDataTable2 = new DataTable();
        myISOAdapter.Fill(myDataTable2);
        string[] strs;
        DataView tmpView1 = myDataTable1.DefaultView;
        DataTable tmpTable1 = tmpView1.ToTable("tmpTable1",true,strs= new string[]{"isoebe004","isoead003"});
        DataTable tmpTable2 = tmpView1.ToTable("tmpTable2", true, strs = new string[] { "isoebe004","isoeba003","isoebe001","isoeba002" });
        DataTable tmpTable3 = tmpView1.ToTable("tmpTable3", true, strs = new string[] { "isoebe001", "isoeba003x", "isoeba001x", "isoeba002x", "isoebd003", "isoebf005","in_groups" });
        DataView tmpView2 = myDataTable2.DefaultView;
        DataTable tmpTable4 = tmpView2.ToTable("tmpTable4",true,strs= new string[]{"isoebe004","isoead003"});
        DataTable tmpTable5 = tmpView2.ToTable("tmpTable5", true, strs = new string[] { "isoebe004","isoeba003","isoebe001","isoeba002" });
        DataTable tmpTable6 = tmpView2.ToTable("tmpTable6", true, strs = new string[] { "isoebe001", "isoeba003x", "isoeba001x", "isoeba002x", "isoebd003", "isoebf005","in_groups" });

        foreach (DataRow row in tmpTable1.Rows) {
            tmpstring += "<tr><td class='td1'><div>" + row["isoebe004"] + " " + row["isoead003"] + "</div></td><td><table>";
            foreach (DataRow row1 in tmpTable2.Select("isoebe004 = '"+ row["isoebe004"]+"'")) {
                tmpstring += "<tr><td class='td2'><div><a style='color:blue;' target='_blank' href='/efnet/src/ISO/ISOEM008/DocDetail.aspx?DocNO=" + row1["isoebe001"] + "&DocVer=" + row1["isoeba002"] + "'>" + row1["isoeba003"] + "</div></td><td class='td3'><div>" + row1["isoebe001"] + "</div></td><td  class='td4'><div>" + row1["isoeba002"] + "</div></td><td><table>";
                foreach(DataRow row2 in tmpTable3.Select("isoebe001 = '"+ row1["isoebe001"]+"'")){
                    if (row2["isoeba003x"].ToString() == "")
                    {
                        tmpstring += "<tr><td  class='td5'><div>&nbsp;</div></td><td  class='td6'><div>&nbsp;</div></td><td  class='td7'><div>&nbsp;</div></td></tr>";
                    }
                    else
                    {
                        tmpstring += "<tr><td  class='td5'><div><a style='color:blue;' target='_blank' href='/efnet/src/ISO/ISOEM008/DocDetail.aspx?DocNO=" + row2["isoeba001x"] + "&DocVer=" + row2["isoeba002x"] + "'>" + row2["isoeba003x"] + "</a>"+
						((row2["isoebd003"].ToString()!="")?"<a style='color:red;font-weight:bold;' target='_blank' href='../../frm/"+row2["isoebd003"].ToString()+"/"+row2["isoebd003"].ToString()+".aspx'>&nbsp;&nbsp;[申請]</a>":"")
                        + (row2["isoebf005"].ToString() == "9" && row2["in_groups"].ToString() == "1" ? "<a style='color:blue;' target='_blank' href='../functions/readStream.aspx?DocNO=" + row2["isoeba001x"] + "&DocVer=" + row2["isoeba002x"] + "''>&nbsp;&nbsp;[列印]</a>" : "")
                        +"</div></td><td  class='td6'><div>" + row2["isoeba001x"] + "</div></td><td  class='td7'><div>" + row2["isoeba002x"] + "</div></td></tr>";
                    }
                }
                tmpstring += "</table></td><td><table title='" + row1[1] + "'>";

				foreach (DataRow row3 in tmpTable5.Select("isoebe004 = '"+ row1[2].ToString().Replace("-","")+"'")) {
					tmpstring += "<tr><td class='td2'><div><a style='color:blue;' target='_blank' href='/efnet/src/ISO/ISOEM008/DocDetail.aspx?DocNO=" + row3["isoebe001"] + "&DocVer=" + row3["isoeba002"] + "'>" + row3["isoeba003"] + "</div></td><td class='td3'><div>" + row3["isoebe001"] + "</div></td><td  class='td4'><div>" + row3["isoeba002"] + "</div></td><td><table>";
					foreach(DataRow row4 in tmpTable6.Select("isoebe001 = '"+ row3["isoebe001"]+"'")){
						if (row4["isoeba003x"].ToString() == "")
						{
							tmpstring += "<tr><td  class='td5'><div>&nbsp;</div></td><td  class='td6'><div>&nbsp;</div></td><td  class='td7'><div>&nbsp;</div></td></tr>";
						}
						else
						{
							tmpstring += "<tr><td  class='td5'><div><a style='color:blue;' target='_blank' href='/efnet/src/ISO/ISOEM008/DocDetail.aspx?DocNO=" + row4["isoeba001x"] + "&DocVer=" + row4["isoeba002x"] + "'>" + row4["isoeba003x"] + "</a>"+
							((row4["isoebd003"].ToString()!="")?"<a style='color:red;font-weight:bold;' target='_blank' href='../../frm/"+row4["isoebd003"].ToString()+"/"+row4["isoebd003"].ToString()+".aspx'>&nbsp;&nbsp;[申請]</a>":"")
                            + (row4["isoebf005"].ToString() == "9" && row4["in_groups"].ToString() == "1" ? "<a style='color:blue;' target='_blank' href='../functions/readStream.aspx?DocNO=" + row4["isoeba001x"] + "&DocVer=" + row4["isoeba002x"] + "''>&nbsp;&nbsp;[列印]</a>" : "")
							+"</div></td><td  class='td6'><div>" + row4["isoeba001x"] + "</div></td><td  class='td7'><div>" + row4["isoeba002x"] + "</div></td></tr>";
						}
					}
                    tmpstring += "</table></td></tr>";
				}
				tmpstring += "</table></td></tr>";
            }
            tmpstring+="</table></td></tr>";
        }
        tmpstring="<table class='table1' style='display:none;'>"+tmpstring+"</table>";
        foreach (string SessionVar in Session.Keys)
        {
            SessionValues += "<br />" + SessionVar + ":" + Session[SessionVar].ToString();
        }
        SessionValues = "<div>" + SessionValues + "</div>";
    }
}

接著在機密等級代號維護作業中,新增一條文件權限等級「9」自訂公開、可列印。 新增一條機密等級代號9允許列印

指定允許被開啟列印的ISO文件,將文件的機密等級設定為「9」。指定允許列印的表單文件權限為「9 」

最後就完成了,ISO文件一覽表中加載了列印連結。ISO文件一覽表增加表單列印

Asp.net Response.write PDF to IE browser and got garbled

Asp.net response.write a binary pdf file to chrome is ok , but ie is fail that got garbled. Because ie must get server response a end tag.

在 Asp.net 寫出 PDF 檔至前端瀏覽器顯示。在 chrome 可以正常顯示,但在 IE 上無法檢視 僅出現亂碼。因為 IE 會跟你計較輸出資料串流時有沒有告知它串流已輸出完了。Response.End() 沒給 IE 就出亂碼。

程式片段

myConnection.Open();
SqlDataReader myReader = myCommand.ExecuteReader();

if (myReader.Read())
{
//Response.ContentType = myReader[“MIME"].ToString();
Response.ContentType = “application/pdf";
Response.BinaryWrite((byte[])myReader[“isoebb010″]);
Response.End();
}
else{
Response.Write(“你沒有權限瀏覽與列印所選取的文件。
如有任何疑問請聯繫資訊課人員。");
}

myReader.Close();
myConnection.Close();
[/sourcecode]

c# read binary data from sqlserver and output data-stream

From: http://dbtutorials.com/advanced/retrieving-binary-sql-cs.aspx

c# read binary data from sqlserver

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;

public partial class ShowImage : System.Web.UI.Page
{
	protected void Page_Load(object sender, EventArgs e)
	{
		try
		{
			int PictureID = Convert.ToInt32(Request.QueryString["ID"]);

			using (SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
			{
				const string SQL = "SELECT [MIME], [BinaryData] FROM [BinaryTable] WHERE [ID] = @ID";
				SqlCommand myCommand = new SqlCommand(SQL, myConnection);
				myCommand.Parameters.AddWithValue("@ID", PictureID);

				myConnection.Open();
				SqlDataReader myReader = myCommand.ExecuteReader();

				if (myReader.Read())
				{
					Response.ContentType = myReader["MIME"].ToString();
					Response.BinaryWrite((byte[]) myReader["BinaryData"]);
				}

				myReader.Close();
				myConnection.Close();
			}
		}
		catch (Exception ex)
		{
			Response.Write(ex.ToString());
		}
	}
}

NPOI讓ASP.NET網頁簡單輸出Native的Excel

NPOI官網: http://npoi.codeplex.com/

下載最新的「NPOI」 x.x.x binary and examples,裏面包含了許多範例程式。簡單的複製範例程式片段,往自已的程式貼上就可以跑了當然要使用NPOI函式庫囉。

會使用NPOI最主要原因,是因為ASP.NET GridView 輸出的Excel基本上是Html的Table。要拿來給某此資料匯入工具吃,可能無法使吃下去。

linqtoexcel 讓讀取Excel資料像處理資料庫一樣簡單

Linq to Excel

Use LINQ to retrieve data from spreadsheets.

var excel = new ExcelQueryFactory("excelFileName");
var indianaCompanies = from c in excel.Worksheet<Company>()
                       where c.State == "IN"
                       select c;

Download the current version or install the NuGet package.

Go to the Read me page for information on implementing Linq to Excel in your project.

Need help? Report an issue or send questions to the discussion group.


Demo Video

GridView的DataFormatString參考

GridView的DataFormatString參考

GridView 在DataFormatString屬性 中的 {0} 表示資料本身,而在冒號後面的格式字符串代表所們希望資料顯示的格式; 例如 {0:d} ==> 2009/3/11

GridView DataFormatString屬性 數字、貨幣格式
在指定的格式符號後可以指定小數所要顯示的位數。例如原來的數據為「1.56」,若格式設定為 {0:N1},則輸出為「1.5」。其常用的數值格式如下表所示:

格式字串輸入結果
“{0:C}" 12345.6789 ==> $12,345.68
“{0:C}" -12345.6789 ==>($12,345.68)
“{0:D}" 12345 ==>12345
“{0:D8}" 12345 ==>00012345
“{0:E}" 12345.6789 ==>1234568E+004
“{0:E10}" 12345.6789 ==>1.2345678900E+004
“{0:F}" 12345.6789 ==>12345.68
“{0:F0}" 12345.6789==> 12346
“{0:G}" 12345.6789==> 12345.6789
“{0:G7}" 123456789 ==>1.234568E8
“{0:N}" 12345.6789 ==>12,345.68
“{0:N4}" 123456789 ==>123,456,789.0000
“Total: {0:C}" 12345.6789 ==>Total: $12345.68

GridView DataFormatString屬性 常用的日期時間格式:

格式 說明 輸出格式
d 精簡日期格式 MM/dd/yyyy
D 詳細日期格式 dddd, MMMM dd, yyyy
f 完整格式 (long date + short time) dddd, MMMM dd, yyyy HH:mm
F 完整日期時間格式 (long date + long time) dddd, MMMM dd, yyyy HH:mm:ss
g 一般格式 (short date + short time) MM/dd/yyyy HH:mm
G 一般格式 (short date + long time) MM/dd/yyyy HH:mm:ss
s 適中日期時間格式 yyyy-MM-dd HH:mm:ss
t 精簡時間格式 HH:mm
T 詳細時間格式 HH:mm:ss

所以不一定要記,只要跟程式一樣 yyyy ==> 年 ,MM==>月,dd==>日,HH==>時,mm==>分,ss==>秒

Asp.net session mode = stateserver , let session disappear no longer.

ASP.NET的sessionState的三種屬性

InProc(預設):也就是將Session保存在Process裡面(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),這個Process算是不穩定,在某些事件發生時,Process會重新啟動。在web.config的設定:

<configuration>
      <system.web>
             <sessionState   mode="InProc"
                  timeout="20"
                  cookieless="UseCookies">
             </sessionState>
      </system.web>
</configuration>

StateServer:本機的一個服務,可以在系統服務裡看到服務名為ASP.NET State Service的服務,預設下是不啟動的。當我們設定mode為StateServer之後,要在服務那邊手動將該服務啟動喔。在web.config的設定:

   <configuration>
      <system.web>
            <sessionState mode="StateServer" timeout="500"
            stateConnectionString="tcpip=127.0.0.1:42424"/>
      </system.web>
  </configuration>

SQLServer:將 session 存於 SqlServer 資料庫中,必需要有ASPState資料庫,所以要使用 aspnet_regiis.exe 工具來新增,步驟如下:

(1.)新增 ASPState 資料庫:進入命令模式視窗輸入 aspnet_regsql.exe -S ServerName -E -ssadd -sstype p
(2.)如果要移除:進入命令模式視窗輸入aspnet_regsql.exe -S ServerName -E -ssremove
(3.)在web.config的設定:

<configuration>      
      <system.web>   
             <sessionState mode="SQLServer"   
                        sqlCommandTimeout="30"   
                        sqlConnectionString="data  source=localhost;Integrated             
                        Security=SSPI">   
              </sessionState>   
      </system.web>   
</configuration>

from:http://www.dotblogs.com.tw/boei/archive/2010/07/06/16414.aspx

Asp.NET 所開發的網頁無法輸入日文字或其它Unicode字型

之前已經有發現到類似的問題,是在網頁中輸入日文字所造成的問題。當時的情況是只要輸入請假事由的字串中包含日文字型就會出現以下的訊息。「偵測到來自用戶端的潛在危險 Request.Form 值.」 ,雖然可以透過取消字串驗證的方式,即可以讓日文字以unicode的方式存入後端。但最終還是沒繼續採用此方式(決得有點不安全)。

作法:在需要輸入日文頁面中的「Page」標籤中加上一屬性值「ValidateRequest="false"」,例如: <%@ Page ValidateRequest="false"%>。

而下面是比較好的做法就是將網站編碼格式改為「UTF-8」這樣的作法也比較一勞永逸。

作法:編輯 web.config 設定 globalization 其中的編碼屬性

<configuration>
  <system.web>
    <globalization
    fileEncoding="utf-8"
    requestEncoding="utf-8"
    responseEncoding="utf-8"
    culture="en-US"
    uiCulture="de-DE"
    />
  </system.web>
</configuration>

注意事項:雖然完成上述的設定後網頁就會以UTF-8的編碼格式傳送至前端,但是網頁呈現出來的文字很有可能會出現亂碼。因為在建立或是編輯程式碼檔案或是前端aspx檔案時,所用的編碼格式是BIG5的而造成。

解決方法:用notepad++開啟有亂碼出現的前端頁面碼ASPX的檔案或是後端的BindCode檔案,這就要看你的中文亂碼是安在哪個檔案上頭的。notepad++開啟檔案後,選擇編碼 >> 轉換至 utf-8 碼格式。