در دنیای امروز، هوش مصنوعی دیگر یک اختیار نیست؛ بلکه یک ضرورت رقابتی است. اگر یک توسعهدهنده ASP.NET هستی و هنوز OpenAI را به پروژههایت اضافه نکردهای، باید بدانی که رقبایت دارند با سرعت نور جلو میروند.
در این مقاله، به صورت کاملاً عملی و قدمبهقدم یاد میگیریم چطور API هوش مصنوعی OpenAI را در یک پروژه ASP.NET Core پیادهسازی کنیم. از نصب پکیج تا نوشتن کنترلر، از مدیریت خطا تا بهینهسازی هزینه — همه چیز اینجاست.
OpenAI یک شرکت تحقیقاتی هوش مصنوعی است که مدلهای پیشرفتهای مثل GPT-4o، GPT-4، GPT-3.5 Turbo و DALL·E را ارائه میدهد. این مدلها از طریق یک REST API در دسترس هستند و میتوانی در هر پلتفرمی — از جمله ASP.NET — از آنها استفاده کنی.
کاربردهای اصلی OpenAI در پروژههای وب شامل موارد زیر میشود:
قبل از شروع کدنویسی، باید مطمئن شوی این موارد را داری:
برای دریافت کلید API مراحل زیر را انجام بده:
مایکروسافت و OpenAI هر دو پکیجهای رسمی برای داتنت دارند. بهترین گزینه در سال ۲۰۲۵ پکیج OpenAI است که به صورت رسمی توسط OpenAI نگهداری میشود:
dotnet add package OpenAI
یا اگر میخوای از پکیج مایکروسافت Azure OpenAI استفاده کنی:
dotnet add package Azure.AI.OpenAI
برای امنیت بیشتر، هرگز کلید API را مستقیماً در کد ننویس. از فایل تنظیمات استفاده کن:
{
“OpenAI”: {
“ApiKey”: “sk-your-api-key-here”,
“Model”: “gpt-4o-mini”,
“MaxTokens”: 1000
}
}
ابتدا یک کلاس تنظیمات میسازیم:
public class OpenAISettings
{
public string ApiKey { get; set; } = string.Empty;
public string Model { get; set; } = “gpt-4o-mini”;
public int MaxTokens { get; set; } = 1000;
}
حالا یک اینترفیس و سرویس برای مدیریت تمام ارتباطات با OpenAI مینویسیم:
public interface IOpenAIService
{
Task GetChatCompletionAsync(string userMessage, string? systemPrompt = null);
Task SummarizeTextAsync(string text);
Task TranslateTextAsync(string text, string targetLanguage);
}
public class OpenAIService : IOpenAIService
{
private readonly OpenAIClient _client;
private readonly OpenAISettings _settings;
private readonly ILogger _logger;
public OpenAIService(
IOptions settings,
ILogger logger)
{
_settings = settings.Value;
_logger = logger;
_client = new OpenAIClient(_settings.ApiKey);
}
public async Task GetChatCompletionAsync(
string userMessage,
string? systemPrompt = null)
{
try
{
var chatClient = _client.GetChatClient(_settings.Model);
var messages = new List();
if (!string.IsNullOrEmpty(systemPrompt))
messages.Add(new SystemChatMessage(systemPrompt));
messages.Add(new UserChatMessage(userMessage));
var options = new ChatCompletionOptions
{
MaxOutputTokenCount = _settings.MaxTokens
};
ChatCompletion completion = await chatClient
.CompleteChatAsync(messages, options);
return completion.Content[0].Text;
}
catch (Exception ex)
{
_logger.LogError(ex, “خطا در ارتباط با OpenAI API”);
throw;
}
}
public async Task SummarizeTextAsync(string text)
{
var systemPrompt = “تو یک متخصص خلاصهسازی هستی. متن زیر را به فارسی خلاصه کن.”;
return await GetChatCompletionAsync(text, systemPrompt);
}
public async Task TranslateTextAsync(string text, string targetLanguage)
{
var systemPrompt = $“متن زیر را به {targetLanguage} ترجمه کن.”;
return await GetChatCompletionAsync(text, systemPrompt);
}
}
var builder = WebApplication.CreateBuilder(args);
// تنظیم OpenAI
builder.Services.Configure(
builder.Configuration.GetSection(“OpenAI”));
// ثبت سرویس
builder.Services.AddScoped();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// ادامه تنظیمات…
حالا یک کنترلر میسازیم که درخواستهای کاربر را دریافت و به OpenAI ارسال کند:
[ApiController]
[Route(“api/[controller]”)]
public class ChatController : ControllerBase
{
private readonly IOpenAIService _openAIService;
private readonly ILogger _logger;
public ChatController(
IOpenAIService openAIService,
ILogger logger)
{
_openAIService = openAIService;
_logger = logger;
}
[HttpPost(“message”)]
public async Task SendMessage(
[FromBody] ChatRequest request)
{
if (string.IsNullOrWhiteSpace(request.Message))
return BadRequest(“پیام نمیتواند خالی باشد.”);
var response = await _openAIService
.GetChatCompletionAsync(
request.Message,
request.SystemPrompt);
return Ok(new ChatResponse
{
Reply = response,
Timestamp = DateTime.UtcNow
});
}
[HttpPost(“summarize”)]
public async Task Summarize(
[FromBody] TextRequest request)
{
var summary = await _openAIService
.SummarizeTextAsync(request.Text);
return Ok(new { Summary = summary });
}
[HttpPost(“translate”)]
public async Task Translate(
[FromBody] TranslateRequest request)
{
var translation = await _openAIService
.TranslateTextAsync(request.Text, request.TargetLanguage);
return Ok(new { Translation = translation });
}
}
public record ChatRequest(string Message, string? SystemPrompt);
public record ChatResponse
{
public string Reply { get; init; } = string.Empty;
public DateTime Timestamp { get; init; }
}
public record TextRequest(string Text);
public record TranslateRequest(string Text, string TargetLanguage);
یکی از بهترین ویژگیهای OpenAI، Streaming است؛ یعنی پاسخ به صورت زنده و کلمهبهکلمه نمایش داده میشود (مثل ChatGPT). این کار تجربه کاربری را فوقالعاده بهتر میکند:
[HttpPost(“stream”)]
public async Task StreamMessage([FromBody] ChatRequest request)
{
Response.Headers.Add(“Content-Type”, “text/event-stream”);
Response.Headers.Add(“Cache-Control”, “no-cache”);
Response.Headers.Add(“Connection”, “keep-alive”);
var chatClient = _openAIClient.GetChatClient(“gpt-4o-mini”);
var messages = new List
{
new UserChatMessage(request.Message)
};
await foreach (var update in chatClient.CompleteChatStreamingAsync(messages))
{
foreach (var part in update.ContentUpdate)
{
var data = $“data: {part.Text}
”;
await Response.WriteAsync(data);
await Response.Body.FlushAsync();
}
}
}
یکی از مهمترین بخشها در پیادهسازی حرفهای، مدیریت خطاست. OpenAI API گاهی خطاهای Rate Limit یا Timeout میدهد. با Polly میتوانیم Retry خودکار اضافه کنیم:
// نصب پکیج
// dotnet add package Microsoft.Extensions.Http.Polly
// در Program.cs
builder.Services.AddHttpClient()
.AddTransientHttpErrorPolicy(p =>
p.WaitAndRetryAsync(3,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))));
OpenAI بر اساس تعداد Token هزینه میگیرد. برای کنترل هزینهها به این نکات توجه کن:
// نمونه کش کردن پاسخها
public class CachedOpenAIService : IOpenAIService
{
private readonly IOpenAIService _inner;
private readonly IMemoryCache _cache;
public CachedOpenAIService(IOpenAIService inner, IMemoryCache cache)
{
_inner = inner;
_cache = cache;
}
public async Task GetChatCompletionAsync(
string userMessage, string? systemPrompt = null)
{
var cacheKey = $“openai_{userMessage.GetHashCode()}”;
if (_cache.TryGetValue(cacheKey, out string? cachedResponse))
return cachedResponse!;
var response = await _inner
.GetChatCompletionAsync(userMessage, systemPrompt);
_cache.Set(cacheKey, response,
TimeSpan.FromMinutes(30));
return response;
}
}
🚀 آیا میخواهید سایت شما هم مثل رقبا در صفحه اول گوگل باشد و زنگخورهایتان چند برابر شود؟
سئوی سایت خود را به متخصصان ما بسپارید. ما با تجربهای که در سئوی تکنیکال و محتوامحور داریم، رتبه سایت شما را در گوگل ایران متحول میکنیم.
همین حالا برای مشاوره رایگان با ما تماس بگیرید:
📞 09190994063 | 09376846692
Function Calling یکی از قدرتمندترین قابلیتهای OpenAI است که به مدل اجازه میدهد توابع تعریفشده شما را فراخوانی کند. برای مثال، میتوانی به GPT بگویی هر وقت کاربر درخواست آبوهوا کرد، تابع getWeather() را صدا بزند:
var tools = new List
{
ChatTool.CreateFunctionTool(
functionName: “get_weather”,
functionDescription: “Get current weather for a city”,
functionParameters: BinaryData.FromString(“”"
{
“type”: “object”,
“properties”: {
“city”: {
“type”: “string”,
“description”: “The city name”
}
},
“required”: [“city”]
}
“”")
)
};
var options = new ChatCompletionOptions();
foreach (var tool in tools)
options.Tools.Add(tool);
var completion = await chatClient
.CompleteChatAsync(messages, options);
if (completion.FinishReason == ChatFinishReason.ToolCalls)
{
foreach (var toolCall in completion.ToolCalls)
{
if (toolCall.FunctionName == “get_weather”)
{
var args = JsonDocument.Parse(toolCall.FunctionArguments);
var city = args.RootElement
.GetProperty(“city”).GetString();
// اینجا تابع واقعی آبوهوا را صدا بزن
}
}
}
امنیت در پیادهسازی OpenAI API بسیار مهم است. این نکات را رعایت کن:
// خواندن API Key از Environment Variable
var apiKey = Environment.GetEnvironmentVariable(“OPENAI_API_KEY”)
?? throw new InvalidOperationException(
“OPENAI_API_KEY is not set”);
// یا در appsettings.Development.json
// و استفاده از User Secrets در محیط توسعه:
// dotnet user-secrets set “OpenAI:ApiKey” “sk-…”
اگر از Minimal API در داتنت ۸ استفاده میکنی، پیادهسازی حتی سادهتر است:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure(
builder.Configuration.GetSection(“OpenAI”));
builder.Services.AddScoped();
builder.Services.AddMemoryCache();
var app = builder.Build();
app.MapPost(“/api/chat”, async (
ChatRequest request,
IOpenAIService openAIService) =>
{
var response = await openAIService
.GetChatCompletionAsync(request.Message);
return Results.Ok(new { Reply = response });
});
app.MapPost(“/api/summarize”, async (
TextRequest request,
IOpenAIService openAIService) =>
{
var summary = await openAIService
.SummarizeTextAsync(request.Text);
return Results.Ok(new { Summary = summary });
});
app.Run();
برای نوشتن Unit Test روی سرویس OpenAI، از Mock استفاده کن تا نیازی به فراخوانی واقعی API نباشد:
[Fact]
public async Task GetChatCompletion_ReturnsResponse_WhenSuccessful()
{
// Arrange
var mockService = new Mock();
mockService
.Setup(s => s.GetChatCompletionAsync(
It.IsAny(),
It.IsAny()))
.ReturnsAsync(“سلام! چطور میتوانم کمک کنم؟”);
var controller = new ChatController(
mockService.Object,
Mock.Of>());
// Act
var result = await controller
.SendMessage(new ChatRequest(“سلام”, null));
// Assert
var okResult = Assert.IsType(result);
Assert.NotNull(okResult.Value);
}
💡 نکته حرفهای:
اگر پروژه شما در ایران است و به خاطر تحریم به API دسترسی مستقیم نداری، میتوانی از پروکسی یا سرویسهای واسط مثل OpenRouter استفاده کنی. فقط BaseURL را در کلاینت تغییر بده و همان کد کار میکند.
🎯 آیا میخواهید سایت فناوری یا نرمافزاریتان در صفحه اول گوگل دیده شود؟
محتوای تکنیکال سئوشده، کلیدیترین سلاح شما برای رقابت در دنیای دیجیتال است. تیم متخصص ما با ترکیب دانش فنی و تخصص سئو، رتبه سایت شما را در کمترین زمان بهبود میدهد.
همین حالا برای مشاوره رایگان با ما تماس بگیرید:
📞 09190994063 | 09376846692
به دلیل تحریمها، دسترسی مستقیم به OpenAI از ایران امکانپذیر نیست. اما با استفاده از سرورهای خارجی، VPN توسعهدهنده یا سرویسهای واسط مثل OpenRouter و ProxyAPI، میتوانی از این API در پروژههای خود بهرهمند شوی. کد ASP.NET شما تغییری نمیکند و فقط BaseURL عوض میشود.
GPT-4o-mini سریعتر و بسیار ارزانتر است (حدود ۱۵ برابر) و برای اکثر کارهای روزمره مثل پاسخ به سوالات ساده، خلاصهسازی و ترجمه کافی است. GPT-4o قدرتمندتر است و برای تحلیلهای پیچیده، کدنویسی حرفهای و استدلال منطقی بهتر است. توصیه میشود ابتدا با mini شروع کنی و در صورت نیاز به قدرت بیشتر، به نسخه کامل ارتقا دهی.
هزینه بر اساس تعداد Token محاسبه میشود. هر ۱۰۰۰ توکن تقریباً ۷۵۰ کاراکتر فارسی یا ۵۰۰ کلمه انگلیسی است. برای gpt-4o-mini قیمت حدود ۰.۱۵ دلار به ازای هر میلیون توکن ورودی است که بسیار مقرونبهصرفه میباشد. با استفاده از کشکردن پاسخها و انتخاب مدل مناسب میتوانی هزینهها را به شدت کاهش دهی.
بله! مدلهای GPT-4 و GPT-4o به خوبی از زبان فارسی پشتیبانی میکنند و میتوانند متون فارسی را درک، تولید، ترجمه و تحلیل کنند. البته باید توجه داشت که توکنگذاری (Tokenization) برای فارسی کمی متفاوت است و متنهای فارسی معمولاً توکن بیشتری نسبت به انگلیسی مصرف میکنند.
بله! در Blazor Server میتوانی مستقیماً همین سرویس را Inject کنی. در Blazor WebAssembly به دلیل اجرا در مرورگر، باید از طریق API backend فراخوانی کنی تا کلید API لو نرود. بهترین روش این است که یک ASP.NET Core Web API به عنوان backend داشته باشی و Blazor WASM از آن API استفاده کند.
OpenAI به خودی خود حافظه ندارد و هر درخواست مستقل است. برای پیادهسازی چتبات با حافظه، باید تاریخچه پیامها را خودت نگه داری و در هر درخواست، کل تاریخچه را ارسال کنی. میتوانی این تاریخچه را در Session، Redis یا پایگاه داده ذخیره کنی. فقط دقت کن که با افزایش تاریخچه، هزینه Token هم بالا میرود.
خیلی عالی بود، بهخصوص بخش Function Calling که قابلیتهای جدیدی رو اضافه میکنه. آیا امکان این وجود داره که چندین Function Calling همزمان در یک درخواست استفاده بشه؟ و آیا برای توسعهدهندگان، داکیومنت خاصی برای طراحی پارامترهای توابع وجود داره؟
بله، Function Calling قابلیت بسیار قدرتمندی است. مدل میتواند چندین تابع را در یک درخواست فراخوانی کند و شما باید لاجیک سمت سرور را برای اجرای آنها پیادهسازی کنید. داکیومنت رسمی OpenAI اطلاعات کاملی درباره نحوه طراحی Function Parameters با استفاده از JSON Schema ارائه میدهد. برای مشاوره در این زمینه با شمارههای 09190994063 و 09376846692 تماس بگیرید.
سلام، مقاله خیلی کاملی بود و واقعاً نیاز داشتم که یاد بگیرم چطور OpenAI رو به ASP.NET اضافه کنم. قدم به قدم توضیح داده شده و فهمیدن مطلب رو آسون میکنه. ممنون از زحمات شما.
باعث افتخاره که مقاله براتون مفید بوده. هدف ما همین بود که پیادهسازی OpenAI رو برای توسعهدهندگان ASP.NET سادهتر کنیم. اگه سوال یا نیاز به راهنمایی بیشتری داشتید، حتماً از طریق شمارههای 09190994063 و 09376846692 با ما در ارتباط باشید.
ممنون بابت این آموزش جامع. تیم ما در حال حاضر روی یک پروژه با ASP.NET کار میکند و به دنبال بهبود سئو هستیم. با توجه به اینکه شما به سئوی محتوامحور اشاره کردید، آیا در زمینه تولید محتوای سئوشده با هوش مصنوعی هم خدماتی ارائه میدهید؟
سلام فاطمه خانم. بله، تیم ما در زمینه تولید محتوای سئوشده، از جمله با بهرهگیری از تکنیکهای هوش مصنوعی، تخصص دارد و میتواند سایت شما را در گوگل ایران متحول کند. برای دریافت مشاوره رایگان و آشنایی با خدمات ما، لطفاً با شمارههای 09190994063 و 09376846692 تماس بگیرید.
بسیار عالی و کاربردی! همیشه دغدغه دسترسی به OpenAI از ایران رو داشتم. ممنون از راهنماییتون درباره استفاده از پروکسی و OpenRouter. آیا تجربه خاصی در استفاده از OpenRouter با داتنت دارید که بخواید به اشتراک بذارید؟
خوشحالیم که این بخش براتون مفید بوده. OpenRouter یک گزینه عالیه و با تغییر BaseURL در کلاینت OpenAIClient داتنت، میتونید به راحتی ازش استفاده کنید. در آینده شاید مقالهای اختصاصی در این مورد منتشر کنیم. برای مشاوره بیشتر میتوانید با شمارههای 09190994063 و 09376846692 تماس بگیرید.
با سلام، من یک پروژه Blazor WASM دارم و میخواستم بدانم بهترین رویکرد برای استفاده از OpenAI API در این نوع پروژه چیست تا کلید API لو نرود؟ ممنون میشوم اگر بیشتر توضیح دهید.
سلام. همانطور که در مقاله اشاره شد، برای Blazor WebAssembly بهترین رویکرد این است که یک ASP.NET Core Web API به عنوان Backend داشته باشید و Blazor WASM از آن API بکند استفاده کند. به این ترتیب کلید API شما در سمت سرور باقی میماند و در مرورگر کاربر لو نمیرود. برای کمک به پیادهسازی میتوانید با شمارههای 09190994063 و 09376846692 تماس بگیرید.
نحوه پیادهسازی Streaming برای پاسخهای بلادرنگ واقعاً جذاب بود. همین ویژگی باعث میشه تجربه کاربری خیلی بهتر بشه. آیا این روش بار زیادی روی سرور ایجاد نمیکنه؟
بله، Streaming تجربه کاربری را به شکل چشمگیری بهبود میبخشد. در مورد بار سرور، Stream کردن به خودی خود بار زیادی ایجاد نمیکند، بلکه به توزیع بار کمک میکند. البته باید مدیریت کنید که تعداد درخواستهای همزمان از حد مجاز فراتر نرود. برای پیادهسازی بهینه و مقیاسپذیر، میتوانید با شمارههای 09190994063 و 09376846692 مشاوره بگیرید.
بحث مدیریت خطا و استفاده از Polly خیلی هوشمندانه بود. در پروژههای بزرگ این مسائل حیاتی هستند. همچنین نکاتی که در مورد امنیت و ذخیره API Key در Environment Variables گفتید، بسیار کاربردی و مهم است. یک بار دیگر، سپاس از مقاله جامع و کاملتان.
از بازخورد مثبت شما متشکریم محسن عزیز. مدیریت صحیح خطا و رعایت نکات امنیتی از ارکان اصلی یک پیادهسازی حرفهای است. خوشحالیم که این بخشها مورد توجه شما قرار گرفته است. برای هرگونه سوال یا نیاز به پشتیبانی فنی، با شمارههای 09190994063 و 09376846692 تماس بگیرید.
بحث بهینهسازی هزینه و انتخاب مدل مناسب (GPT-4o-mini) خیلی برام مهم بود. ممنون که به این نکته اشاره کردید. آیا پیشنهاد میکنید برای هر درخواست قبل از ارسال، یک بررسی اولیه انجام دهیم تا مدل مناسب انتخاب شود یا از ابتدا یک مدل پیشفرض در نظر بگیریم؟
این سوال خوبی است! معمولاً برای سادگی، یک مدل پیشفرض (مثل gpt-4o-mini) را انتخاب میکنیم و فقط برای وظایف پیچیده که نیاز به استدلال قویتری دارند، به سراغ مدلهای قدرتمندتر میرویم. میتوانید با توجه به کاربرد و نیازهای پروژه خود، این استراتژی را تنظیم کنید. برای راهنمایی دقیقتر با شمارههای 09190994063 و 09376846692 در تماس باشید.