您的位置:首页 > 其它

[项目总结-原创]InternetRadio项目Ajax技术方案选型

2008-09-03 10:32 651 查看
1 综述

InternetRadio项目是一个基于Web2.0理念的面向大众的音乐共享站点,其大量使用了Ajax功能来提高用户的体验效果,并提高数据传输的效率,典型的比如Autosuggest、添加音乐评论等。为了便于相关代码的集中控制,InternetRadio项目从底层封装、Ajax框架选型、代码管理等方面加以控制。

Ajax框架选型:Prototype提供Ajax封装,Script.aculo.us提供UI封装。

代码集中管理:在App_Code/BusinessHandler.cs中统一控制Ajax内容的输出。

Server端底层实现:利用C#的反射机制,实现Ajax客户端对Server端API的调用。

1.1 Ajax和UI框架选型

InternetRadio选用Prototype(http://www.prototypejs.org/)作为底层Ajax底层框架,包括Ajax API封装和 Javascript扩展;另外选择Script.aculo.us(http://script.aculo.us/)作为UI框架,利用其包括Autosuggest等在内的UI特性。

另外,作为辅助,增加Javascript/AjaxPublic.js进一步封装Prototype API,提供一系列方法简化Ajax客户端调用,比如PreparePostData()、AjaxGetFromUrl()、AjaxGetFromUrlSynchronous()等。

1.2 基于反射的Ajax远程调用实现

与Ajax.NET Professional(http://www.ajaxpro.info/)类似,InternetRadio项目也支持Ajax客户端对Server端API的直接调用,比如:

function Init() {

new Ajax.Autocompleter(

'<%=KeywordTextBox.ClientID %>',

'AutoSuggestion',

'../BusinessHandler/AutosuggestForKeywordSearch.ajax',

{

tokens:",",

paramName:"ajax_keyword",

callback: AutoSuggestionCallback

}

);

}

在上述代码中,Ajax直接调用Server端BusinessHandler类的AutosuggestForKeywordSearch方法。Suryani.Ajax Project提供了上述调用的支持和实现。

提供Suryani.Ajax.Service.ServiceManager.Register(string package, Type serviceType)方法,用于注册要开放给客户端Ajax调用的类。ServiceManager将所注册的类保存在全局变量modules中。

开放Suryani.Ajax.Utility.AjaxConfiguration.Register(Dictionary<string, Type> source)供Global.asax调用,用于在Website启动时向Server注册全部要开放给客户端调用的类。AjaxConfiguration.Register()方法调用ServiceManager.Register()方法完成所有类的注册。

增加Suryani.Ajax.Service.AjaxMethodAttribute自定义标签类,用于标识要开放给客户端调用的类方法。Suryani.Ajax.Service.ServiceManager.Register()方法将遍历所注册类的全部方法,将附加AjaxMethod自定义标签的所有方法保存在modules全局变量中,以备客户端Ajax调用。

提供Suryani.Ajax.Service.AjaxHttpHandler自定义HttpHandler类,拦截来自客户端的所有Ajax 请求(该请求的URL以".ajax"结尾),解析URL,利用反射的原理从全局变量modules中获取已注册的类和方法,并将执行结果输出到客户端。



初始化并注册类



Ajax远程调用Server端API的过程

1.3 Ajax代码集中管理

由于InternetRadio项目中大量用到Ajax功能,客户端Ajax可以直接调用Server端的API,而且每一个Ajax请求都需要Server端根据请求组织要交付Browser端的内容。为了对这些代码集中管理,我们在App_Code中增加了BusinessHandler类,作为Browser端与Server端的中介,负责请求的响应和内容的组织。而且整个项目中,只开放BusinessHandler供客户端直接调用调用。比如:

/// <summary>

/// 根据标签关键词搜索对应的标签

/// </summary>

/// <param name="keyword"></param>

[AjaxMethod]

public string FindTagsByKeyword(string keyword)

{

StringBuilder builder = new StringBuilder();

try

{

IList<Tag> tags = TagManager.FindTagsByKeyword(keyword);

if (tags != null)

{

builder.Append("<ul>");

foreach (Tag tag in tags)

{

builder.Append(string.Format(CultureInfo.CurrentCulture, "<li>{0}</li>", tag.TagName));

}

builder.Append("</ul>");

}

}

catch { }

return builder.ToString();

}

1.4 典型应用

1.4.1 简单的Ajax应用:添加歌曲标签

URL:http://nyxm.vicp.net:5052/Music/Music.aspx?MusicId=26553

功能描述:为当前歌曲添加相应的自定义标签

程序主文件:UserControl/MusicInfoControl.ascx

代码流程:

单击"保存"按钮:SaveTagButtonOnClick()

function SaveTagButtonOnClick()

{

var tagName = $('<%= TagNameTextBox.ClientID %>').value;

var musicId=$('<%= MusicIdHiddenField.ClientID %>').value;

var url = "/BusinessHandler/AddTag.ajax?ajax_tagName=" + encodeURIComponent(tagName) + "&ajax_musicId="+musicId;

AjaxGetFromUrl(url,SaveTagCallBack);

$('<%= TagNameTextBox.ClientID %>').value="";

}

调用AjaxGetFromUrl()方法,通过Prototype向Server端发起Ajax请求。

AjaxHttpHandler拦截到Ajax请求,执行BusinessHandler.AddTag()方法,向Browser输出以<span>形式组织的标签列表:

/// <summary>

/// 添加歌曲的标签

/// </summary>

/// <param name="tagName"></param>

/// <param name="musicId"></param>

[AjaxMethod]

public string AddTag(string tagName, int musicId)

{

int userId = ContextAccessor.Current.UserId;

string createBy = ContextAccessor.Current.UserName;

TagManager.Add(tagName, createBy, musicId, userId);

IList<Tag> tags = TagManager.FindTagsByMusicId(musicId);

StringBuilder returnString = new StringBuilder();

foreach (Tag tag in tags)

{

returnString.Append("<span>");

returnString.Append(PageContentBuilder.BuildTagSearchLink(tag.TagName, tag.TagName));

returnString.Append("</span>  \n");

}

return returnString.ToString();

}

回调函数SaveTagCallBack()检测到 Server端返回的标签列表,将其呈现在页面上:

function SaveTagCallBack(request)

{

$('TagListDiv').innerHTML = request.responseText;

}





1.4.2 结合Script.aculo.us的应用:Autosuggest

URL:http://nyxm.vicp.net:5052/Index.aspx

功能描述:根据关键词框的输入,自动提示补录。

程序主文件:UserControl/ QuickSearchControl.ascx

代码流程:

页面初始化:

当页面载入的时候,利用Script.aculo.us的Autocompleter控件实现对关键词输入框的监控。

function Init() {

new Ajax.Autocompleter(

'<%=KeywordTextBox.ClientID %>',

'AutoSuggestion',

'../BusinessHandler/AutosuggestForKeywordSearch.ajax',

{

tokens:",",

paramName:"ajax_keyword",

callback: AutoSuggestionCallback

}

);

}

Event.observe(window,'load',Init);

当用户在关键词输入框输入关键词时,Autocompleter控件向Server端发起Ajax请求,检索提示内容。AjaxHttpHandler拦截该请求,执行BusinessHandler.AutosuggestForKeywordSearch()方法:

/// <summary>

/// 根据关键词检索对应的音频

/// </summary>

/// <param name="searchType"></param>

/// <param name="keyword"></param>

/// <returns></returns>

[AjaxMethod]

public string AutosuggestForKeywordSearch(string searchType, string keyword)

{

if (searchType.Equals(WebConstants.Search_Player, StringComparison.OrdinalIgnoreCase))

{

return FindPlayersByKeyword(keyword);

}

else if (searchType.Equals(WebConstants.Search_Music, StringComparison.OrdinalIgnoreCase))

{

return FindMusicByKeyword(keyword);

}

else if (searchType.Equals(WebConstants.Search_Tag))

{

return FindTagsByKeyword(keyword);

}

return string.Empty;

}

Server端以无序列表<ul>的形式组织返回给Browser端的Autosuggest内容列表。

回调函数AutoSuggestionCallback()将Autosuggest内容呈现在页面上:

function AutoSuggestionCallback(obj) {

var searchType = "Player";

if($("<%=PlayerRadioButton.ClientID %>").checked == true) searchType = "Player";

else if($("<%=MusicRadioButton.ClientID %>").checked == true) searchType = "Music";

else if($("<%=TagRadioButton.ClientID %>").checked == true) searchType = "Tag";

return "ajax_searchType="+searchType+"&ajax_keyword="+ encodeURIComponent(obj.value);

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: