日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入Atlas系列:探究Application Services(2) - 自定义服务器端Profile Service支持

發(fā)布時間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入Atlas系列:探究Application Services(2) - 自定义服务器端Profile Service支持 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  在上一篇文章中,我們討論了使用ASP.NET AJAX默認的Profile Service。一般來說,它已經能夠迎合大多數應用的需要了。不過除此之外,ASP.NET AJAX還提供了讓我們自定義Profile Service的機制。要自定義Profile Service,一般來說要分為兩步:


一、在ScriptManager中指定Profile Service的Path

在ASP.NET AJAX的客戶端腳本中,如果沒有使用Sys.Services.ProfileService.set_path方法來指定一個提供Profile Service的地址,就會使用默認的地址,它會使ASP.NET AJAX的Profile Service使用程序集中特定的類。一般來說,我們不需要手動調用Sys.Services.ProfileService.set_path方法,只需要在ScriptManager中指定即可。如下:
<asp:ScriptManager?ID="ScriptManager1"?runat="server"?ScriptMode="Debug">
????
<ProfileService?Path="CustomProfileService.asmx"?/>
</asp:ScriptManager>
打開頁面后,可以在頁面中發(fā)現(xiàn)如下的JavaScript代碼:
Sys.Services.ProfileService.set_path('/CustomProfileService.asmx');
出現(xiàn)“/”是因為我測試的頁面在根目錄下。因此,Profile Service就會使用指定的Web Service,而不是默認的Web Service類。


二、實現(xiàn)自己的Web Service類

指定了自己的Web Service類,自然就要實現(xiàn)自己的類了。事實上,我們要實現(xiàn)的就是3個方法。就這個方面來說,ASP.NET AJAX中Profile Service使用的默認的Web Service類Microsoft.Web.Profile.ProfileService是我們絕佳的參考。因此,我們在這里分析一下這些方法,對于我們的自定義工作是非常有幫助的。

可能需要注意的一點是,我們在實現(xiàn)這些方法時,從理論上來講參數類型不用完全和Microsoft.Web.Profile.ProfileService中的方法完全相同。ASP.NET AJAX的能夠根據參數的類型盡可能地將獲得的JSON字符串轉換成需要的類型。不過事實上,似乎Microsoft.Web.Profile.ProfileService里那些方法的參數選擇已經是非常合理的。另外,由于客戶端Profile Service代碼不太容易修改(事實上客戶端也不是不能擴展,最極端的情況,不就是我們自己實現(xiàn)一個ProfileService嗎?),為了保持返回的JSON字符串能夠被正確處理,這些方法的返回值一般來說可以不變。


1、GetAllPropertiesForCurrentUser方法

這個方法的作用是獲得當前用戶所有的Profile信息,它沒有輸入的參數,返回的JSON字符串形式如下:
{
????'ZipCode'?:?...,
????'Address.City'?:?...,
????'Address.State'?:?...
}

它通過GroupName.ProfileName的形式來表示Profile Group,Group中的每一個Profile需要分別列出,而“...”則表示對應Profile值的JSON字符串。

在Microsoft.Web.Profile.ProfileService里,這個方法的代碼如下:
[WebMethod]
public?IDictionary<string,?object>?GetAllPropertiesForCurrentUser()
{
??? ProfileService.CheckProfileServicesEnabled();
???
return?ProfileService.GetProfile(HttpContext.Current,?null);
}


2、GetPropertiesForCurrentUser方法

這個方法的作用是獲得當前用戶指定的Profile信息,它的輸入JSON字符串形式如下:
['ZipCode',?'Address.City',?'Address.State']
它的返回值的JSON字符串和GetAllPropertiesForCurrentUser相同,就不再贅述了。

在類中,這個方法的代碼如下:
[WebMethod]
public?IDictionary<string,?object>?GetPropertiesForCurrentUser(string[]?properties)
{
????ProfileService.CheckProfileServicesEnabled();
????
return?ProfileService.GetProfile(HttpContext.Current,?properties);
}

