在 ASP.NET Core 3.1 專案中,我ClaimsIdentity在用戶登錄后向物件添加了一些自定義宣告。
public void ConfigureServices(IServiceCollection services)
{
...
options.Events.OnTicketReceived = context =>
{
var claimsIdentity = (ClaimsIdentity)context.Principal.Identity;
// custom claims
AddCustomClaims(claimsIdentity);
return;
};
...
}
private void AddCustomClaims(ClaimsIdentity claimsIdentity)
{
claimsIdentity.AddClaim(new Claim("test1", "helloearth!!!"));
claimsIdentity.AddClaim(new Claim("test2", "helloplanet!!!"));
claimsIdentity.AddClaim(new Claim("test3", "helloworld!!!"));
}
如果我在 上設定斷點return;并查看context.Principal.Identity物件,則所有三個宣告都會出現在那里。
我不明白為什么?我以為我制作了一個副本context.Principal.Identity并且AddCustomClaims方法只操作了那個副本。但不知何故,原始物件受到了影響。
uj5u.com熱心網友回復:
這是變數和參考型別之間由來已久的混淆。
簡單地說,.NET 中有兩大型別別,值型別和參考型別。當你在混合中引入變數時,保存值型別的變數保存整個值,就像一個數字,而保存參考型別的變數只保存對一個物件的參考,而該物件在計算機記憶體中的其他地方。
您.Identity在那里的屬性包含這樣一個參考,對參考型別的實體,因此當您這樣做時
var claimsIdentity = (ClaimsIdentity)context.Principal.Identity;
您實際上并沒有制作物件的另一個副本,而是制作了對它的參考的副本。我喜歡用房子來解釋這個。您的物件實體是某處的一所房子,而變數就像帶有該房子地址的便利貼。
你的宣告沒有蓋另一棟房子,它只是做了另一個帶有相同地址的便利貼。
或者在 .NET 術語中,您的變數claimsIdentity現在擁有與在 中找到的相同的參考.Identity,但它們都參考相同的單個物件,位于記憶體中的某處。
所以當你改變那個物件時,你改變了那個物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/386288.html
