只有累積,沒有奇蹟

2018年9月28日 星期五

[.NET] QueryString 的那些事

概述

Querystring(查詢字串)是附加在網頁URL結尾的資訊。主要是在Url上傳遞資料,可能是一個搜尋字串、頁碼、某項特定的指標…或類似的東西
在網址結尾加上一個問號(?)開始,每一組參數都是用「&」區隔開來,是一種KEY / Value的組合。
舉例來說(參考上圖),在Yahoo首頁搜尋引擎輸入「Hello world」後,在按下搜尋按鈕,會導頁到查詢結果頁面,並將符合搜尋字串相關資料呈現出來。
運作原理是透過Querystring作為資料傳遞,當你按下搜尋按鈕時,會將你在首頁(A網頁)輸入的搜尋字串「Hello world」傳遞到查詢結果呈現頁面(B網頁)
前言
Querystring是ASP.NET狀態管理(ASP.NET State Management)機制中常用到的傳遞資料方式之一
相信每個ASP.NET開發人員對此都很熟悉,此篇文章是自己對於Querystring資訊,整理給日後的自己看
有些事過30歲後就不一樣了XD

概述
Querystring(查詢字串)是附加在網頁URL結尾的資訊。主要是在Url上傳遞資料
可能是一個搜尋字串、頁碼、某項特定的指標…或類似的東西
在網址結尾加上一個問號(?)開始,每一組參數都是用「&」區隔開來,是一種KEY / Value的組合。
image
舉例來說(參考上圖),在Yahoo首頁搜尋引擎輸入「Hello world」後,在按下搜尋按鈕
會導頁到查詢結果頁面,並將符合搜尋字串相關資料呈現出來。
運作原理是透過Querystring作為資料傳遞,當你按下搜尋按鈕時,會將你在首頁(A網頁)輸入的搜尋字串「Hello world」傳遞到查詢結果呈現頁面(B網頁)


使用方式
取得Querystrnig參數內容方式:
  • C#:使用起來相當方便,可以用Requert.Querystring或是Request.Url.Query取得對應的值(註一)
// 設定
Response.Redirect("Default.aspx?參數名稱=" + 參數值)
Server.Transfer("Default.aspx?參數名稱=" + 參數值)

// 取得
// 指定特定key
string q = Request.QueryString["參數名稱"];
Response.Write(q);

// 取得集合
NameValueCollection nvc = Request.QueryString; 
foreach (string key in nvc.Keys)
{
    Response.Write("{0} => {1}", key, nvc[key]);
}
  • Client端:可以用Javascript寫一長串判斷來達到目的,在此建議可以用jQuery外掛(Query String Object)處理比較方便偷懶
/*使用jQuery外掛:jQuery String Object*/
// 設定
var newUrl = $.query.set("參數名稱", 參數值).toString();     

// 取得
var str = $.query.get('參數名稱');
註一:使用Request.QueryString會改變編碼,為確保接收參數不受影響,可以使用Request.Url.Query取得尚未解碼的原始字串,在進行解碼。


URL編碼
在URL網路標準規範中有規定,URL網址只能用英文字母和數字[0-9a-zA-Z]、一些特殊符號及特定保留字,才可以不經過編碼直接用在URL(註二)這意謂URL中如果有中文字的話,就必須經過編碼後使用。(註三)
在程式開發時,瀏覽器如果要在Querystring中帶有中文字或是特殊字元資料時,可以透過以下進行編碼&解碼
  • .Net Framework:
// 使用Server.UrlEncode進行編碼
String myURL = "http://www.ABC.com/Search.aspx?q=" + Server.UrlEncode("你好嗎");
Response.Write("<a href=" + myURL + "> 你好嗎 </a>");

// 使用Server.UrlDecode進行解碼
String myDecodedString = Server.UrlDecode(URI);
Response.Write("Decoded:" + myDecodedString );
  • Javascript:
// URL編碼:encodeURI():以UTF-8輸出,在每個字前面加上%
url = url + "?q=" + encodeURI("你好嗎");