可以看到,GetAllPropertiesForCurrentUser和GetPropertiesForCurrentUser中都是使用了ProfileService.GetProfile靜態(tài)方法來獲得結果的,我們來仔細看一下這個方法的實現(xiàn)。如下:
GetProfile靜態(tài)方法
?1?internal?static?IDictionary<string,?object>?GetProfile(HttpContext?context,?string[]?properties)
?2?{
?3?????//?當前用戶的Profile
?4?????ProfileBase?profile?=?context.Profile;
?5?
?6?????//?如果沒有profile,則返回null
?7?????if?(profile?==?null)
?8?????{
?9?????????return?null;
10?????}
11?
12?????//?作為結果返回的字典
13?????IDictionary<string,?object>?dictResult?=?new?Dictionary<string,?object>();
14?
15?????//?如果properties為null,表示需要返回所有的參數
16?????if?(properties?==?null)
17?????{
18?????????//?枚舉web.config中注冊的每一個Profile屬性設置
19?????????foreach?(SettingsProperty?property?in?ProfileBase.Properties)
20?????????{
21?????????????//?獲得Profile屬性名稱
22?????????????string?name?=?property.Name;
23?
24?????????????//?如果web.config配置文件里沒有定義ReadAccessProperties,
25?????????????//?或者該Profile屬性被定義在ReadAccessPropeties中。
26?????????????if?((ProfileService._allowedGet?!=?null)?&&?ProfileService._allowedGet.ContainsKey(name))
27?????????????{
28?????????????????//?則準備輸出
29?????????????????dictResult.Add(name,?profile[name]);
30?????????????}
31?????????}
32?
33?????????//?返回結果
34?????????return?dictResult;
35?????}
36?
37?????//?枚舉參數的每一項,它們是需要輸出的Profile信息
38?????foreach?(string?prop?in?properties)
39?????{
40?????????//?如果web.config配置文件里沒有定義ReadAccessProperties,
41?????????//?或者該Profile屬性被定義在ReadAccessPropeties中。
42?????????if?((ProfileService._allowedGet?!=?null)?&&?ProfileService._allowedGet.ContainsKey(prop))
43?????????{
44?????????????//?則準備輸出
45?????????????dictResult.Add(prop,?profile[prop]);
46?????????}
47?????}
48?
49?????//?返回結果
50?????return?dictResult;
51?}

這個方法還是非常容易理解和編寫的,不需要涉及到任何序列化或者反序列化操作,那些工作完全由ASP.NET的Web Service Access機制代為完成了。


3、SetPropertiesForCurrentUser方法

這個方法的作用是保存當前用戶的Profile信息,它的輸入JSON字符串形式如下:
{
????'ZipCode'?:?...,
????'Address.City'?:?...,
????'Address.State'?:?...
}

而它返回的則是正確保存的Profile數量。代碼如下:
[WebMethod]
public?int?SetPropertiesForCurrentUser(IDictionary<string,?object>?values)
{
????ProfileService.CheckProfileServicesEnabled();
????
return?ProfileService.SetProfile(HttpContext.Current,?values);
}

起關鍵作用的方法是ProfileService.SetProfile靜態(tài)方法,我們來仔細看一下這個方法:
SetProfile靜態(tài)方法
?1?internal?static?int?SetProfile(HttpContext?context,?IDictionary<string,?object>?profileValues)
?2?{
?3?????//?如果沒有提供保存的Profile值,則返回0
?4?????if?((profileValues?==?null)?||?(profileValues.Count?==?0))
?5?????{
?6?????????return?0;
?7?????}
?8?
?9?????//?獲取當前用戶的Profile值
10?????ProfileBase?profile?=?context.Profile;
11?
12?????//?如果當前沒有Profile,也返回0
13?????if?(profile?==?null)
14?????{
15?????????return?0;
16?????}
17?
18?????int?count?=?0;
19?
20?????//?獲得當前的Serializer,
21?????//?以獲取JavaScriptTypeResolver和JavaScriptConverter的支持
22?????WebServiceData?data?=?WebServiceData.GetWebServiceData(context,?context.Request.FilePath);
23?????JavaScriptSerializer?serializer?=?data.Serializer;
24?
25?????//?枚舉提供的每一個Profile的值
26?????foreach?(KeyValuePair<string,?object>?pair?in?profileValues)
27?????{
28?????????//?獲得Profile的名稱
29?????????string?name?=?pair.Key;
30?????????if?((ProfileService._allowedSet?!=?null)?&&?ProfileService._allowedSet.ContainsKey(name))
31?????????{
32?????????????//?通過Profile名稱獲得在web.config中的Profile定義
33?????????????SettingsProperty?property?=?ProfileBase.Properties[name];
34?????????????//?如果存在這個Profile屬性
35?????????????if?(property?!=?null)
36?????????????{
37?????????????????//?獲得Profile屬性的類型
38?????????????????Type?type?=?property.PropertyType;
39?????????????????//?調用內部的ObjectConverter.ConvertObjectToType方法進行轉換,
40?????????????????//?然后賦值給相應的Profile
41?????????????????profile[name]?=?ObjectConverter.ConvertObjectToType(pair1.Value,?type,?serializer);
42?
43?????????????????//?已經保存的Profile屬性數量加1
44?????????????????count++;
45?????????????????continue;
46?????????????}
47?????????}
48?????}
49?
50?????return?count;
51?}

方法也不難理解,不過可以需要對于ASP.NET AJAX的序列化與反序列化能力有一定了解,例如第22和23行構造了一個JavaScriptSerializer的目的是使用包含在WebServiceData內的JavaScriptTypeResolver信息,以此獲得從字符串形式的type描述到確定type類型的映射關系。這其實是一個非常有用的特性,不過有點讓人想不通的是,在目前的WebServiceData中由于沒有方法添加自定義的JavaScriptTypeResolver,因此這個功能的效用為0。難道未來的版本會有辦法利用到這個特性?拭目以待吧,雖然我覺得比較困難。

我們也可以看到,這個方法中使用了內部的ObjectConverter.ConvertObjectToType方法來將一個嵌套的Dictionay和List轉換為指定的類型。如果我們要使用這個方法,應該怎么做呢?事實上,ASP.NET AJAX提供了我們一定的序列化與反序列化能力。請看JavaScirptSerializer的公有實例方法ConvertToType<T>的實現(xiàn):
public?T?ConvertToType<T>(object?obj)
{
????
return?(T)?ObjectConverter.ConvertObjectToType(obj,?typeof(T),?this);
}

它直接調用了內部的ObjectConverter.ConverObjectToType方法,這不就是我們所需要的功能嗎?

等一下!別高興的太早!請注意,這是一個范型方法!我們這里只能獲得一個Profile屬性的類型對象,不能在編譯期指定調用哪種具體類型的范型方法,也就是說,我們不能在這里簡單地使用這個范型方法。我們在這里需要對范型方法的調用進行“后期綁定”,因為只有在執(zhí)行期才能獲得范型的類型。

后期綁定?這不就是Reflection提供的功能嗎?因此,我們可以使用.NET Framework 2.0的Reflection機制,它已經對于范型類型提供了支持。在這里,我們可以這么做:
JavaScriptSerializer?serializer?=?new?JavaScriptSerializer();

Type?type?
=?value.GetType(); //?獲得所需的Profile屬性的Type對象
MethodInfo?info?
=?typeof(JavaScriptSerializer).GetMethod("ConvertToType").MakeGenericMethod(type);
return?info.Invoke(serializer,?new?object[]?{?value?});
這樣,我們就實現(xiàn)了對于范型方法調用的“后期綁定”:在執(zhí)行期才決定調用哪個具體類型的范型方法。這么做會有性能損失,例如查找ConvertToType方法并構造相應的范型的MethodInfo,但是如果我們使用Dictionary<Type, MethodInfo>將type和它所對應的MethodInfo保存起來,可以在一定程度上的減少性能的損失。不過使用Method.Invoke造成的性能損失就無法避免了。

