داتنت (C# .NET 8 / 9) پلتفرم اصلی توسعه سیستمهای سازمانی، پورتالهای بانکی و سامانههای اداری کشور است. در این آموزش به شیوه اصولی و استاندارد، سرویس ارسال پیامک و اعتبارسنجی OTP را با استفاده از تزریق وابستگی (Dependency Injection) و IHttpClientFactory در ASP.NET Core پیادهسازی میکنیم.
تعریف اینترفیس سرویس (ISmsService.cs)
public interface ISmsService
{
Task<bool> SendOtpAsync(string mobile, string patternCode, Dictionary<string, object> parameters);
Task<bool> SendSimpleSmsAsync(string mobile, string message);
}
پیادهسازی سرویس با Typed HttpClient (FreeSmsService.cs)
using System.Net.Http.Json;
public class FreeSmsService : ISmsService
{
private readonly HttpClient _httpClient;
public FreeSmsService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<bool> SendOtpAsync(string mobile, string patternCode, Dictionary<string, object> parameters)
{
var payload = new
{
to = mobile,
pattern_code = patternCode,
params = parameters
};
var response = await _httpClient.PostAsJsonAsync("otp", payload);
return response.IsSuccessStatusCode;
}
public async Task<bool> SendSimpleSmsAsync(string mobile, string message)
{
var payload = new
{
to = new[] { mobile },
text = message
};
var response = await _httpClient.PostAsJsonAsync("send", payload);
return response.IsSuccessStatusCode;
}
}
پیکربندی در فایل Program.cs
در فایل Program.cs سرویس را به عنوان Typed Client با تنظیمات هدر و تایماوت اضافه کنید:
builder.Services.AddHttpClient<ISmsService, FreeSmsService>(client =>
{
client.BaseAddress = new Uri("https://api.free-sms.ir/v1/");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {builder.Configuration["FreeSms:ApiKey"]}");
client.Timeout = TimeSpan.FromSeconds(5);
});
تنظیمات فایل appsettings.json
{
"FreeSms": {
"ApiKey": "YOUR_FREE_SMS_API_KEY"
}
}
استفاده در Minimal API یا Controller
app.MapPost("/api/auth/send-code", async (string mobile, ISmsService smsService) =>
{
var code = new Random().Next(10000, 99999).ToString();
var parameters = new Dictionary<string, object> { { "code", code } };
var sent = await smsService.SendOtpAsync(mobile, "identity_otp_v1", parameters);
if (!sent)
return Results.Problem("ارسال پیامک با خطا مواجه شد");
return Results.Ok(new { message = "کد تایید ارسال گردید" });
});
Polly و قابلیت تابآوری (Resilience): با استفاده از پکیج Microsoft.Extensions.Http.Resilience در .NET 8 میتوانید سیاستهای Retry و Circuit Breaker را به سادگی به کلاینت پیامک خود بیافزایید.
سوالات متداول
آیا این کلاینت با پروژههای Blazor و WPF هم کار میکند؟+
بله، معماری مبتنی بر .NET Standard 2.1 و .NET 8 بوده و در انواع پروژههای ASP.NET Core، Blazor، WPF و MAUI قابل استفاده است.
چگونه خطاهای مخابراتی را لاگ کنیم؟+
با تزریق ILogger<FreeSmsService> در سازنده کلاس، در صورتی که !response.IsSuccessStatusCode بود، متن خطای برگشتی از وبسرویس را لاگ کنید.
چرا باید به جای ایجاد مستقیم HttpClient از IHttpClientFactory در داتنت استفاده کنیم؟+
استفاده مستقیم از new HttpClient() باعث بحران نشت سوکت (Socket Exhaustion) در حجم بالای تراکنش میشود؛ IHttpClientFactory چرخه حیات سوکتها و DNS pooling را مدیریت میکند.
چگونه کلید API وبسرویس را به صورت امن در پروژه ASP.NET Core ذخیره کنیم؟+
در محیط Development از قابلیت dotnet user-secrets و در محیط Production از متغیرهای محیطی سیستمعامل (Environment Variables) یا Azure KeyVault استفاده نمایید.