// URL解碼:decodeURI()
document.write(encodeURI(URI)
在網路規範中沒有規定具體的編碼方法,瀏覽器本身可以自行設定,導致URL編碼有點混亂,開發上必須要更加小心
有關URL編碼的細節,我推薦大家可以參考「关于URL编码」,這篇文章中有詳細的介紹(我看完才比較瞭解,遮臉 XD)

註二:RFC 1783:"...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL."
註三:在google輸入「你好嗎」三個字時,按下搜尋之後,搜尋結果頁面網址呈現的查詢字串會是UTF-8編碼後「%E4%BD%A0%E5%A5%BD%E5%97%8E」


安全性
Querystring在使用上很方便,但以安全性考量來說,是有淺在安全性風險滴
因為可透過瀏覽器看到網址內容,清楚可見查詢的資訊,且使用者可任意修改
使用時有幾點建議(網路是很危險滴,大人們請多多留意阿)
  • 驗證資料:不要輕易相信從Client傳來的URL網址,對於Querystring的參數值是要經過驗證。有心的駭客要竊取網站資料,會將攻擊指令組成一長字串Querystring,進行SQL Inject攻擊(註四)
  • 敏感性資料:因為淺而易見,不要放置敏感性資料在Querystring
  • 長度限制:一些瀏覽器對於Querystring有長度限制,超過預設長度字元時,Querystring會被截斷,詳細可以參考ASP.NET 4.0 設定QueryString的最大長度
註四:SQL Inject可以參考黑暗大文章寫的游擊式的SQL Injection攻擊


其他議題
在查資料驗證自己的想法中,有查到很多相關Querystring的議題,在此先列出來,方便日後自己研究
[C#]用Base64編碼QueryStringQuerystring使用Base64加密法進行URL編碼
簡易的URL Rewriting隱藏Querystring:使用Url Rewrite 將Querystring隱藏起來
剔除特定QueryString參數:說明如何移除特定的Qquerystring參數


番外篇 - ASP.NET各種狀態比較表
在查資料的過程中,很幸運的找到一張圖說明ASP.NET的各種狀態(ASP.NET State Management)比較表
透過這張圖表,可以更詳細的瞭解各狀態之間的關係比較(圖表來源 Bubblog,如有侵權或是不妥請告知)
aspnetstate

參考
此篇文章是上網查詢自己整理的結果,如果內容有錯誤的地方,麻煩各位高手給予小弟指導
如果覺得此篇文章不錯,請幫忙點選「我要推薦」;讓我有持續努力的動力,謝謝

ASP.NET 狀態管理建議事項

关于URL编码

[HTTP]Http GET、POST Method

HttpUtility.ParseQueryString


[ASP.NET] State Management – Summary

[Tool] WebServiceStudio

WebServiceStudio 透過簡單的操作介面,分析Web Servie的小工具
介紹
在撰寫Web Service的時候,往往都要透過寫另一隻測試程式或「人工測試」的方式
來驗證Web Service輸出結果是否正確無誤,這種作法有時候是很耗時的,在無意中發現一個測試及分析Web Service的小工具

名稱:「WebService Studio 」
簡介:透過簡單的操作介面,分析Web Servie的小工具(聽說是微軟的人開發的)
下載網址:Downloads
Source Code:View Source Code

簡單介紹一下功能及操作
工具畫面
image
1. 輸入Web Service網址,輸入後按下Get
以上圖所示:輸入檢查EMail的Webservice的服務位置(http://www.webservicex.com/ValidateEmail.asmx?WSDL
2. WebServiceStudio 會分析輸入的Web Service的WSDL結構
  • Invoke: Input Value 為輸入的參數,Output為WebService回傳的結果。
                    舉例檢查Email來說,Input 輸入
    aaa@bbb.ccc,按下Invoke,output及回傳Boolean result = False
  • Response/Request:可以查看到Web Service資訊傳遞的狀況
  • WSDLs & Proxy:Web Service的WSDL XML格式內容
  • Message:紀錄程式的訊息

整體玩了一下,畫面操作很好上手,推薦給有需要的人參考^^

參考

2018年9月25日 星期二

[.NET] ASP.NET 狀態管理(State Management):ViewState

Web應用程式是沒有狀態(Stateless)的,從前面介紹的文章(Application、Page Life-Cycle)可以了解到,每次用戶端發送請求(Request)到伺服器端時,都會建立Web網頁類別的新執行個體。由於每個請求都是新的個體,這也代表每次來回存取時,網頁及控制項的資訊將會遺失。例如,根據預設,當使用者在網頁textbox控制項輸入「Hello world」,按下按鈕送出後,這項資訊就會傳送到伺服器。但伺服器在回傳(Response)時,卻不會將此資訊「Hello world」回傳到瀏覽器。接下來要分享的有關ViewState使用方式
前言
    Web應用程式是沒有狀態(Stateless)的,從前面介紹的文章(ApplicationPage Life-Cycle)可以了解到,每次用戶端發送請求(Request)到伺服器端時,都會建立Web網頁類別的新執行個體。由於每個請求都是新的個體,這也代表每次來回存取時,網頁及控制項的資訊將會遺失。例如,根據預設,當使用者在網頁textbox控制項輸入「Hello world」,按下按鈕送出後,這項資訊就會傳送到伺服器。但伺服器在回傳(Response)時,卻不會將此資訊「Hello world」回傳到瀏覽器。(廢話好像越來越多了…還是快點進入主題好了 XD)
ASP.NET 狀態管理
    ASP.NET為了解決此問題,ASP.NET 網頁架構提供多種狀態管理(State Management)機制,提供開發者保留來回存取(Postback)Web伺服器之間網頁與控制項的值,如下圖所示
ASP.NET State Management
用戶端
  • View state(檢視狀態)
  • Control state(控制項狀態)
  • Hidden fields(隱藏欄位)
  • Cookies
  • Query strings(查詢字串)
伺服器端
  • Application state(應用程式狀態)
  • Session state(工作階段狀態)
  • Profile Properties(設定檔屬性)
每個狀態使用方式、優缺點都不相同,詳細請參考ASP.NET 狀態管理概觀
ViewState是什麼?
    ViewState是儲存於用戶端(Client-Base)的狀態管理機制,用來保存來回存取(Postback)之間的網頁和控制項的值,根據預設(EnableViewState=true),當ASP.NET執行網頁時,會收集網頁和所有控制項中的值並透過單一編碼(Base64)的字串,存放於隱藏表單欄位(hidden field)的值(Value)屬性中,由於隱藏表單欄位是傳送至使用者端網頁的一部分,所有ViewState值會暫時存放在用戶端的瀏覽器中。當網頁執行完之後,在網頁上滑鼠點右鍵,查看網頁原始檔可以看到類似下面的資訊
ViewStateSample
    從上圖可以得知,存放在隱藏欄位的值是透過Base64編碼後的字串,使用Base64編碼的原因有兩項,第一 :Base64編碼後的字串方便Http傳輸,第二:讓它不容易閱讀
註:但可以透過工具來解析
另外,使用ViewState前需先注意,ASP.NET 網頁中必須要有伺服器表單<form runat=”server”>,伺服器執行網頁值,ASP.NET網頁架構才能讀取/儲存隱藏欄位ViewState資訊,否則ViewState將無法正常運作。
Viewstate In Life Cycle
    在網頁生命週期中 ,有兩個事件跟ViewState有關係的,分別是LoadViewState、SaveViewstate,可以參考下圖所示
ViewState
LoadViewState:讀取隱藏表單欄位(hidden field)的值,將讀到的ViewState字串解碼,透過LoadPageStateFromPersistenceMedium方法還原檢視的狀態
SaveViewState:在PreRenderComplete事件之後,此事件會收集網頁及網頁上的控制項狀態(值)的資訊,將收集好的值透過Base64編碼成字串,透過SavePageStateToPersistenceMedium()方法,存放在ID為「__VIEWSTATE」隱藏表單欄位(hidden field)的值中。
註:以上兩個階段只會發生在當網頁觸發Postback後,如果有需要的話,這兩個方法都可以被覆寫。
ViewState使用方式
    使用方式很簡單,是採用鍵(key)與值(value)的方式儲存/讀取,用法如下

// set
ViewState["Text"] = "123";

// get
string myValue = ViewState["Text"].ToString();
    Viewstate預設為啟用,由控制項來決定所需要存入的ViewState物件。但是有時候這類資訊對於應用程式毫無用處。當網頁上的控制項資料很多的時候(如GridView),網頁的ViewState大小也會跟著增加,會造成傳輸網頁受到影響,這時候就必須考慮是否真的需要使用ViewState,或者可以直接停用ViewState功能。
停用Viewstate的方式有三種,可以透過設定控制項、網頁、設定檔三種層級屬性 EnableViewState為false
控制項(Control)的ViewState

<asp:Label id=Label1 runat="server" EnableViewState="false" />
網頁(Page)的ViewState

<%@ Page ... EnableViewState="false" %>
設定檔(WebConfig)的ViewState

<pages enableViewState="false" />

Session還是ViewState
    有時候會發現,使用ViewState 並不是最好得選擇。最常使用的替代方案為Session,ViewState不適用於
  • 呈現大量資料:ViewState會增加網頁傳送至瀏覽器的大小(HTML負載)和表單大小,儲存、呈現大量資料時不適用。
  • 安全性的資料:雖然ViewState是經過編碼並可以選擇性加密,但若不將資料傳送至用戶端還是最安全的。
  • ViewState不支援的物件(類型):如GridView,ViewState支援序列化的物件(註1)可以存於ViewState,但不支援的物件產生很大的ViewState且速度較慢。
Session與ViewState的比較,請參考下圖
VS
註1:ViewState支援: 字串, 整數, 布林, 陣列, 陣列清單, 雜湊資料表, 自訂 TypeConverter (strings, integers, Booleans, arrays, ArrayList, hashtable, custom TypeConverters)
資料來源:aspnetresources.com
補充
有關ViewState還有很多有相關的資訊,我先將他列出來,提供有興趣的朋友可以研究
參考
    此篇文章是上網查詢自己整理的結果,如果內容有錯誤的地方,麻煩各位高手給予小弟指導
如果覺得此篇文章不錯,請幫忙點選「我要推薦」;讓我有持續努力的動力,謝謝 :D


2018年9月22日 星期六

[C#] 刪除 Array 陣列中指定的元素

前言
此文章紀錄如何移除 Array 陣列中指定的元素!
想要移除 Array 陣列中某項特定的元素,但發現因 Array 類別中,沒有類似 Remove 的方法可使用  QAQ
如下圖所示:
Array
查了一下Array 成員,發現公用方法中並沒有 Remove 方法,但在.NET Framework 2.0 中 Array 類別有實做 IListICollection 和 IEnumerable 泛型介面

使用 LINQ

int[] myNumbers = { 1, 30, 26, 53, 97, };

int myRemoveNum = 53;

myNumbers = myNumbers.Where(val => val != myRemoveNum).ToArray();
.NET Framework 3.5
namespace:System.Linq
透過 Enumerable.Where<TSource>方法,找出輸入資料符合條件的項目。

不使用 LINQ

int[] myNumbers = { 1, 30, 26, 53, 97, };

int myRemoveNum = 53;

myNumbers = Array.FindAll(myNumbers, val => val != myRemoveNum).ToArray();
.NET Framework 2.0
透過 Array.FindAll 泛型方法取得符合條件的所有元素。

以上情況都是假設元素是不重複的情況下使用,但如果陣列中有可能元素重複的話
可以透過 Array.IndexOf 方法找到第一個符合項目的資料,詳細可以參考 這裡

參考

Copyright © m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com