|
|
|||||||||||||||||||||||||||||
|
Создаем контрол по технологии Microsoft ASP.NET AJAXИсточник: progblog
Пришёл век эпохи Web 2.0. Обычные решения на основе WebForms уже перестают соответствовать современным требованиям к web-проектам. Что-же нам предлагает Microsoft? Хм, достаточно мощное решение - Microsoft ASP.NET AJAX. Давайте попробуем создать простейшее приложение и посмотрим как оно устроено. Первое, что необходимо сделать, это создать проект типа ASP.NET Web Application. Затем создадим папку под наш будущий контрол, я на назвал её "MyControl".Далее нам понадобится добавить туда 4 файла: MyControl.cs, MyControl.debug.js, MyControl.js, MyControlService.asmx. MyControl.cs - отвечает за серверную инициализацию контрола. MyControl.debug.js, MyControl.js - клиентский код. Файл .debug.js содержит полную клиентскую debug-версию разрабатываемого контрола,в отличие от MyControl.js, в котором должен содержаться упакованный javascript-код. ASP.NET автоматизированно вызывает тот или иной клиентский код, в зависимости от режима запуска проекта: debug или release. Файл MyControlService.asmx является WebService'ом и отвечает за обработку Ajax-запросов к серверу нашего контрола, на клиенте вызовы осуществляются с помощью класса Sys.Net.WebServiceProxy. Итак, MyControl.cs: 1. using System; 2. using System.Collections.Generic; 3. using System.Linq; 4. using System.Web; 5. using System.Web.UI; 6. using System.ComponentModel; 7. 8. namespace WebApplication1.MyControl 9. { 10. public class MyControlScript : System.Web.UI.ScriptReference 11. { 12. public MyControlScript() 13. : base("~/MyControl/MyControl.js") { 14. ScriptMode = ScriptMode.Inherit; 15. } 16. } 17. 18. public class MyControl : ScriptControl 19. { 20. [UrlProperty] 21. [DefaultValue("")] 22. public string ServicePath { get; set; } 23. 24. protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors() { 25. if (string.IsNullOrEmpty(ServicePath)) 26. throw new InvalidOperationException("'ServicePath' must be specified"); 27. 28. var control = new ScriptControlDescriptor("WebApplication1.MyControl.MyControl", this.ClientID); 29. control.AddProperty("servicePath", ResolveUrl(ServicePath)); 30. 31. yield return control; 32. } 33. 34. protected override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences() { 35. return new ScriptReference[] 36. { 37. new MyControlScript() 38. }; 39. } 40. 41. public override void RenderBeginTag(HtmlTextWriter writer) { 42. } 43. 44. public override void RenderEndTag(HtmlTextWriter writer) { 45. } 46. 47. protected override void RenderContents(HtmlTextWriter writer) { 48. 49. writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID); 50. writer.RenderBeginTag(HtmlTextWriterTag.Div); 51. writer.Write("<a href=\"#\" id=\""+this.ClientID+"_anchor\">получить данные с сервера</a>"); 52. writer.RenderEndTag(); 53. } 54. } 55. } 1. using System; 2. using System.Collections.Generic; 3. using System.Linq; 4. using System.Web; 5. using System.Web.UI; 6. using System.ComponentModel; 7. 8. namespace WebApplication1.MyControl 9. { 10. public class MyControlScript : System.Web.UI.ScriptReference 11. { 12. public MyControlScript() 13. : base("~/MyControl/MyControl.js") { 14. ScriptMode = ScriptMode.Inherit; 15. } 16. } 17. 18. public class MyControl : ScriptControl 19. { 20. [UrlProperty] 21. [DefaultValue("")] 22. public string ServicePath { get; set; } 23. 24. protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors() { 25. if (string.IsNullOrEmpty(ServicePath)) 26. throw new InvalidOperationException("'ServicePath' must be specified"); 27. 28. var control = new ScriptControlDescriptor("WebApplication1.MyControl.MyControl", this.ClientID); 29. control.AddProperty("servicePath", ResolveUrl(ServicePath)); 30. 31. yield return control; 32. } 33. 34. protected override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences() { 35. return new ScriptReference[] 36. { 37. new MyControlScript() 38. }; 39. } 40. 41. public override void RenderBeginTag(HtmlTextWriter writer) { 42. } 43. 44. public override void RenderEndTag(HtmlTextWriter writer) { 45. 0 ///ServicePath 29. get_servicePath: function() { 30. return this._servicePath; 31. }, 32. set_servicePath: function(value) { 33. this._servicePath = value; 34. }, 35. dispose: function() { 36. //Add custom dispose actions here 37. WebApplication1.MyControl.MyControl.callBaseMethod(this, 'dispose'); 38. } 39. } 40. WebApplication1.MyControl.MyControl.registerClass('WebApplication1.MyControl.MyControl', Sys.UI.Control); 41. 42. if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded(); 1. ///<reference name="MicrosoftAjax.js" /> 2. 3. Type.registerNamespace("WebApplication1.MyControl"); 4. 5. WebApplication1.MyControl.MyControl = function(element) { 6. WebApplication1.MyControl.MyControl.initializeBase(this, [element]); 7. this._servicePath = ''; 8. var id = element.id; 9. this._anchor = document.getElementById(id + '_anchor'); 10. } 11. 12. WebApplication1.MyControl.MyControl.prototype = { 13. initialize: function() { 14. WebApplication1.MyControl.MyControl.callBaseMethod(this, 'initialize'); 15. var _this = this; [UrlProperty] [DefaultValue("")] public string ServicePath { get; set; }
protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors() { if (string.IsNullOrEmpty(ServicePath)) throw new InvalidOperationException("'ServicePath' must be specified");
var control = new ScriptControlDescriptor("WebApplication1.MyControl.MyControl", this.ClientID); control.AddProperty("servicePath", ResolveUrl(ServicePath));
yield return control; }
protected override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences() { return new ScriptReference[] { new MyControlScript() }; }
public override void RenderBeginTag(HtmlTextWriter writer) { }
public override void RenderEndTag(HtmlTextWriter writer) { }
protected override void RenderContents(HtmlTextWriter writer) {
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.Write("<a href=\"#\" id=\""+this.ClientID+"_anchor\">получить данные с сервера</a>"); writer.RenderEndTag(); } } } Класс ScriptControl отвечает за клиент-серверное связывание контролов. Наследник ScriptControl должен реализовать два метода: GetScriptDescriptors и GetScriptReferences. Первый возвращает объект ScriptDescriptor, содержащий в себе описание клиентского контрола(пространство имен и имя класса,перечень свойств, которые необходимо инициализировать). В нашем случае мы заполняем свойство "servicePath", хранящее адрес WebService'а. GetScriptReferences нужен для автоматизации подключения всех скриптов, требуемых для нашего контрола, причем все скрипты подключаются автоматизированно через ScriptManager и отпадает проблема дублирования клиентских скриптов на странице. Теперь посмотрим на клиентский код: 1. ///<reference name="MicrosoftAjax.js" /> 2. 3. Type.registerNamespace("WebApplication1.MyControl"); 4. 5. WebApplication1.MyControl.MyControl = function(element) { 6. WebApplication1.MyControl.MyControl.initializeBase(this, [element]); 7. this._servicePath = ''; 8. var id = element.id; 9. this._anchor = document.getElementById(id + '_anchor'); 10. } 11. 12. WebApplication1.MyControl.MyControl.prototype = { 13. initialize: function() { 14. WebApplication1.MyControl.MyControl.callBaseMethod(this, 'initialize'); 15. var _this = this; 16. this._anchor.onclick = function() { 17. Sys.Net.WebServiceProxy.invoke(_this.get_servicePath(), 18. 'GetData', false, null, 19. function(data) { 20. window.alert(data); 21. }, function(error) { 22. window.alert('При получении данных произошла ошибка:'+error._message); 23. } 24. ); 25. }; 26. // Add custom initialization here 27. }, 28. ///ServicePath 29. get_servicePath: function() { 30. return this._servicePath; 31. }, 32. set_servicePath: function(value) { 33. this._servicePath = value; 34. }, 35. dispose: function() { 36. //Add custom dispose actions here 37. WebApplication1.MyControl.MyControl.callBaseMethod(this, 'dispose'); 38. } 39. } 40. WebApplication1.MyControl.MyControl.registerClass('WebApplication1.MyControl.MyControl', Sys.UI.Control); 41. 42. if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded(); 1. ///<reference name="MicrosoftAjax.js" /> 2. 3. Type.registerNamespace("WebApplication1.MyControl"); 4. 5. WebApplication1.MyControl.MyControl = function(element) { 6. WebApplication1.MyControl.MyControl.initializeBase(this, [element]); 7. this._servicePath = ''; 8. var id = element.id; 9. this._anchor = document.getElementById(id + '_anchor'); 10. } 11. 12. WebApplication1.MyControl.MyControl.prototype = { 13. initialize: function() { 14. WebApplication1.MyControl.MyControl.callBaseMethod(this, 'initialize'); 15. var _this = this; 16. this._anchor.onclick = function() { 17. Sys.Net.WebServiceProxy.invoke(_this.get_servicePath(), 18. 'GetData', false, null, 19. function(data) { 20. window.alert(data); 21. }, function(error) { 22. window.alert('При получении данных произошла ошибка:'+error._message); 23. } 24. ); 25. }; 26. // Add custom initialization here 27. }, 28. ///ServicePath 29. get_servicePath: function() { 30. return this._servicePath; 31. }, 32. set_servicePath: function(value) { 33. this._servicePath = value; 34. }, 35. dispose: function() { 36. //Add custom dispose actions here 37. WebApplication1.MyControl.MyControl.callBaseMethod(this, 'dispose'); 38. } 39. } 40. WebApplication1.MyControl.MyControl.registerClass('WebApplication1.MyControl.MyControl', Sys.UI.Control); 41. 42. if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
///<reference name="MicrosoftAjax.js" />
Type.registerNamespace("WebApplication1.MyControl");
WebApplication1.MyControl.MyControl = function(element) { WebApplication1.MyControl.MyControl.initializeBase(this, [element]); this._servicePath = ''; var id = element.id; this._anchor = document.getElementById(id + '_anchor'); }
WebApplication1.MyControl.MyControl.prototype = { initialize: function() { WebApplication1.MyControl.MyControl.callBaseMethod(this, 'initialize'); var _this = this; this._anchor.onclick = function() { Sys.Net.WebServiceProxy.invoke(_this.get_servicePath(), 'GetData', false, null, function(data) { window.alert(data); }, function(error) { window.alert('При получении данных произошла ошибка:'+error._message); } ); }; // Add custom initialization here }, ///ServicePath get_servicePath: function() { return this._servicePath; }, set_servicePath: function(value) { this._servicePath = value; }, dispose: function() { //Add custom dispose actions here WebApplication1.MyControl.MyControl.callBaseMethod(this, 'dispose'); } } WebApplication1.MyControl.MyControl.registerClass('WebApplication1.MyControl.MyControl', Sys.UI.Control);
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded(); Вся инициализация локальных переменных происходит в конструкторе, туда же и приходит html-объект element для которого создается экземпляр контрола. Объявление вида "///<reference name="MicrosoftAjax.js" />" необходимо для подсказок(IntelliSense) редактора Visual Studio. В методе initialize мы подвязываем клиентские обработчики, в данном случае использую анонимную функцию. По нажатию на ссылку, используя класс Sys.Net.WebServiceProxy производим вызов метода "GetData" нашего WebService'а. И обрабатываем 2 результата: выполнилось успешно и произошла ошибка. В случае возникновения исключительной ситуации подробную информацию о причине ошибки можно получить из объекта класса Exception. Код WebService'а выглядит следующим образом: 1. using System; 2. using System.Collections.Generic; 3. using System.Linq; 4. using System.Web; 5. using System.Web.Services; 6. 7. namespace WebApplication1.MyControl 8. { 9. [WebService(Namespace = "http://tempuri.org/")] 10. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 11. [System.ComponentModel.ToolboxItem(false)] 12. [System.Web.Script.Services.ScriptService] // необходимо для клиентского связывания 13. public class MyControlService : System.Web.Services.WebService 14. { 15. [WebMethod] 16. public string GetData() { 17. return "Мой первый ajax <b style="color: black; background-color: rgb(160, 255, 255);">контрол</b> :)"; 18. } 19. } 20. }
1. using System; 2. using System.Collections.Generic; 3. using System.Linq; 4. using System.Web; 5. using System.Web.Services; 6. 7. namespace WebApplication1.MyControl 8. { 9. [WebService(Namespace = "http://tempuri.org/")] 10. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 11. [System.ComponentModel.ToolboxItem(false)] 12. [System.Web.Script.Services.ScriptService] // необходимо для клиентского связывания 13. public class MyControlService : System.Web.Services.WebService 14. { 15. [WebMethod] 16. public string GetData() { 17. return "Мой первый ajax <B style="BACKGROUND-COLOR: rgb(160,255,255); COLOR: black">контрол</B> :)"; 18. } 19. } 20. }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services;
namespace WebApplication1.MyControl { [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] [System.Web.Script.Services.ScriptService] // необходимо для клиентского связывания public class MyControlService : System.Web.Services.WebService { [WebMethod] public string GetData() { return "Мой первый ajax контрол :)"; } } } Здесь мы видим простой метод, возвращающий строку. Результат выполнения вызова WebMethod'а при нажатии на сслыку будет выглядеть следующим образом:
Код инициализации клиентского контрола, сгенерированного ASP.NET: 1. <script type="text/javascript"> 2. //<![CDATA[ 3. Sys.Application.initialize(); 4. Sys.Application.add_init(function() { 5. $create(WebApplication1.MyControl.MyControl, { "servicePath": "/MyControl/MyControlService.asmx" }, null, null, $get("control")); 6. }); 7. //]]> 8. </script> 1. <script type="text/javascript"> 2. //<![CDATA[ 3. Sys.Application.initialize(); 4. Sys.Application.add_init(function() { 5. $create(WebApplication1.MyControl.MyControl, { "servicePath": "/MyControl/MyControlService.asmx" }, null, null, $get("control")); 6. }); 7. //]]> 8. </script>
<script type="text/javascript"> //<![CDATA[ Sys.Application.initialize(); Sys.Application.add_init(function() { $create(WebApplication1.MyControl.MyControl, { "servicePath": "/MyControl/MyControlService.asmx" }, null, null, $get("control")); }); //]]> </script>
Желаю удачи в освоении Web 2.0! Ссылки по теме
|
|