另外,我打算在接下來的文章中詳細分析一下ASP.NET AJAX中提供給開發(fā)人員的序列化與反序列化能力,以及它們是如何配合JavaScriptTypeResolver與JavaScriptConverter提供一定的自定義能力。





我們現(xiàn)在已經知道了如何自定義服務器端的Profile Service支持,但是如果我們一直使用客戶端的“標準”功能,還談不上“自定義”或者“擴展”。那么在下一片文章中,我們一起來討論一下自定義客戶端的Profile Service支持吧。

轉載于:https://www.cnblogs.com/JeffreyZhao/archive/2006/11/04/Inside_Atlas_Series__Investigate_the_Application_Services_2.html

總結

以上是生活随笔為你收集整理的深入Atlas系列:探究Application Services(2) - 自定义服务器端Profile Service支持的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 伊人久久九 | 狠狠操一区二区 | 日本一区二区在线免费 | 国产精品国产三级国产专区53 | 全部孕妇毛片丰满孕妇孕交 | 女人av在线 | 精品一区二区三区成人免费视频 | 伊人称影院| 亚洲欧洲日本一区二区三区 | 国产手机av在线 | 欧美xxxx18 | 夜夜激情网 | 久草色在线| 久久中文精品 | 天天夜夜啦啦啦 | 国产成人h | 亚洲永久网站 | 天天干天天色天天射 | 中文字幕乱码视频 | 色综合网站| 日韩人妻精品一区二区三区 | 天天操免费视频 | 国产精品中文无码 | 亚洲欧美大片 | 日日草夜夜草 | 日韩黄色免费视频 | 影音先锋在线播放 | bangbros性欧美18 | 国产老妇视频 | 青青草亚洲| 狠狠爱综合 | 不卡中文av | 中国爆后菊女人的视频 | 秋霞影院午夜丰满少妇在线视频 | 密臀久久 | 91网站在线播放 | 91秘密入口| 在线观看免费成人 | 成人深夜影院 | 成人一级生活片 | 国产中文网 | 欧美aaaaaa | 日韩精品中文字幕在线 | 天堂av在线网| 国产精品啪 | 免费色av | 国产一区精品久久 | 天天干天天做 | 可以在线观看的黄色 | 91美女精品 | 午夜激情久久久 | 成 人 免费 黄 色 | 日韩av大全| 99久久久无码国产精品性 | 国产大屁股喷水视频在线观看 | 亚洲天堂男人av | 成人性生交视频免费观看 | 在线欧美激情 | 泷泽萝拉在线播放 | 成人午夜精品一区二区 | 日韩成人精品一区二区 | 黄色a一片| 污片免费看| 欧美射图 | 天天插美女 | 色哟哟在线 | 五月中文字幕 | 一区二区三区91 | 啪啪福利社 | 中文无码一区二区三区在线观看 | 久操热 | 日韩大片在线 | www精品国产| 久久欧美精品 | 国产av一区二区三区 | 五月激情六月丁香 | 免费av网址大全 | 日本不卡视频一区二区 | 亚洲视频手机在线观看 | 日韩在线观看网址 | 中文人妻熟妇乱又伦精品 | 日本高清不卡码 | 黄色avav | 91天堂素人 | 91重口味 | 日日草视频 | 亚洲一二三区在线观看 | 日韩成人一区二区三区 | 阿的白色内裤hd中文 | 欧美交受高潮1 | av日韩一区 | 懂色av一区二区三区 | 成人av高清在线 | 亚洲国产第一页 | 久久婷婷综合色 | 亚洲自拍第三页 | 97人妻精品一区二区三区软件 | 久久综合在线 | 手机看片日韩福利 |