深入Atlas系列:探究Application Services(3) - 自定义客户端Profile Service支持
2006-11-05 21:32 by 老赵, 3418 visits一、使用自定义类替换Sys.Services.ProfileService对象
一般来说,这是最容易想到的办法。我们可以写一个类继承Sys.Services._ProfileService类(这个类完全通过prototype扩展,因此对于继承非常友好),甚至完全重写一个类,这个一般就看具体情况了。假设我们已经定义了这么一个类“Jeffz.Services.ProfileService”,并将其包含在MyProfile.Service.js中,就要开始使用了。那么还要注意些什么呢?
需要注意的就是顺序,我们一般会使用ScriptManager引入该JS,如下:
<Scripts>
<asp:ScriptReference Path="MyProfileService.js" />
</Scripts>
<ProfileService LoadProperties="ZipCode, Address.City" Path="MyProfile.asmx"/>
</asp:ScriptManager>
我们为ProfileService节点加上了LoadProperties属性,表明需要预加载Profile中的ZipCode和Address这个Profile Group下的City属性。另外,我们将EnablePartialRendering属性设为了False,避免出现多余的代码。于是,生成如下的代码如下:
<script type="text/javascript">
<!--
Sys.Services.ProfileService.set_path('/MyProfile.asmx');
Sys.Services.ProfileService.properties = Sys.Serialization.JavaScriptSerializer.deserialize('{\"ZipCode\":\"\"}');
Sys.Services.ProfileService.properties.Address = new Sys.Services.ProfileGroup(Sys.Serialization.JavaScriptSerializer.deserialize('{\"City\":\"\"}'));
Sys.Services.AuthenticationService._set_authenticated(true);
// -->
</script>
<script src="MyProfileService.js" type="text/javascript"></script>
第一行引入的是MicrosoftAjax.js,它之中定义了ASP.NET AJAX中默认的ProfileService,而紧接着就是对于ProfileService的使用:设定其Path以及预加载的Properties。在引入之后千万不能忘了要将这些信息进行保留。但是这两者之间无法插入任何代码,因此我们可以在MyProfileService.js里添加如下的代码,以保留这些信息:
if (!path)
{
path = Sys.Services._ProfileService.WebServicePath;
}
var properties = Sys.Services.ProfileService.properties;
var newInstance = new Jeffz.Services.ProfileService();
newInstance.set_path(path);
newInstance.properties = properties;
Sys.Services.ProfileService = newInstance;
当然,可能代码会根据实际情况略有不同,但是注意JavaScript引入以及执行的顺序,在做任何自定义工作时都是非常重要的。
有人也许会问,既然已经重新定义了自己的实现,为什么还要将其“伪装”成默认的ProfileService呢?因为这种“自定义”其实并不为“官方”所承认,这么做能够保证了兼容性,保证了第三方的组件也能使用Profile Service,即使它们没有“意识”到没有使用ASP.NET AJAX提供的默认Profile Service。
二、直接修改Sys.Services._ProfileService.prototype
Sys.Services._ProfileService完全通过prototype定义,这不光非常有利于“继承”,它的一个很大的特点就是能够通过直接修改prototype而做到修改类的行为,它对于已经实例化的对象依然有用。例如之需要如下的代码就能够为它的load函数提供一个trace功能:
Sys.Service._ProfileService.prototype.load = function(propertyNames, loadCompletedCallback, failedCallback, userContext)
{
for (var i = 0; i < propertyNames.length; i++)
{
debug.trace(propertyNames[i]);
}
Sys.Service._ProfileService.prototype._originalLoad(propertyNames, loadCompletedCallback, failedCallback, userContext);
}
事实上,如果需要修改类库已有的行为,最方便的就是这种做法。从这里可以看出JavaScript的灵活性,以及使用prototype的好处。
其实这个只能算是小技巧吧……