السلام عليكم ورحمة الله وبركاته
أسعد الله صباحكم/مسائكم بكل خير
كل عام وانت بخير
كلنا نعلم أن عالم تطوير الويب والبرمجة بشكل عام لا يعفرا الراحة ولا التوقف. فكل يوم يطرأ شيء جديد، مفهوم جديد، مبدأ جديد، تكنولوجيا جديدة .... وهلم جرا.
سنتناول بإذن الله في هذا الموضوع عدة أمور، أولا سنتعرف وبشكل بسيط ومختصر عن الـ JQeury ومن ثم على ما يعرف بالـ JSON وبعد ذلك وكالمعتاد سوف نرى كيفية تسخير ما ورد لمصلحتنا لتصميم ASP.NET Web Application
أولا : JQuery
هي ببساطة مكتبة تم إنشائها بالـ JavaScript ولكن بعض ما يميزها هو خفة وزنها وتوفقها مع المتصفحات المختلفة وبساطتها. ويمكنها إنجاز ما يمكن إنجازه في 10 سطور فقط في سطر واحد. فعلى سبيل المثال لو كان هناك table يحمل id بقيمة mytable وأردت أن تعطي كل الصفوف الزوجية الـ class الذي يحمل الإسم even فكل ما عليك فعله هو:
<script>
$(function() {
$("table#mytable tr:nth-child(even)").addClass("even");
});
</script>أولا ما يطرأ في بال من يريد تعلم JQuery لأول مرة هو : ما هي هذه العلامة $ ؟ هي عبارة عن function وسوف تقوم بإستخدامها كثيرا وكل ما تقوم به إرجاع reference لعنصر أو مجموعة من العناصر وبعضها يكون بشكل متسلسل، فمثلا دعونا نرى المثال التالي
$("div.test").add("p.quote").html("a little test").fadeOut();لو أردنا أن نحولة إلى لفظ سيكون أشبه بالعبارات التالية :
1) قم بإرجاع العنصر أو العناصر التي نوعها div ولديها class بإسم test
2) قم بإضافة عنصر من نوع p وبـ class يحمل الإسم quote في العنصر أو العناصر التي تم إرجعها في النقطة رقم 1
3) قم بإضافة html code بالقيمة a little test في العنصر p الذي تم إضافته للعنصر أو العناصر المرجعة من النقطة رقم 1
4) قم بتطبيق fadeOut function المعرفة مسبقا للعنصر أو العناصر المرجعة من النقطة رقم 1
إذا يمكنا أن نكتب قاعدة عامة للـ JQuery على الصيغة التالية
$([selector]); // where selector: is a CSS selector (div, .className, #idValue, *, div p, p h1, ....... etc)
لتنصيب الـ JQuery كل ما عليك فعله تحميل ملف الـ JavaScript للمكتبة ثم إضافة link لهذا الملف في مشروعك كالتالي
<script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
ثانيا: JSON
JSON هو إختصار لـ JavaScript Object Notation وكما الإسم يقترح هذا يعني أننا أيضا سنتعامل مع الـ Javascript، قبل أن نعرف كيف سنستفيد من JQuery و JSON في الـ ASP.NET دعونا نرى ما هي هذه الـ JSON.
في لغة C# عندما تريد أن تنشئ object يجب أولا أن يكون لديك Class وعلى حسب ومن ثم تقوم بإنشاء object جديدة وبعدها تقوم بإستخدام الـ properties أو الـ methods التابعة لها على حسب مستوى الدخول، كما في المثال التالي:
namespace MyNameSpace {
public class MyClass {
pulic string StringProperty { get; set; }
public int IntProperty { get; set; }
public float FloatProperty { get; set; }
}
/* Usage
MyClass ob = new MyClass();
ob.StringProperty = "String Value";
ob.IntProperty = 1;
ob.FloatProperty = 1.0f;
*/
}في الـ JavaScript الوضع يختلف وقد يوجد منكم من هو مطلع على الـ Dynamic Languages كالـ JavaScript أو الـ ActionScript، دعونا نرى كيفية تمثيل MyClass ولكن بالـ JavaScript
var myob = {"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0};
alert("String Property: " + myob.StringProperty + ", Int Property: " + myob.IntProperty +
", Float Property: " + myob.FloatProperty);في حالة لو أردنا أن ننشئ Array of objects يكون الكود كالتالي
var myob = [
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0}
];
alert(myob[3].FloatProperty);هذه هو الـ JSON، ويأتي السؤال الذهبي وهو لأي غرض يوجد لدينا JSON ؟ إجابة هذا السؤال هو السبب الرئيسي الذي جعلني أبداء هذه المقالة، عندما نتعامل مع أي Web Service فإنه يتم إرجاع ملف XML وبعد ذلك نقوم إما بقرائته عن طريق XmlReader أو تصميم XSLT حتى نظهر البيانات بشكل مناسبب، ماذا لو كان هناك طريقة بحيث بدلا من الحصول على ملف XML يتم الحصول على object/s إما C# أو VB أو PHP أو Java أو أفضل منهم كلهم لغة محلية متوافقة مع كل المتصفحات ؟؟؟؟؟ هنا يأتي دور الـ JSON.
ثالثا: تطبيق ما تتطرقنا إليه في الـ ASP.NET
سوف نقوم بإنشاء مشروع جديد ونسميه ما نشاء (كل مين ينام على الجمب الي يريحه :blush: ) وسوف نرى كيف نقوم بإستهلاك Web Service عن طريق JQuery وفي نفس الوقت بإستخدام AJAX دون الحاجة إلى إستخدام ScriptManager أو asp:XmlDataSource أو XmlReader أو ما إلى ذلك، اولا سوف أقوم بإضافة مجلد بإسم Services وهو الذي سيحوي الـ Web Service الوحيدة والتي سأسميها MyWebService.asmx وسوف تحوي حاليا على WebMethod وحيدة وهي كالتالي
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Serialization;
using System.Xml.Linq;
/// <summary>
/// Summary description for MyWebService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class MyWebService : System.Web.Services.WebService
{
public MyWebService()
{
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public string SimpleWebService() { return "Jquery rocks!"; }
}بسيطة جدا فقط ترجه لنا العبارة "JQuery Rocks!"، ستكون الصفحة التي سوف تستهلك MyWebService.asmx و التي بإسم Default.aspx كاتالي
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Using JQuery in ASP .NET</title>
<!-- don't forget to reference JQuery library file -->
<script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$("#simple").click(function() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Services/MyWebService.asmx/SimpleWebService",
data: "{}",
dataType: "json",
success: function(msg) {
$("#output").html(msg.d); // equivalent to document.getElementById("output").innerHTML = msg.d;
}
});
}
);
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="simple" type="button" value="Call Simple Web Service" />
<div style="padding: 5px" id="output">
</div>
</div>
</form>
</body>
</html>لمزيد من العلومات حول الدالة .ajax قم بالإطلاع على هذا الرابط
ما يهما هنا هو
$.ajax({
contentType: "application/json; charset=utf-8", // must be set application/json
url: "Services/MyWebService.asmx/SimpleWebService", // web service url
data: "{}", // {} means no data to be sent
dataType: "json", // must be set to json
success: function(msg) { // callback method if asynchronous request successeeded
$("#output").html(msg.d);
}
});قم بالضغط على الزر F5 وبعد ذلك بالضغط الزر الموجود في الصفحة ماذا تلاحظ ؟ لم يحدث أي شيء، لماذا؟ يعود السبب لعدم إستخدامنا للـ Class Attribute المسمى [system.Web.Script.Services.ScriptService] لاحظ أنه عندما تقوم بإنشاء Web Service سيتم إضافة method إفتراضية بإسم HelloWorld وفوق مباشرة يوجد [WebMethod]، هذا الـ [WebMethod] يسمى Method Attribute والغرض منه الدلالة أن الدالة التي تحته مباشرة هي عبارة عن دالة تابعة لـ WebService، كذالك الـ Class يمكن أن يكون له ِAttribute كما هو الحال عندما تريد أن تقوم بعمل Serialization/Deserialization لكائنات Class معين فتقوم بكتابة [serializable] فوق تعريف الكلاس مباشرة. لجعل مثالنا يقوم بما نود أن يقوم به قم بكتابة [system.Web.Script.Services.ScriptService] والغرض منه هو الدلالة على أن هذه الـ Web Service يمكن إستهلاكها من داخل script، سيصبح الكود كالتالي:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Serialization;
using System.Xml.Linq;
/// <summary>
/// Summary description for MyWebService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService] // enable script invokation
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class MyWebService : System.Web.Services.WebService
{
public MyWebService()
{
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public string SimpleWebService() { return "Jquery rocks!"; }
}الآن سوف نرى كيفية إتهلاك ليس Web Service بل Page Method وإرسال قيمه لها، كل ما علينا فعله هو إضافة Method في الـ Page نفسها ولكن بشرط أن تكون static وترجع فيمة من نوع string ولا ننسى أن نسبقه الـ [WebMethod] كي لا نقع في نفس الخطأ فالمؤمن لا يدلغ من جحر ضب مرتين :cool: ، سيكون الكود كالتالي في صفحة Default.aspx.cs
[System.Web.Services.WebMethod()]
public static string PageHelloTo(string name)
{
return string.Format("Hello there '{0}'", name);
}بينما صفحة الـ Default.aspx كالتالي
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Using JQuery in ASP .NET</title>
<script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="js/json2.js" type="text/javascript"></scrip>t
<script src="js/jquery-jtemplates.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$("#pageMethod").click(function(){
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/PageHelloTo",
dataType: "json",
data: "{'name': '" + $('input[type=text]').val() + "'}", // must have same parameters name, it is a JSON if u remove the quotes it will be {'name': value-from-textBox}
success: function(msg){
$("#output").html(msg.d);
},
error: function(msg) {
alert(msg.statusText);
}
});
});
$("#simple").click(function() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Services/MyWebService.asmx/SimpleWebService",
data: "{}",
dataType: "json",
success: function(msg) {
$("#output").html(msg.d);
}
});
}
);
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" /> <input id="pageMethod" type="button" value="Call Page Method" /><br />
<input id="simple" type="button" value="Call Simple Web Service" />
<div style="padding: 5px" id="output">
</div>
</div>
</form>
</body>
</html>بقي علينا أن نرى كيفية التعالم في حالة إذا كان الـ Web Service سيقوم بإرجاع Array of objects، أولا كيف نقوم بذلك علما بأن الـ WebMethod تقوم فقط بإرجاع string، توجد دالة في الـ JavaScript قديمة كانت تسبب لي صعوبة في الفهم أيام الجامعة وهي eval
أتظح لي مؤخرا أنها فقط تقوم بتحويل ما يرسل لها وهو من نوع string إلى JavaScript Code، بمعنى آخر لو كتبت التالي :
<script type="text/javascript">
var whatever = eval("alert('Testing!')");
</script>ستلاحظ أن مربع حوار سيظهر أمامك، طيب لو كتبنا كود يتوافق مع JSON هل سيتم تحويله فعلا إلى object ؟ دعونا نرى الكود التالي
var myob = eval('
[
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0},
{"StringProperty": "String Value",
"IntProperty": 1,
"FloatProperty": 1.0}
]');
alert(myob[3].StringProperty);ستلاحظ أنه تم إنشاء Array of object من string تحتوي على تمثيل JSON ولكن أود الإشارة إلى أن الـ string في الـ javascript يجب أن تكون في سطر واحد أو أنها تكون concatenated بالعلامة + فقبل أن تقوموا بتنفيذ الكود أعلاه الرجاء مراعاة ذلك. لكن كلنا رأينا في الكود قبل الأخير كيف ظهر مربع الحوار، ماذا لو كان هناك كود ضار، ماذا لو كنت تود إستخدام Public Web Service و بسبب ماء كان هناك كود ضار، كيف تحمي نفسك وأهم من ذلك زوار موقعك ؟ لا تخف فإن من وضع معايير json قد وفر كود يقوم بتحويل json string representation إلى object/s مع مراعاة الحماية، يمكن أن تقوم بتحميل ملف الـ javascript عبر هذا الرابط ، ثم إضافة الملف للصفحة تبعك وبع ذلك إستخدام الدالة التالية
<script type="text/javascript"> var ob = JSON.parse(jsonString); // a SyntaxError exception will be thrown if jsonString contains monkey business ;) </script>
والآن قم بإضافة Web Method جديدة في ملف MyWebService.cs كالتالي
[WebMethod]
public string GetData()
{
List<Dictionary<string, object>> data = new List<Dictionary<string, object>>();
for (int i = 1; i <= 10; i++)
{
Dictionary<string, object> row = new Dictionary<string, object>();
row.Add("ID", i);
row.Add("Name", "Robatic " + i);
data.Add(row);
}
return new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(data);
}الدالة System.Web.Script.Serialization.JavaScriptSerializer().Serialize تقوم بتحويل object or array of objects إلى تمثيل json هناك مقترح في موقع MSDN لمن هم متعودون على إستخدام XmlWriter/Reader وهو موجود في هذا الرابط ، سيكون الكود النهائي لـ Default.aspx كالتالي
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Using JQuery in ASP .NET</title>
<script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="js/json2.js" type="text/javascript"></scrip>t
<script src="js/jquery-jtemplates.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$("#pageMethod").click(function(){
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/PageHelloTo",
dataType: "json",
data: "{'name': '" + $('input[type=text]').val() + "'}",
success: function(msg){
$("#output").html(msg.d);
},
error: function(msg) {
alert(msg.statusText);
}
});
});
$("#simple").click(function() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Services/MyWebService.asmx/SimpleWebService",
data: "{}",
dataType: "json",
success: function(msg) {
$("#output").html(msg.d);
}
});
}
);
$("#json").click(function() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Services/MyWebService.asmx/GetData",
data: "{}",
dataType: "json",
success: function(msg){
var data = JSON.parse(msg.d);
var outputStr = "";
for(i in data)
outputStr += "<h5>ID: " + data.ID + ", Name: " + data.Name + "</h5>";
$("#output").html(outputStr);
}
});
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" /> <input id="pageMethod" type="button" value="Call Page Method" /><br />
<input id="simple" type="button" value="Call Simple Web Service" />
<input id="json" type="button" value="Load Data" />
<div style="padding: 5px" id="output">
</div>
</div>
</form>
</body>
</html>أخيرا، قد تكون الـ JSON خفيفة ومحلية (native) وجيده لمن له خبرة في الـ javascript ولكن هذا لا يجعلها الحل الأمثل يوجد بها بعض العيوب، والمبرمج المتمرس يعرف جيدا أنه لا يوجد طريقة مثلا أبدا وإنما تفضل طريقة عن طريقة على حسب المطلوب برمجته والوضع الحالي، فمثلا تخيل أنك تريد إستخدام WebService لا تعطي إلا XML فهل ستقوم ببرمجة كود يقوم بتحيل نتائج الـ XML إلى تمثيل JSON ؟؟
أخيرا سأسرد لكم بعض الروابط التي قد تساعدكم وأيضا سأضيف المشروع في المرفقات
أتمنى للجميع التوفيق والنجاح
