تعلم برمجة الـ RESTful services أو الـ Web APIs بإستخدام ASP.NET Core بطريقة مفصلة وتدريجية
كنا فيما سبق نستخدم Postman لتجربة الخدمة التي بنيناها، ولكن عندما نريد الإستفادة من هذه الخدمة بالفعل سيكون ذلك إما عن طريق نداء الخدمة من الـ frontend وسنأخذ مثال على الـ javascript للقيام بذلك أو يكون في الـ backend وسنستخدم NET. في هذه الحالة.
سنبدأ من الـ frontend وسنوضح كيف يمكن لـ javascript أن تستدعي جميع العمليات التي قمنا بإنشائها في EmployeesController:
إحفظ الكود التالي في ملف بإسم get-employee.html ثم قم بعرضه في أحد المتصفحات:
<html>
<body>
<script>
var baseUrl = 'https://localhost:5001/api/employees';
var employeeId = 1;
var url = baseUrl + '/' + employeeId;
fetch(url)
.then(response => response.json())
.then(json => console.log(json))
</script>
</body>
</html>
ستلاحظ أن الصفحة لا تحتوي على شيئ، ولكن لو عرضت الـ developer tools بإستخدام F12 سترى التالي:
![]() |
ولو حاولنا فتح المتصفح مباشرة على الرابط:
https://localhost:5001/api/employees/1
ستظهر لنا الشاشة التالية:
![]() |
والمشكلة هنا أن المتصفح لم يتعرف على الشهادة certificate التي أنشأتها بيئة عمل dot net core للتطوير development. ولإعتمادها مؤقتاً نضغط على Advanced ثم Proceed to localhost:
![]() |
بإمكاننا بعد ذلك أن نرى نتيجة الإستدعاء ظاهرة في المتصفح:
![]() |
عند تنفيذ الملف get-employee.html مرة أخرى ستلاحظ أننا الآن نستقبل رسالة خطأ مختلفة:
![]() |
وسبب ذلك يعود الى مبدأ Cross-Origin Resource Sharing - CORS حيث أن المتصفح لن يسمح لنا بإستدعاء خدمة عن طريق الـ javascript ليست في نفس دومين المستدعي طلما لم تصرح الخدمة بالسماح بذلك.
للسماح لأي مستفيد من الوصول الى الخدمة نقوم بالتالي:
نقوم بالتعديل التالي:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddCors(o => o.AddPolicy("CorsPolicy",
builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); }
));
}
نضيف ما يلي:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
...
app.UseRouting();
app.UseCors();
app.UseAuthorization();
...
}
يجب أن يكون النداء لـ UseCors بعد ()UseRouting وقبل ()UseAuthorization حسب الترتيب المذكور في الصفحة التالية:
في EmployeesController نضيف التعديلات التالية:
...
using Microsoft.AspNetCore.Cors;
namespace aspnetcorewebapiproject.Controllers
{
[EnableCors("CorsPolicy")]
[Route("api/[controller]")]
[ApiController]
public class EmployeesController : ControllerBase
{
...
والآن عند عرض الملف في المتصفح مرة أخرى سوف يكون بإمكاننا رؤية نتيجة الإستدعاء بشكل صحيح:
![]() |
وهي قريبة لما سبق. ننشئ ملف جديد بإسم get-employees.html ثم نستعرضه في المتصفح:
<html>
<body>
<script>
var url = 'https://localhost:5001/api/employees';
fetch(url)
.then(response => response.json())
.then(json => console.log(json))
</script>
</body>
</html>
![]() |
ننشئ ملف جديد بإسم post-employee.html ثم نستعرضه في المتصفح:
<html>
<body>
<script>
var url = 'https://localhost:5001/api/employees';
fetch(url, {
method: 'POST',
body: JSON.stringify({
firstName: "Abdulrahman",
lastName: "Saud",
isManager: false,
salary: 500,
enrollmentDate: "2016-03-12"
}),
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
})
.then(response => response.json())
.then(json => console.log(json))
</script>
</body>
</html>
وبإستطاعتنا أن نرى أنه تم إضافة المستخدم الجديد:
![]() |
ننشئ ملف جديد بإسم put-employee.html ثم نستعرضه في المتصفح:
<html>
<body>
<script>
var baseUrl = 'https://localhost:5001/api/employees';
var employeeId = 5;
var url = baseUrl + '/' + employeeId;
fetch(url, {
method: 'PUT',
body: JSON.stringify({
id: 5,
firstName: "Abdulrahman",
lastName: "Saud",
isManager: true,
salary: 500,
enrollmentDate: "2016-03-12"
}),
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
})
.then(response => response.json())
.then(json => console.log(json))
</script>
</body>
</html>
وبإستطاعتنا أن نرى أنه تم فعلاً تعديل البيانات:
![]() |
ننشئ ملف جديد بإسم delete-employee.html ثم نستعرضه في المتصفح:
<html>
<body>
<script>
var baseUrl = 'https://localhost:5001/api/employees';
var employeeId = 5;
var url = baseUrl + '/' + employeeId;
fetch(url, {
method: 'DELETE'
})
.then(response => response.json())
.then(json => console.log(json))
</script>
</body>
</html>
وبإستطاعتنا أن نرى أن العملية تمت بشكل صحيح:
![]() |
في الحالات التي نريد فيها إستدعاء الخدمة من الـ backend فإننا نستخدم هذه الإسلوب وأسهل طريقة للتعامل مع خدمة من نوع REST عن طريق الـ NET. هي بإستخدام مكتبة RestSharp. وللقيام بذلك نتبع الخطوات التالية:
وذلك بتنفيذ الأمر التالي:
dotnet new console
ثم نفتح المشروع في VS Code:
code .
يجب علينا إعادة تعريف الـ classes التالية للتعامل معها في المشروع:
وبالنسبة لـ PaginatedList فنحن لسنا بحاجة لتعريف الـ methods وإنما الـ properties فقط.
لإضافة هذه المكتبة البرمجية نستخدم الأمر التالي:
dotnet add package RestSharp
وسنقوم الآن بإستدعاء جميع العمليات بإستخدام هذه المكتبة.
using System;
using RestSharp;
namespace ConsumeRestService
{
class Program
{
static void Main(string[] args)
{
var client = new RestClient("https://localhost:5001/api");
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
var request = new RestRequest("employees/1", Method.GET);
var response = client.Execute<EmployeesResponse<EmployeeDetailsDto>>(request);
Console.WriteLine( response.Content );
}
}
}
أحتجنا الى إضافة السطر التالي لتجاوز مشكلة شهادة الـ SSL:
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
static void Main(string[] args)
{
var client = new RestClient("https://localhost:5001/api");
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
var request = new RestRequest("employees", Method.GET);
var response = client.Execute<EmployeesResponse<PaginatedList<EmployeeDetailsDto>>>(request);
Console.WriteLine( response.Content );
}
static void Main(string[] args)
{
var client = new RestClient("https://localhost:5001/api");
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
var request = new RestRequest("employees", Method.POST);
request.AddJsonBody( new {
firstName = "Fahad",
lastName = "Talal",
isManager = false,
salary = 800,
enrollmentDate = "2013-02-11"
});
var response = client.Execute<EmployeesResponse<EmployeeDetailsDto>>(request);
Console.WriteLine( response.Content );
}
static void Main(string[] args)
{
int employeeId = 6;
var client = new RestClient("https://localhost:5001/api");
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
var request = new RestRequest($"employees/{employeeId}", Method.PUT);
request.AddJsonBody( new {
id = employeeId,
firstName = "Faisal",
lastName = "Talal",
isManager = false,
salary = 800,
enrollmentDate = "2013-02-11"
});
var response = client.Execute<EmployeesResponse<EmployeeDetailsDto>>(request);
Console.WriteLine( response.Content );
}
static void Main(string[] args)
{
var client = new RestClient("https://localhost:5001/api");
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
var request = new RestRequest("employees/6", Method.DELETE);
var response = client.Execute<EmployeesResponse<EmployeeDetailsDto>>(request);
Console.WriteLine( response.Content );
}