.NET / PowerShell 範例:收發含 Cookie 的 HTTP Request
0 |
遇到傳送 HttpRequest 時需附帶 Cookie 的需求,順手整理 .NET Framework、.NET 6、PowerShell 範例供未來參考。
模擬情境為網站有 AutoRedirect.aspx 及 ShowAndSetCookie.aspx 兩支程式,前者單純導向 ShowAndSetCookie.aspx:
<%@Page Language="C#"%>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
Response.Redirect("ShowAndSetCookie.aspx");
}
</script>
ShowAndSetCookie.aspx 則讀取名為 ReqId 的 Cookie 並顯示,再設定名為 RespId 的 Cookie:
<%@Page Language="C#"%>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
var cookie = Request.Cookies["ReqId"];
Response.Write("Cookie['ReqId'] = " + (cookie == null ? "N/A" : cookie.Value));
Response.Cookies.Add(new HttpCookie("RespId") {
Value = DateTime.Now.ToString("mmssfff")
});
}
</script>
.NET Framework
WebClient 用起來最簡便但不支援 CookieContainer,我們可透過繼承技巧擴充它。 CookieContainer 加入 Cookie 時記得要指定 Domain,WebClient 才知道連哪個站台要附帶該 Cookie。取回 Cookie 時也要指定 Uri,以便取出屬於該網站的 Cookie:
using System;
using System.Net;
namespace WebClientWithCookie
{
internal class Program
{
static void Main(string[] args)
{
var wc = new CookieWebClient();
var url = "http://localhost/aspnet/CookieTest/AutoRedirect.aspx";
wc.CookieContainer.Add(new Cookie
{
Name = "ReqId",
Value = DateTime.Now.ToString("mm:ss.fff"),
Domain = new Uri(url).Host
});
Console.WriteLine(wc.DownloadString(url));
Console.WriteLine($"RespId=" + wc.CookieContainer.GetCookies(new Uri(url))["RespId"]?.Value);
Console.ReadLine();
}
}
public class CookieWebClient : WebClient
{
public CookieContainer CookieContainer { get; set; } = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
var webReq = base.GetWebRequest(address);
var httpWebReq = webReq as HttpWebRequest;
if (httpWebReq != null) httpWebReq.CookieContainer = CookieContainer;
return webReq;
}
}
}
實測結果:
.NET 6
.NET Core / .NET 6 建議改用 HttpClient,一樣是用 CookieContainer。先建立 HttpClientHandler 設定傳輸屬性,其中包含 CookieContainer 屬性,用 HttpClientHandler 做為 HttpClient 的建構參數,其餘寫法與 .NET Framework 大同小異。
var handler = new HttpClientHandler();
var url = "http://localhost/aspnet/CookieTest/AutoRedirect.aspx";
handler.CookieContainer.Add(new System.Net.Cookie
{
Name = "ReqId",
Value = DateTime.Now.ToString("mm:ss.fff"),
Domain = new Uri(url).Host
});
var client = new HttpClient(handler);
var response = await client.GetAsync(url);
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
Console.WriteLine($"RespId=" + handler.CookieContainer.GetCookies(new Uri(url))["RespId"]?.Value);
實測成功:
PowerShell
PowerShell 一樣是靠 CookieContainer。使用時先建立 WebRequestSession,其餘操作與 .NET 相同。
$url = "http://localhost/aspnet/CookieTest/AutoRedirect.aspx"
$sess = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$cookie = New-Object System.Net.Cookie
$cookie.Name = "ReqId"
$cookie.Value = [System.DateTime]::Now.ToString("mm:ss.fff")
$cookie.Domain = (New-Object Uri($url)).Host
$sess.Cookies.Add($cookie)
(Invoke-WebRequest $url -WebSession $sess).Content
"RespId=" + $sess.Cookies.GetCookies((New-Object Uri($url)))["RespId"].Value
測試 OK。
Samples for sending and receiving cookies with .NET WebClient, HttpClient and PowerShell.
Comments
Be the first to post a comment