From 753d5ef259e05c30db9f321cdbad29778a749e98 Mon Sep 17 00:00:00 2001 From: Arun Kumar Ragu Date: Fri, 24 Oct 2025 17:58:49 +0530 Subject: [PATCH 1/7] 988747: Drafted UG for SmartPaste and SmartTextArea. --- .../smart-paste/EJ2_ASP.NETCORE/annotation.md | 81 +++++ .../EJ2_ASP.NETCORE/claude-service.md | 256 +++++++++++++++ .../custom-inference-backend.md | 82 +++++ .../EJ2_ASP.NETCORE/customization.md | 21 ++ .../EJ2_ASP.NETCORE/deepseek-service.md | 253 +++++++++++++++ .../EJ2_ASP.NETCORE/gemini-service.md | 301 ++++++++++++++++++ .../EJ2_ASP.NETCORE/getting-started.md | 285 +++++++++++++++++ .../EJ2_ASP.NETCORE/groq-service.md | 254 +++++++++++++++ .../smart-paste/images/SmartPaste.gif | Bin 0 -> 52285 bytes .../images/SmartPaste_Annotation.gif | Bin 0 -> 42667 bytes .../EJ2_ASP.NETCORE/claude-service.md | 212 ++++++++++++ .../custom-inference-backend.md | 84 +++++ .../EJ2_ASP.NETCORE/customization.md | 72 +++++ .../EJ2_ASP.NETCORE/deepseek-service.md | 210 ++++++++++++ .../EJ2_ASP.NETCORE/features.md | 19 ++ .../EJ2_ASP.NETCORE/gemini-service.md | 259 +++++++++++++++ .../EJ2_ASP.NETCORE/getting-started.md | 237 ++++++++++++++ .../EJ2_ASP.NETCORE/groq-service.md | 211 ++++++++++++ .../images/SmartTextArea-Inline.gif | Bin 0 -> 46939 bytes .../images/SmartTextArea-Popup.gif | Bin 0 -> 53407 bytes .../smart-textarea/images/SmartTextArea.gif | Bin 0 -> 46939 bytes ej2-asp-core-toc.html | 45 +++ 22 files changed, 2882 insertions(+) create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md create mode 100644 ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md create mode 100644 ej2-asp-core-mvc/smart-paste/images/SmartPaste.gif create mode 100644 ej2-asp-core-mvc/smart-paste/images/SmartPaste_Annotation.gif create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md create mode 100644 ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md create mode 100644 ej2-asp-core-mvc/smart-textarea/images/SmartTextArea-Inline.gif create mode 100644 ej2-asp-core-mvc/smart-textarea/images/SmartTextArea-Popup.gif create mode 100644 ej2-asp-core-mvc/smart-textarea/images/SmartTextArea.gif diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md new file mode 100644 index 0000000000..bcad4400b0 --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md @@ -0,0 +1,81 @@ +--- +layout: post +title: Annotations in ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Learn how to use annotations with the ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Annotations +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Annotations in ASP.NET Core Smart Paste Button Control + +The Syncfusion ASP.NET Core Smart Paste Button control leverages AI to intelligently parse clipboard content and populate form fields, enhancing user productivity. By default, the control analyzes form fields (e.g., ``, ` + +
+ + +
+
+ +
+ + +
+
+ + +
+
+
+ + +
+ + + + + +
+
+ I am John Doe from the United States. My email is johndoe@example.com, and my phone number is 555-123-4567. I’d like to inquire about your services and have a detailed discussion regarding your product offerings. Please contact me via email. I’m happy to subscribe to your newsletter for updates. Thank you! +
+ +{% endhighlight %} +{% endtabs %} + +![Syncfusion ASP.NET Core Smart Paste Button with Annotation](../images/SmartPaste_Annotation.gif) + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md new file mode 100644 index 0000000000..99494db74b --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md @@ -0,0 +1,256 @@ +--- +layout: post +title: Claude AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Learn how to implement a custom AI service using Claude AI with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Claude AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Claude AI Integration with ASP.NET Core Smart Paste Button + +The Syncfusion ASP.NET Core SmartPaste Button control enables AI-powered, context-aware content pasting into forms, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the Anthropic Claude AI service with the Smart Paste Button using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core App. + +## Setting Up Claude + +1. **Create an Anthropic Account** + Visit [Anthropic Console](https://console.anthropic.com), sign up, and complete the verification process. +2. **Obtain an API Key** + Navigate to [API Keys](https://console.anthropic.com/settings/keys) and click "Create Key." +3. **Review Model Specifications** + Refer to [Claude Models Documentation](https://docs.anthropic.com/claude/docs/models-overview) for details on available models. + +## Create a Claude AI Service + +Create a service class to manage interactions with the Claude API, including authentication and response processing for the Smart Paste Button. + +1. Create a `Services` folder in your project. +2. Add a new file named `ClaudeAIService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json`). + +```csharp +using Microsoft.Extensions.AI; +using System.Net; +using System.Text; +using System.Text.Json; + +public class ClaudeAIService +{ + private readonly string _apiKey; + private readonly string _modelName = "claude-3-5-sonnet-20241022"; // Example model + private readonly string _endpoint = "https://api.anthropic.com/v1/messages"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public ClaudeAIService(IConfiguration configuration) + { + _apiKey = configuration["Claude:ApiKey"] ?? throw new ArgumentNullException("Claude API key is missing."); + if (!HttpClient.DefaultRequestHeaders.Contains("x-api-key")) + { + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("x-api-key", _apiKey); + HttpClient.DefaultRequestHeaders.Add("anthropic-version", "2023-06-01"); // Check latest version in Claude API docs + } + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestBody = new ClaudeChatRequest + { + Model = _modelName, + Max_tokens = 1000, // Maximum tokens in response + Messages = chatMessages.Select(m => new ClaudeMessage + { + Role = m.Role == ChatRole.User ? "user" : "assistant", + Content = m.Text + }).ToList(), + Stop_sequences = new List { "END_INSERTION", "NEED_INFO", "END_RESPONSE" } // Configurable stop sequences + }; + + var content = new StringContent(JsonSerializer.Serialize(requestBody, JsonOptions), Encoding.UTF8, "application/json"); + + try + { + var response = await HttpClient.PostAsync(_endpoint, content); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + var responseObject = JsonSerializer.Deserialize(responseString, JsonOptions); + return responseObject?.Content?.FirstOrDefault()?.Text ?? "No response from Claude model."; + } + catch (Exception ex) when (ex is HttpRequestException || ex is JsonException) + { + throw new InvalidOperationException("Failed to communicate with Claude API.", ex); + } + } +} +``` + +N> Store the Claude API key in `appsettings.json` (e.g., `{ "Claude": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. Verify the `anthropic-version` header in [Claude API Documentation](https://docs.anthropic.com/claude/docs) for the latest version. + +## Define Request and Response Models + +Define C# classes to match the Claude API’s JSON request and response format. + +1. Create a new file named `ClaudeModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class ClaudeChatRequest +{ + public string Model { get; set; } + public int Max_tokens { get; set; } + public List Messages { get; set; } + public List Stop_sequences { get; set; } +} + +public class ClaudeMessage +{ + public string Role { get; set; } + public string Content { get; set; } +} + +public class ClaudeChatResponse +{ + public List Content { get; set; } +} + +public class ClaudeContentBlock +{ + public string Text { get; set; } +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart Paste Button to the Claude service, acting as a bridge for AI-generated responses. + +1. Create a new file named `ClaudeInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class ClaudeInferenceService : IChatInferenceService +{ + private readonly ClaudeAIService _claudeService; + + public ClaudeInferenceService(ClaudeAIService claudeService) + { + _claudeService = claudeService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _claudeService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the ASP.NET Core App + +Register the Claude service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add the Smart Paste Button + +Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the Claude AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +

Contact Form

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+
+ + +
+ + + +
+ +
+
+ I am John Doe from the United States. My email is johndoe@example.com, and my phone number is 555-123-4567. I’d like to inquire about your services and have a detailed discussion regarding your product offerings. Please contact me via email. I’m happy to subscribe to your newsletter for updates. Thank you! +
+ +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart Paste Button control will be rendered in the default web browser. + +![ASP.NET Core Smart Paste Button Control](../images/SmartPaste.gif) + +## Troubleshooting + +If the Claude AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the Claude API key and model name are correct in the configuration. Check the `ClaudeAIService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the Claude API endpoint (`https://api.anthropic.com/v1/messages`) is accessible. Test with HTTP/2 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `ClaudeAIService` and `ClaudeInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md new file mode 100644 index 0000000000..5c235ebfe7 --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md @@ -0,0 +1,82 @@ +--- +layout: post +title: Custom AI Service Integration with ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Learn how to integrate custom AI services with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Custom AI Service +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Custom AI Service Integration with ASP.NET Core Smart Paste Button + +The Syncfusion ASP.NET Core Smart Paste Button leverages AI to parse clipboard content and populate form fields, enhancing user productivity. By default, it supports OpenAI and Azure OpenAI services, but you can integrate custom AI services using the `IChatInferenceService` interface. This interface facilitates communication between the Smart Paste Button and your custom AI provider, enabling precise mapping of clipboard data to form fields. + +## IChatInferenceService Interface + +The `IChatInferenceService` interface defines a contract for integrating AI services with the Smart Paste Button, enabling the control to process clipboard data for form field mapping. + +```csharp +public interface IChatInferenceService +{ + Task GenerateResponseAsync(ChatParameters options); +} +``` + +The `GenerateResponseAsync` method takes `ChatParameters` (containing clipboard data and form field metadata) and returns a string response from the AI service, which the Smart Paste Button uses to populate form fields. + +## Simple Implementation of a Custom AI Service + +Below is a sample implementation of a mock AI service named `MockAIService`. This service demonstrates how to implement the `IChatInferenceService` interface by returning sample, context-aware responses. You can replace the logic with your own AI integration. + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class MockAIService : IChatInferenceService +{ + public Task GenerateResponseAsync(ChatParameters options) + { + + } +} +``` + +## Registering the Custom AI Service + +Register the custom AI service in the **~/Program.cs** file of your ASP.NET Core Application: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Implemented AI Services + +Here are examples of AI services integrated using the `IChatInferenceService` interface: + +| Service | Documentation | +|---------|---------------| +| Claude | [Claude Integration](claude-service) | +| DeepSeek | [DeepSeek Integration](deepseek-service) | +| Groq | [Groq Integration](groq-service) | +| Gemini | [Gemini Integration](gemini-service) | + +## Troubleshooting + +If the custom AI integration does not work as expected, try the following: +- **Fields Not Populating**: Verify that the custom AI service’s endpoint, model, and API key are correct in `appsettings.json`. Ensure the `GenerateResponseAsync` method returns valid data. +- **Service Registration Errors**: Confirm that `CustomAIService` and `CustomInferenceService` are registered in **Program.cs**. +- **AI Parsing Errors**: Check the AI service’s response format and ensure it matches the expected `CustomAIResponse` structure. Test the API independently to verify connectivity. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) + diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md new file mode 100644 index 0000000000..c6d1e17811 --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md @@ -0,0 +1,21 @@ +--- +layout: post +title: Customization in ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Explore styles and appearance customization options with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Types and Appearance +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Types and Appearance + +The Syncfusion® ASP.NET Core Smart Paste Button control inherits all properties, types, and styling options of the Syncfusion® ASP.NET Core Button control. This allows users to utilize the existing features and flexibility of the Syncfusion® ASP.NET Core Button while taking advantage of the enhanced Smart Paste Button functionality. + +- [Types and Styles](https://ej2.syncfusion.com/aspnetcore/documentation/button/types-and-styles) +- [Style and Appearance](https://ej2.syncfusion.com/aspnetcore/documentation/button/style-and-appearance) + +## See Also + +- [ASP.NET Core Button Control: Types and Styles](https://ej2.syncfusion.com/aspnetcore/documentation/button/types-and-styles) +- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md new file mode 100644 index 0000000000..146bd99697 --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md @@ -0,0 +1,253 @@ +--- +layout: post +title: DeepSeek AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Learn how to implement a custom AI service using DeepSeek AI with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: DeepSeek AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# DeepSeek AI Integration with ASP.NET Core Smart Paste Button + +The Syncfusion ASP.NET Core SmartPaste Button control enables AI-powered, context-aware content pasting into forms, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the DeepSeek AI service with the Smart Paste Button using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core App. + +## Setting Up DeepSeek + +1. **Obtain a DeepSeek API Key** + Create an account at [DeepSeek Platform](https://platform.deepseek.com), sign in, and navigate to [API Keys](https://platform.deepseek.com/api_keys) to generate an API key. +2. **Review Model Specifications** + Refer to [DeepSeek Models Documentation](https://api-docs.deepseek.com/quick_start/pricing) for details on available models (e.g., `deepseek-chat`). + +## Create a DeepSeek AI Service + +Create a service class to manage interactions with the DeepSeek API, including authentication and response processing for the Smart Paste Button. + +1. Create a `Services` folder in your project. +2. Add a new file named `DeepSeekAIService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json`). + +```csharp +using System.Net; +using System.Text; +using System.Text.Json; +using Microsoft.Extensions.AI; + +public class DeepSeekAIService +{ + private readonly string _apiKey; + private readonly string _modelName = "deepseek-chat"; // Example model + private readonly string _endpoint = "https://api.deepseek.com/chat/completions"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public DeepSeekAIService(IConfiguration configuration) + { + _apiKey = configuration["DeepSeek:ApiKey"] ?? throw new ArgumentNullException("DeepSeek API key is missing."); + if (!HttpClient.DefaultRequestHeaders.Contains("Authorization")) + { + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}"); + } + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestBody = new DeepSeekChatRequest + { + Model = _modelName, + Temperature = 0.7f, // Controls response randomness (0.0 to 1.0) + Messages = chatMessages.Select(m => new DeepSeekMessage + { + Role = m.Role == ChatRole.User ? "user" : "system", // Align with DeepSeek API roles + Content = m.Text + }).ToList() + }; + + var content = new StringContent(JsonSerializer.Serialize(requestBody, JsonOptions), Encoding.UTF8, "application/json"); + + try + { + var response = await HttpClient.PostAsync(_endpoint, content); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + var responseObject = JsonSerializer.Deserialize(responseString, JsonOptions); + return responseObject?.Choices?.FirstOrDefault()?.Message?.Content ?? "No response from DeepSeek."; + } + catch (Exception ex) when (ex is HttpRequestException || ex is JsonException) + { + throw new InvalidOperationException("Failed to communicate with DeepSeek API.", ex); + } + } +} +``` + +N> Store the DeepSeek API key in `appsettings.json` (e.g., `{ "DeepSeek": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. + +## Define Request and Response Models + +Define C# classes to match the DeepSeek API’s JSON request and response format. + +1. Create a new file named `DeepSeekModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class DeepSeekMessage +{ + public string Role { get; set; } + public string Content { get; set; } +} + +public class DeepSeekChatRequest +{ + public string Model { get; set; } + public float Temperature { get; set; } + public List Messages { get; set; } +} + +public class DeepSeekChatResponse +{ + public List Choices { get; set; } +} + +public class DeepSeekChoice +{ + public DeepSeekMessage Message { get; set; } +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart Paste Button to the DeepSeek service, acting as a bridge for AI-generated responses. + +1. Create a new file named `DeepSeekInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class DeepSeekInferenceService : IChatInferenceService +{ + private readonly DeepSeekAIService _deepSeekService; + + public DeepSeekInferenceService(DeepSeekAIService deepSeekService) + { + _deepSeekService = deepSeekService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _deepSeekService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the Blazor App + +Register the DeepSeek service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add the Smart Paste Button + +Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the DeepSeek AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +

Contact Form

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+
+ + +
+ + + +
+ +
+
+ I am John Doe from the United States. My email is johndoe@example.com, and my phone number is 555-123-4567. I’d like to inquire about your services and have a detailed discussion regarding your product offerings. Please contact me via email. I’m happy to subscribe to your newsletter for updates. Thank you! +
+ +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart Paste Button control will be rendered in the default web browser. + +![ASP.NET Core Smart Paste Button Control](../images/SmartPaste.gif) + +## Troubleshooting + +If the DeepSeek AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the DeepSeek API key and model name are correct in the configuration. Check the `DeepSeekAIService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the DeepSeek API endpoint (`https://api.deepseek.com/v1/chat/completions`) is accessible. Test with HTTP/2 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `DeepSeekAIService` and `DeepSeekInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md new file mode 100644 index 0000000000..beb4f06b08 --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md @@ -0,0 +1,301 @@ +--- +layout: post +title: Gemini AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Learn how to implement a custom AI service using Google's Gemini API with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Gemini AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Gemini AI Integration with ASP.NET Core Smart Paste Button + +The Syncfusion ASP.NET Core SmartPaste Button control enables AI-powered, context-aware content pasting into forms, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the Google Gemini AI service with the Smart Paste Button using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core Web App. + +## Setting Up Gemini + +1. **Obtain a Gemini API Key** + Visit [Google AI Studio](https://ai.google.dev/gemini-api/docs/api-key), sign in, and generate an API key. +2. **Review Model Specifications** + Refer to [Gemini Models Documentation](https://ai.google.dev/gemini-api/docs/models) for details on available models. + +## Create a Gemini AI Service + +Create a service class to manage interactions with the Gemini API, including authentication, request/response handling, and safety settings for the Smart Paste Button. + +1. Create a `Services` folder in your project. +2. Add a new file named `GeminiService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json`). + +```csharp +using System.Net; +using System.Text; +using System.Text.Json; +using Microsoft.Extensions.AI; + +public class GeminiService +{ + private readonly string _apiKey; + private readonly string _modelName = "gemini-2.0-flash"; // Example model + private readonly string _endpoint = "https://generativelanguage.googleapis.com/v1beta/models/"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public GeminiService(IConfiguration configuration) + { + _apiKey = configuration["Gemini:ApiKey"] ?? throw new ArgumentNullException("Gemini API key is missing."); + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("x-goog-api-key", _apiKey); + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestUri = $"{_endpoint}{_modelName}:generateContent"; + var parameters = BuildGeminiChatParameters(chatMessages); + var payload = new StringContent( + JsonSerializer.Serialize(parameters, JsonOptions), + Encoding.UTF8, + "application/json" + ); + + try + { + using var response = await HttpClient.PostAsync(requestUri, payload); + response.EnsureSuccessStatusCode(); + var json = await response.Content.ReadAsStringAsync(); + var result = JsonSerializer.Deserialize(json, JsonOptions); + return result?.Candidates?.FirstOrDefault()?.Content?.Parts?.FirstOrDefault()?.Text + ?? "No response from model."; + } + catch (Exception ex) when (ex is HttpRequestException or JsonException) + { + throw new InvalidOperationException("Gemini API error.", ex); + } + } + + private GeminiChatParameters BuildGeminiChatParameters(IList messages) + { + var contents = messages.Select(m => new ResponseContent( + m.Text, + m.Role == ChatRole.User ? "user" : "model" + )).ToList(); + + return new GeminiChatParameters + { + Contents = contents, + GenerationConfig = new GenerationConfig + { + MaxOutputTokens = 2000, + StopSequences = new List { "END_INSERTION", "NEED_INFO", "END_RESPONSE" } // Configurable stop sequences + }, + SafetySettings = new List + { + new() { Category = "HARM_CATEGORY_HARASSMENT", Threshold = "BLOCK_ONLY_HIGH" }, + new() { Category = "HARM_CATEGORY_HATE_SPEECH", Threshold = "BLOCK_ONLY_HIGH" }, + new() { Category = "HARM_CATEGORY_SEXUALLY_EXPLICIT", Threshold = "BLOCK_ONLY_HIGH" }, + new() { Category = "HARM_CATEGORY_DANGEROUS_CONTENT", Threshold = "BLOCK_ONLY_HIGH" } + } + }; + } +} +``` + +N> Store the Gemini API key in `appsettings.json` (e.g., `{ "Gemini": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. The `SafetySettings` filter harmful content; adjust thresholds based on your application’s needs. + +## Define Request and Response Models + +Define C# classes to match the Gemini API’s JSON request and response format. + +1. Create a new file named `GeminiModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class Part +{ + public string Text { get; set; } +} + +public class Content +{ + public Part[] Parts { get; init; } = Array.Empty(); +} + +public class Candidate +{ + public Content Content { get; init; } = new(); +} + +public class GeminiResponseObject +{ + public Candidate[] Candidates { get; init; } = Array.Empty(); +} + +public class ResponseContent +{ + public List Parts { get; init; } + public string Role { get; init; } + + public ResponseContent(string text, string role) + { + Parts = new List { new Part { Text = text } }; + Role = role; + } +} + +public class GenerationConfig +{ + public int Temperature { get; init; } = 0; + public int TopK { get; init; } = 0; + public int TopP { get; init; } = 0; + public int MaxOutputTokens { get; init; } = 2048; + public List StopSequences { get; init; } = new(); +} + +public class SafetySetting +{ + public string Category { get; init; } = string.Empty; + public string Threshold { get; init; } = string.Empty; +} + +public class GeminiChatParameters +{ + public List Contents { get; init; } = new(); + public GenerationConfig GenerationConfig { get; init; } = new(); + public List SafetySettings { get; init; } = new(); +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart Paste Button to the Gemini service, acting as a bridge for AI-generated responses. + +1. Create a new file named `GeminiInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class GeminiInferenceService : IChatInferenceService +{ + private readonly GeminiService _geminiService; + + public GeminiInferenceService(GeminiService geminiService) + { + _geminiService = geminiService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _geminiService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the ASP.NET Core App + +Register the Gemini service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); + +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add the Smart Paste Button + +Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the Gemini AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +

Contact Form

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+
+ + +
+ + + +
+ +
+
+ I am John Doe from the United States. My email is johndoe@example.com, and my phone number is 555-123-4567. I’d like to inquire about your services and have a detailed discussion regarding your product offerings. Please contact me via email. I’m happy to subscribe to your newsletter for updates. Thank you! +
+ +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart Paste Button control will be rendered in the default web browser. + +![ASP.NET Core Smart Paste Button Control](../images/SmartPaste.gif) + +## Troubleshooting + +If the Gemini AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the Gemini API key and model name are correct in the configuration. Check the `GeminiService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the Gemini API endpoint (`https://generativelanguage.googleapis.com/v1beta/models/`) is accessible. Test with HTTP/2 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `GeminiService` and `GeminiInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md new file mode 100644 index 0000000000..bad130b8dc --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md @@ -0,0 +1,285 @@ +--- +layout: post +title: Getting Started with ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Checkout and learn about getting started with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Getting Started +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Getting Started with ASP.NET Core Smart Paste Button Control + +This section briefly explains about how to include `ASP.NET Core Smart Paste Button` control in your ASP.NET Core application using Visual Studio. + +## Prerequisites + +[System requirements for ASP.NET Core controls](https://ej2.syncfusion.com/aspnetcore/documentation/system-requirements) + +## Create ASP.NET Core web application with Razor pages + +* [Create a Project using Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-8.0&tabs=visual-studio#create-a-razor-pages-web-app) + +* [Create a Project using Syncfusion® ASP.NET Core Extension](https://ej2.syncfusion.com/aspnetcore/documentation/getting-started/project-template) + +## Install ASP.NET Core package in the application + +To add `ASP.NET Core` controls in the application, open the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search for [Syncfusion.EJ2.AspNet.Core](https://www.nuget.org/packages/Syncfusion.EJ2.AspNet.Core/) and then install it. Alternatively, you can utilize the following package manager command to achieve the same. + +{% tabs %} +{% highlight C# tabtitle="Package Manager" %} + +Install-Package Syncfusion.EJ2.AspNet.Core -Version {{ site.releaseversion }} + +{% endhighlight %} +{% endtabs %} + +N> Syncfusion® ASP.NET Core controls are available in [nuget.org.](https://www.nuget.org/packages?q=syncfusion.EJ2) Refer to [NuGet packages topic](https://ej2.syncfusion.com/aspnetcore/documentation/nuget-packages) to learn more about installing NuGet packages in various OS environments. The Syncfusion.EJ2.AspNet.Core NuGet package has dependencies, [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/) for JSON serialization and [Syncfusion.Licensing](https://www.nuget.org/packages/Syncfusion.Licensing/) for validating Syncfusion® license key. + +## Add Syncfusion® ASP.NET Core Tag Helper +Open `~/Pages/_ViewImports.cshtml` file and import the `Syncfusion.EJ2` TagHelper. + +{% tabs %} +{% highlight C# tabtitle="~/_ViewImports.cshtml" %} + +@addTagHelper *, Syncfusion.EJ2 + +{% endhighlight %} +{% endtabs %} + +## Add stylesheet and script resources + +Here, the theme and script is referred using CDN inside the `` of `~/Pages/Shared/_Layout.cshtml` file as follows, + +{% tabs %} +{% highlight cshtml tabtitle="~/_Layout.cshtml" %} + + + ... + + + + + + +{% endhighlight %} +{% endtabs %} + +N> Checkout the [Themes topic](https://ej2.syncfusion.com/aspnetcore/documentation/appearance/theme) to learn different ways ([CDN](https://ej2.syncfusion.com/aspnetcore/documentation/common/adding-script-references#cdn-reference), [NPM package](https://ej2.syncfusion.com/aspnetcore/documentation/common/adding-script-references#node-package-manager-npm), and [CRG](https://ej2.syncfusion.com/aspnetcore/documentation/common/custom-resource-generator)) to refer styles in ASP.NET Core application, and to have the expected appearance for Syncfusion® ASP.NET Core controls. + +N> Checkout the [Adding Script Reference](https://ej2.syncfusion.com/aspnetcore/documentation/common/adding-script-references) topic to learn different approaches for adding script references in your ASP.NET Core application. + +## Register Syncfusion® Script Manager + +Also, register the script manager `` at the end of `` in the ASP.NET Core application as follows. + +{% tabs %} +{% highlight cshtml tabtitle="~/_Layout.cshtml" %} + + + ... + + + + +{% endhighlight %} +{% endtabs %} + +## Configure AI Service + +The Smart Paste Button requires an AI service (OpenAI, Azure OpenAI, or Ollama) to analyze and map copied text to form fields. Follow the instructions below to configure an AI model in your application. + +### Install AI Service NuGet Packages + +Install the following NuGet packages based on your chosen AI provider: + +{% tabs %} +{% highlight c# tabtitle="Package Manager" %} + +Install-Package Microsoft.Extensions.AI +Install-Package Microsoft.Extensions.AI.OpenAI +@* For Azure OpenAI only *@ +Install-Package Azure.AI.OpenAI +@* For Ollama only *@ +Install-Package OllamaSharp + +{% endhighlight %} +{% endtabs %} + +### OpenAI Configuration + +For OpenAI, obtain an API key from [OpenAI](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key) and specify the desired model (e.g., `gpt-3.5-turbo`, `gpt-4`). Store the API key securely in a configuration file or environment variable. + +Add the following to the **~/Program.cs** file: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +using Microsoft.Extensions.AI; +using OpenAI; +using Syncfusion.EJ2; + + +builder.Services.AddRazorPages(); + +string openAIApiKey = "API-KEY"; +string openAIModel = "OPENAI_MODEL"; +OpenAIClient openAIClient = new OpenAIClient(openAIApiKey); +IChatClient openAIChatClient = openAIClient.GetChatClient(openAIModel).AsIChatClient(); +builder.Services.AddChatClient(openAIChatClient); + +builder.Services.AddSyncfusionSmartComponents() + .InjectOpenAIInference(); + +var app = builder.Build(); +.... + +{% endhighlight %} +{% endtabs %} + +### Azure OpenAI Configuration + +For Azure OpenAI, deploy a resource and model as described in [Azure OpenAI documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource). Obtain the API key, endpoint, and model name from your Azure portal. + +Add the following to the **~/Program.cs** file: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +using Syncfusion.EJ2; +using Microsoft.Extensions.AI; +using Azure.AI.OpenAI; +using System.ClientModel; + +builder.Services.AddRazorPages(); + +string azureOpenAIKey = "AZURE_OPENAI_KEY"; +string azureOpenAIEndpoint = "AZURE_OPENAI_ENDPOINT"; +string azureOpenAIModel = "AZURE_OPENAI_MODEL"; +AzureOpenAIClient azureOpenAIClient = new AzureOpenAIClient( + new Uri(azureOpenAIEndpoint), + new ApiKeyCredential(azureOpenAIKey) +); +IChatClient azureOpenAIChatClient = azureOpenAIClient.GetChatClient(azureOpenAIModel).AsIChatClient(); +builder.Services.AddChatClient(azureOpenAIChatClient); + +builder.Services.AddSyncfusionSmartComponents() + .InjectOpenAIInference(); + +var app = builder.Build(); +.... + +{% endhighlight %} +{% endtabs %} + +### Ollama Configuration + +To use Ollama for self-hosted models: + +1. Download and install Ollama from [Ollama's official website](https://ollama.com). +2. Install a model from the [Ollama Library](https://ollama.com/library) (e.g., `llama2:13b`, `mistral:7b`). +3. Configure the endpoint URL (e.g., `http://localhost:11434`) and model name. + +Add the following to the **~/Program.cs** file: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +using Syncfusion.EJ2; +using Microsoft.Extensions.AI; +using OllamaSharp; + +builder.Services.AddRazorPages(); + +string ModelName = "MODEL_NAME"; +IChatClient chatClient = new OllamaApiClient("http://localhost:11434", ModelName); +builder.Services.AddChatClient(chatClient); + +builder.Services.AddSyncfusionSmartComponents() + .InjectOpenAIInference(); + +var app = builder.Build(); +.... + +{% endhighlight %} +{% endtabs %} + +## Add ASP.NET Core Smart Paste Button Control + +Now, add the Syncfusion® ASP.NET Core Smart Paste Button tag helper in `~/Pages/Index.cshtml` page. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +

Contact Form

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+
+ + +
+ + + +
+ +
+
+ I am John Doe from the United States. My email is johndoe@example.com, and my phone number is 555-123-4567. I’d like to inquire about your services and have a detailed discussion regarding your product offerings. Please contact me via email. I’m happy to subscribe to your newsletter for updates. Thank you! +
+ +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart Paste Button control will be rendered in the default web browser. + +![ASP.NET Core Smart Paste Button Control](../images/SmartPaste.gif) + +## Performance Considerations + +For optimal performance with the Smart Paste Button: +- Use lightweight AI models (e.g., `gpt-3.5-turbo` or `mistral:7b`) for faster processing. +- Limit form complexity to reduce AI parsing time, especially for large datasets. +- Cache AI model responses where possible to minimize repeated API calls. + +## Troubleshooting Common Issues + +- **AI Service Configuration Errors**: Verify the API key, endpoint, and model name in `Program.cs`. Check for typos or incorrect values. +- **Network Failures**: Ensure a stable internet connection for OpenAI or Azure OpenAI. For Ollama, confirm the local server is running at the specified endpoint (e.g., `http://localhost:11434`). +- **Form Not Populating**: Confirm that the copied text matches the form field structure and that the AI model is correctly configured. diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md new file mode 100644 index 0000000000..63a8780a92 --- /dev/null +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md @@ -0,0 +1,254 @@ +--- +layout: post +title: Groq AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +description: Learn how to implement a custom AI service using Groq AI with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Groq AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Groq AI Integration with ASP.NET Core Smart Paste Button + +The Syncfusion ASP.NET Core Smart Paste Button control enables AI-powered, context-aware content pasting into forms, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the Groq AI service with the Smart Paste Button using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core app. + +## Setting Up Groq + +1. **Create a Groq Account** + Visit [Groq Cloud Console](https://console.groq.com), sign up or sign in, and complete the verification process. +2. **Obtain an API Key** + Navigate to [API Keys](https://console.groq.com/keys) in the Groq Console and click "Create API Key." +3. **Review Model Specifications** + Refer to [Groq Models Documentation](https://console.groq.com/docs/models) for details on available models (e.g., `llama3-8b-8192`). + +## Create a Groq AI Service + +Create a service class to manage interactions with the Groq API, including authentication and response processing for the Smart Paste Button. + +1. Create a `Services` folder in your project. +2. Add a new file named `GroqService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json` or environment variables). + +```csharp +using Microsoft.Extensions.AI; +using System.Net; +using System.Text; +using System.Text.Json; + +public class GroqService +{ + private readonly string _apiKey; + private readonly string _modelName = "llama-3.3-70b-versatile"; // Example model + private readonly string _endpoint = "https://api.groq.com/openai/v1/chat/completions"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for broader compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public GroqService(IConfiguration configuration) + { + _apiKey = configuration["Groq:ApiKey"] ?? throw new ArgumentNullException("Groq API key is missing."); + if (!HttpClient.DefaultRequestHeaders.Contains("Authorization")) + { + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}"); + } + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestPayload = new GroqChatParameters + { + Model = _modelName, + Messages = chatMessages.Select(m => new Message + { + Role = m.Role == ChatRole.User ? "user" : "assistant", + Content = m.Text + }).ToList(), + Stop = new List { "END_INSERTION", "NEED_INFO", "END_RESPONSE" } // Configurable stop sequences + }; + + var content = new StringContent(JsonSerializer.Serialize(requestPayload, JsonOptions), Encoding.UTF8, "application/json"); + + try + { + var response = await HttpClient.PostAsync(_endpoint, content); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + var responseObject = JsonSerializer.Deserialize(responseString, JsonOptions); + return responseObject?.Choices?.FirstOrDefault()?.Message?.Content ?? "No response from model."; + } + catch (Exception ex) when (ex is HttpRequestException || ex is JsonException) + { + throw new InvalidOperationException("Failed to communicate with Groq API.", ex); + } + } +} +``` + +N> Store the Groq API key in `appsettings.json` (e.g., `{ "Groq": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. + +## Define Request and Response Models + +Define C# classes to match the Groq API’s request and response format. + +1. Create a new file named `GroqModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class Choice +{ + public Message Message { get; set; } +} + +public class Message +{ + public string Role { get; set; } + public string Content { get; set; } +} + +public class GroqChatParameters +{ + public string Model { get; set; } + public List Messages { get; set; } + public List Stop { get; set; } +} + +public class GroqResponseObject +{ + public string Model { get; set; } + public List Choices { get; set; } +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart Paste Button to the Groq service. + +1. Create a new file named `GroqInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class GroqInferenceService : IChatInferenceService +{ + private readonly GroqService _groqService; + + public GroqInferenceService(GroqService groqService) + { + _groqService = groqService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _groqService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the ASP.NET Core App + +Register the Groq service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add the Smart Paste Button + +Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the Gemini AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +

Contact Form

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+
+ + +
+ + + +
+ +
+
+ I am John Doe from the United States. My email is johndoe@example.com, and my phone number is 555-123-4567. I’d like to inquire about your services and have a detailed discussion regarding your product offerings. Please contact me via email. I’m happy to subscribe to your newsletter for updates. Thank you! +
+ +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart Paste Button control will be rendered in the default web browser. + +![ASP.NET Core Smart Paste Button Control](../images/SmartPaste.gif) + +## Troubleshooting + +If the Groq AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the Groq API key and model name are correct in the configuration. Check the `GroqService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the Groq API endpoint (`https://api.groq.com/openai/v1/chat/completions`) is accessible. Test with HTTP/2 instead of HTTP/3 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `GroqService` and `GroqInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/images/SmartPaste.gif b/ej2-asp-core-mvc/smart-paste/images/SmartPaste.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a177a1633acea6410021796d743a0549eed4183 GIT binary patch literal 52285 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 J`|k(x{{hkL>M;NS literal 0 HcmV?d00001 diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md new file mode 100644 index 0000000000..5182956eb8 --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md @@ -0,0 +1,212 @@ +--- +layout: post +title: Claude AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +description: Learn how to implement a custom AI service using Claude AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Claude AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Claude AI Integration with ASP.NET Core Smart TextArea + +The Syncfusion ASP.NET Core Smart TextArea control provides AI-powered autocompletion for context-aware text input, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the Anthropic Claude AI service with the Smart TextArea using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core App. + +## Setting Up Claude + +1. **Create an Anthropic Account** + Visit [Anthropic Console](https://console.anthropic.com), sign up, and complete the verification process. +2. **Obtain an API Key** + Navigate to [API Keys](https://console.anthropic.com/settings/keys) and click "Create Key." +3. **Review Model Specifications** + Refer to [Claude Models Documentation](https://docs.anthropic.com/claude/docs/models-overview) for details on available models. + +## Create a Claude AI Service + +Create a service class to manage interactions with the Claude API, including authentication and response processing for the Smart TextArea. + +1. Create a `Services` folder in your project. +2. Add a new file named `ClaudeAIService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json`). + +```csharp +using Microsoft.Extensions.AI; +using System.Net; +using System.Text; +using System.Text.Json; + +public class ClaudeAIService +{ + private readonly string _apiKey; + private readonly string _modelName = "claude-3-5-sonnet-20241022"; // Example model + private readonly string _endpoint = "https://api.anthropic.com/v1/messages"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public ClaudeAIService(IConfiguration configuration) + { + _apiKey = configuration["Claude:ApiKey"] ?? throw new ArgumentNullException("Claude API key is missing."); + if (!HttpClient.DefaultRequestHeaders.Contains("x-api-key")) + { + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("x-api-key", _apiKey); + HttpClient.DefaultRequestHeaders.Add("anthropic-version", "2023-06-01"); // Check latest version in Claude API docs + } + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestBody = new ClaudeChatRequest + { + Model = _modelName, + Max_tokens = 1000, // Maximum tokens in response + Messages = chatMessages.Select(m => new ClaudeMessage + { + Role = m.Role == ChatRole.User ? "user" : "assistant", + Content = m.Text + }).ToList(), + Stop_sequences = new List { "END_INSERTION", "NEED_INFO", "END_RESPONSE" } // Configurable stop sequences + }; + + var content = new StringContent(JsonSerializer.Serialize(requestBody, JsonOptions), Encoding.UTF8, "application/json"); + + try + { + var response = await HttpClient.PostAsync(_endpoint, content); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + var responseObject = JsonSerializer.Deserialize(responseString, JsonOptions); + return responseObject?.Content?.FirstOrDefault()?.Text ?? "No response from Claude model."; + } + catch (Exception ex) when (ex is HttpRequestException || ex is JsonException) + { + throw new InvalidOperationException("Failed to communicate with Claude API.", ex); + } + } +} +``` + +N> Store the Claude API key in `appsettings.json` (e.g., `{ "Claude": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. Verify the `anthropic-version` header in [Claude API Documentation](https://docs.anthropic.com/claude/docs) for the latest version. + +## Define Request and Response Models + +Define C# classes to match the Claude API’s JSON request and response format. + +1. Create a new file named `ClaudeModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class ClaudeChatRequest +{ + public string Model { get; set; } + public int Max_tokens { get; set; } + public List Messages { get; set; } + public List Stop_sequences { get; set; } +} + +public class ClaudeMessage +{ + public string Role { get; set; } + public string Content { get; set; } +} + +public class ClaudeChatResponse +{ + public List Content { get; set; } +} + +public class ClaudeContentBlock +{ + public string Text { get; set; } +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart TextArea to the Claude service, acting as a bridge for AI-generated responses. + +1. Create a new file named `ClaudeInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class ClaudeInferenceService : IChatInferenceService +{ + private readonly ClaudeAIService _claudeService; + + public ClaudeInferenceService(ClaudeAIService claudeService) + { + _claudeService = claudeService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _claudeService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the ASP.NET Core App + +Register the Claude service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add ASP.NET Core Smart TextArea Control + +Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the Claude AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +@{ + var presets = new { + userRole = "Maintainer of an open-source project replying to GitHub issues", + userPhrases = new[] { "Thank you for contacting us.", "To investigate, we'll need a repro as a public Git repo.", "Could you please post a screenshot of NEED_INFO?", "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.", "We don't accept ZIP files as repros." }, + placeHolder = "Write your response to the GitHub issue..." }; +} + + + +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart TextArea control will be rendered in the default web browser. + +![ASP.NET Core Smart TextArea Control](../images/SmartTextArea.gif) + +## Troubleshooting + +If the Claude AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the Claude API key and model name are correct in the configuration. Check the `ClaudeAIService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the Claude API endpoint (`https://api.anthropic.com/v1/messages`) is accessible. Test with HTTP/2 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `ClaudeAIService` and `ClaudeInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md new file mode 100644 index 0000000000..75e7fba538 --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md @@ -0,0 +1,84 @@ +--- +layout: post +title: Custom AI Service Integration with ##Platform_Name## Smart TextArea Control | Syncfusion +description: Learn how to integrate custom AI services with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Custom AI Service +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Custom AI Service Integration with ASP.NET Core Smart TextArea + +The Syncfusion ASP.NET Core Smart TextArea control leverages AI to provide context-aware autocompletion, typically using OpenAI or Azure OpenAI services. Developers can integrate custom AI services using the `IChatInferenceService` interface, which standardizes communication between the Smart TextArea and third-party AI providers. This section explains how to implement and register a custom AI service for the Smart TextArea. + +## IChatInferenceService Interface + +The `IChatInferenceService` interface defines a contract for integrating custom AI services with Syncfusion Smart Controls. It enables the Smart TextArea to request and receive AI-generated responses. + +```csharp +public interface IChatInferenceService +{ + Task GenerateResponseAsync(ChatParameters options); +} +``` + +- **Purpose**: Standardizes communication for AI-generated responses. +- **Parameters**: The `ChatParameters` type includes properties like user input and context. +- **Benefits**: Enables seamless switching between AI providers without modifying component code. + +## Simple Implementation of a Custom AI Service + +Below is a sample implementation of a mock AI service named `MockAIService`. This service demonstrates how to implement the `IChatInferenceService` interface by returning sample, context-aware responses. You can replace the logic with your own AI integration. + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class MockAIService : IChatInferenceService +{ + public Task GenerateResponseAsync(ChatParameters options) + { + + } +} +``` + +## Registering the Custom AI Service + +Register the custom AI service in the **~/Program.cs** file of your ASP.NET Core Application: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Implemented AI Services + +Here are examples of AI services integrated using the `IChatInferenceService` interface: + +| Service | Documentation | +|---------|---------------| +| Claude | [Claude Integration](claude-service) | +| DeepSeek | [DeepSeek Integration](deepseek-service) | +| Groq | [Groq Integration](groq-service) | +| Gemini | [Gemini Integration](gemini-service) | + +## Troubleshooting + +If the custom AI service does not work as expected, try the following: +- **No Suggestions Displayed**: Ensure the `IChatInferenceService` implementation is registered in **Program.cs** and returns valid responses. Check for errors in the `GenerateResponseAsync` method. +- **Dependency Issues**: Verify that all required NuGet packages are installed. Run `dotnet restore` to resolve dependencies. +- **Incorrect Responses**: Debug the custom AI service implementation to ensure it processes `ChatParameters` correctly and returns expected responses. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) + diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md new file mode 100644 index 0000000000..10979f5635 --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md @@ -0,0 +1,72 @@ +--- +layout: post +title: Customize Suggestions ##Platform_Name## Smart TextArea Control | Syncfusion +description: Learn how to customize suggestion display in ##Platform_Name## Smart TextArea of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Customizaion +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Customize Suggestions in ASP.NET Core Smart TextArea + +The Syncfusion ASP.NET Core Smart TextArea control provides AI-powered autocompletion for context-aware text input, with customizable suggestion display options. This section explains how to configure the appearance and behavior of suggestions to enhance user experience in applications like issue trackers or customer support systems. + +## Configure Suggestion Display + +The `show-suggestion-on-popup` attribute controls how AI-generated suggestions are presented to users in the Smart TextArea control. Suggestions are based on the `user-role` and optional `user-phrases` attributes, which define the context and predefined phrases for autocompletion. + +### Pop-up Suggestions + +Set `show-suggestion-on-popup="true"` to display suggestions in a pop-up window above the text area, ideal for scenarios where users need to select from multiple suggestions without cluttering the input area. + +Add the following code in the `~/Pages/Index.cshtml`: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +@{ + var presets = new { + userRole = "Maintainer of an open-source project replying to GitHub issues", + userPhrases = new[] { "Thank you for contacting us.", "To investigate, we'll need a repro as a public Git repo.", "Could you please post a screenshot of NEED_INFO?", "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.", "We don't accept ZIP files as repros." }, + placeHolder = "Write your response to the GitHub issue..." }; +} + + + +{% endhighlight %} +{% endtabs %} + +![ASP.NET Core Smart TextArea Control Suggestion on popup](../images/SmartTextArea-Popup.gif) + +### Inline Suggestions + +Set `show-suggestion-on-popup="false"` (default) to display suggestions inline within the text area, suitable for seamless text entry where users can accept suggestions by continuing to type or pressing a tab key. + +Add the following code in the `~/Pages/Index.cshtml`: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +@{ + var presets = new { + userRole = "Maintainer of an open-source project replying to GitHub issues", + userPhrases = new[] { "Thank you for contacting us.", "To investigate, we'll need a repro as a public Git repo.", "Could you please post a screenshot of NEED_INFO?", "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.", "We don't accept ZIP files as repros." }, + placeHolder = "Write your response to the GitHub issue..." }; +} + + + +{% endhighlight %} +{% endtabs %} + +![ASP.NET Core Smart TextArea Control Suggestion on inline](../images/SmartTextArea-Inline.gif) + +## Troubleshooting + +If suggestions do not appear, try the following: +- **AI Configuration Errors**: Verify that the API key, endpoint, and model name are correctly configured in **Program.cs**. Check for typos or invalid credentials. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md new file mode 100644 index 0000000000..e3e00199ed --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md @@ -0,0 +1,210 @@ +--- +layout: post +title: DeepSeek AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +description: Learn how to implement a custom AI service using DeepSeek AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: DeepSeek AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# DeepSeek AI Integration with ASP.NET Core Smart TextArea + +The Syncfusion ASP.NET Core Smart TextArea control provides AI-powered autocompletion for context-aware text input, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the DeepSeek AI service with the Smart TextArea using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core App. + +## Setting Up DeepSeek + +1. **Obtain a DeepSeek API Key** + Create an account at [DeepSeek Platform](https://platform.deepseek.com), sign in, and navigate to [API Keys](https://platform.deepseek.com/api_keys) to generate an API key. +2. **Review Model Specifications** + Refer to [DeepSeek Models Documentation](https://api-docs.deepseek.com/quick_start/pricing) for details on available models (e.g., `deepseek-chat`). + +## Create a DeepSeek AI Service + +Implement the `IChatInferenceService` interface to connect the Smart TextArea to the DeepSeek service, acting as a bridge for AI-generated responses. + +1. Create a `Services` folder in your project. +2. Add a new file named `DeepSeekAIService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json`). + +```csharp +using System.Net; +using System.Text; +using System.Text.Json; +using Microsoft.Extensions.AI; + +public class DeepSeekAIService +{ + private readonly string _apiKey; + private readonly string _modelName = "deepseek-chat"; // Example model + private readonly string _endpoint = "https://api.deepseek.com/chat/completions"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public DeepSeekAIService(IConfiguration configuration) + { + _apiKey = configuration["DeepSeek:ApiKey"] ?? throw new ArgumentNullException("DeepSeek API key is missing."); + if (!HttpClient.DefaultRequestHeaders.Contains("Authorization")) + { + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}"); + } + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestBody = new DeepSeekChatRequest + { + Model = _modelName, + Temperature = 0.7f, // Controls response randomness (0.0 to 1.0) + Messages = chatMessages.Select(m => new DeepSeekMessage + { + Role = m.Role == ChatRole.User ? "user" : "system", // Align with DeepSeek API roles + Content = m.Text + }).ToList() + }; + + var content = new StringContent(JsonSerializer.Serialize(requestBody, JsonOptions), Encoding.UTF8, "application/json"); + + try + { + var response = await HttpClient.PostAsync(_endpoint, content); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + var responseObject = JsonSerializer.Deserialize(responseString, JsonOptions); + return responseObject?.Choices?.FirstOrDefault()?.Message?.Content ?? "No response from DeepSeek."; + } + catch (Exception ex) when (ex is HttpRequestException || ex is JsonException) + { + throw new InvalidOperationException("Failed to communicate with DeepSeek API.", ex); + } + } +} +``` + +N> Store the DeepSeek API key in `appsettings.json` (e.g., `{ "DeepSeek": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. + +## Define Request and Response Models + +Define C# classes to match the DeepSeek API’s JSON request and response format. + +1. Create a new file named `DeepSeekModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class DeepSeekMessage +{ + public string Role { get; set; } + public string Content { get; set; } +} + +public class DeepSeekChatRequest +{ + public string Model { get; set; } + public float Temperature { get; set; } + public List Messages { get; set; } +} + +public class DeepSeekChatResponse +{ + public List Choices { get; set; } +} + +public class DeepSeekChoice +{ + public DeepSeekMessage Message { get; set; } +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart TextArea to the DeepSeek service, acting as a bridge for AI-generated responses. + +1. Create a new file named `DeepSeekInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class DeepSeekInferenceService : IChatInferenceService +{ + private readonly DeepSeekAIService _deepSeekService; + + public DeepSeekInferenceService(DeepSeekAIService deepSeekService) + { + _deepSeekService = deepSeekService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _deepSeekService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the ASP.NET Core App + +Register the DeepSeek service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add ASP.NET Core Smart TextArea Control + +Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the DeepSeek AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +@{ + var presets = new { + userRole = "Maintainer of an open-source project replying to GitHub issues", + userPhrases = new[] { "Thank you for contacting us.", "To investigate, we'll need a repro as a public Git repo.", "Could you please post a screenshot of NEED_INFO?", "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.", "We don't accept ZIP files as repros." }, + placeHolder = "Write your response to the GitHub issue..." }; +} + + + +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart TextArea control will be rendered in the default web browser. + +![ASP.NET Core Smart TextArea Control](../images/SmartTextArea.gif) + +## Troubleshooting + +If the DeepSeek AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the DeepSeek API key and model name are correct in the configuration. Check the `DeepSeekAIService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the DeepSeek API endpoint (`https://api.deepseek.com/v1/chat/completions`) is accessible. Test with HTTP/2 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `DeepSeekAIService` and `DeepSeekInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md new file mode 100644 index 0000000000..c801bc2a9a --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md @@ -0,0 +1,19 @@ +--- +layout: post +title: Styles and Appearances in ##Platform_Name## Smart TextArea Control | Syncfusion +description: Checkout and learn here all about Styles and Appearances in ##Platform_Name## Smart TextArea of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Features +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Inherited Features from TextArea + +The Syncfusion® ASP.NET Core Smart TextArea control fully inherits all the properties, features, and styling options of the Syncfusion® ASP.NET Core TextArea control. This means that you can leverage the existing features of the Syncfusion® ASP.NET Core TextArea while benefiting from the enhanced functionality of the Smart TextArea. + +* [Form Support](https://ej2.syncfusion.com/aspnetcore/documentation/textarea/form-support) +* [Floating Labels](https://ej2.syncfusion.com/aspnetcore/documentation/textarea/floating-label) +* [Events](https://ej2.syncfusion.com/aspnetcore/documentation/textarea/events) +* [Methods](https://ej2.syncfusion.com/aspnetcore/documentation/textarea/methods) +* [Style and Appearance](https://ej2.syncfusion.com/aspnetcore/documentation/textarea/style-appearance) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md new file mode 100644 index 0000000000..8dab9fe657 --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md @@ -0,0 +1,259 @@ +--- +layout: post +title: Gemini AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +description: Learn how to implement a custom AI service using Google's Gemini AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Gemini AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Gemini AI Integration with ASP.NET Core Smart TextArea + +The Syncfusion ASP.NET Core Smart TextArea control provides AI-powered autocompletion for context-aware text input, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the Google Gemini AI service with the Smart TextArea using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core Web App. + +## Setting Up Gemini + +1. **Obtain a Gemini API Key** + Visit [Google AI Studio](https://ai.google.dev/gemini-api/docs/api-key), sign in, and generate an API key. +2. **Review Model Specifications** + Refer to [Gemini Models Documentation](https://ai.google.dev/gemini-api/docs/models) for details on available models. + +## Create a Gemini AI Service + +Create a service class to manage interactions with the Gemini API, including authentication, request/response handling, and safety settings for the Smart TextArea. + +1. Create a `Services` folder in your project. +2. Add a new file named `GeminiService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json`). + + +```csharp +using System.Net; +using System.Text; +using System.Text.Json; +using Microsoft.Extensions.AI; + +public class GeminiService +{ + private readonly string _apiKey; + private readonly string _modelName = "gemini-2.0-flash"; // Example model + private readonly string _endpoint = "https://generativelanguage.googleapis.com/v1beta/models/"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public GeminiService(IConfiguration configuration) + { + _apiKey = configuration["Gemini:ApiKey"] ?? throw new ArgumentNullException("Gemini API key is missing."); + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("x-goog-api-key", _apiKey); + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestUri = $"{_endpoint}{_modelName}:generateContent"; + var parameters = BuildGeminiChatParameters(chatMessages); + var payload = new StringContent( + JsonSerializer.Serialize(parameters, JsonOptions), + Encoding.UTF8, + "application/json" + ); + + try + { + using var response = await HttpClient.PostAsync(requestUri, payload); + response.EnsureSuccessStatusCode(); + var json = await response.Content.ReadAsStringAsync(); + var result = JsonSerializer.Deserialize(json, JsonOptions); + return result?.Candidates?.FirstOrDefault()?.Content?.Parts?.FirstOrDefault()?.Text + ?? "No response from model."; + } + catch (Exception ex) when (ex is HttpRequestException or JsonException) + { + throw new InvalidOperationException("Gemini API error.", ex); + } + } + + private GeminiChatParameters BuildGeminiChatParameters(IList messages) + { + var contents = messages.Select(m => new ResponseContent( + m.Text, + m.Role == ChatRole.User ? "user" : "model" + )).ToList(); + + return new GeminiChatParameters + { + Contents = contents, + GenerationConfig = new GenerationConfig + { + MaxOutputTokens = 2000, + StopSequences = new List { "END_INSERTION", "NEED_INFO", "END_RESPONSE" } // Configurable stop sequences + }, + SafetySettings = new List + { + new() { Category = "HARM_CATEGORY_HARASSMENT", Threshold = "BLOCK_ONLY_HIGH" }, + new() { Category = "HARM_CATEGORY_HATE_SPEECH", Threshold = "BLOCK_ONLY_HIGH" }, + new() { Category = "HARM_CATEGORY_SEXUALLY_EXPLICIT", Threshold = "BLOCK_ONLY_HIGH" }, + new() { Category = "HARM_CATEGORY_DANGEROUS_CONTENT", Threshold = "BLOCK_ONLY_HIGH" } + } + }; + } +} +``` + +N> Store the Gemini API key in `appsettings.json` (e.g., `{ "Gemini": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. The `SafetySettings` filter harmful content; adjust thresholds based on your application’s needs. + +## Define Request and Response Models + +Define C# classes to match the Gemini API’s JSON request and response format. + +1. Create a new file named `GeminiModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class Part +{ + public string Text { get; set; } +} + +public class Content +{ + public Part[] Parts { get; init; } = Array.Empty(); +} + +public class Candidate +{ + public Content Content { get; init; } = new(); +} + +public class GeminiResponseObject +{ + public Candidate[] Candidates { get; init; } = Array.Empty(); +} + +public class ResponseContent +{ + public List Parts { get; init; } + public string Role { get; init; } + + public ResponseContent(string text, string role) + { + Parts = new List { new Part { Text = text } }; + Role = role; + } +} + +public class GenerationConfig +{ + public int Temperature { get; init; } = 0; + public int TopK { get; init; } = 0; + public int TopP { get; init; } = 0; + public int MaxOutputTokens { get; init; } = 2048; + public List StopSequences { get; init; } = new(); +} + +public class SafetySetting +{ + public string Category { get; init; } = string.Empty; + public string Threshold { get; init; } = string.Empty; +} + +public class GeminiChatParameters +{ + public List Contents { get; init; } = new(); + public GenerationConfig GenerationConfig { get; init; } = new(); + public List SafetySettings { get; init; } = new(); +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart TextArea to the Gemini service, acting as a bridge for AI-generated responses. + +1. Create a new file named `GeminiInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class GeminiInferenceService : IChatInferenceService +{ + private readonly GeminiService _geminiService; + + public GeminiInferenceService(GeminiService geminiService) + { + _geminiService = geminiService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _geminiService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the ASP.NET Core App + +Register the Gemini service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); + +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add ASP.NET Core Smart TextArea Control + +Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the Gemini AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +@{ + var presets = new { + userRole = "Maintainer of an open-source project replying to GitHub issues", + userPhrases = new[] { "Thank you for contacting us.", "To investigate, we'll need a repro as a public Git repo.", "Could you please post a screenshot of NEED_INFO?", "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.", "We don't accept ZIP files as repros." }, + placeHolder = "Write your response to the GitHub issue..." }; +} + + + +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart TextArea control will be rendered in the default web browser. + +![ASP.NET Core Smart TextArea Control](../images/SmartTextArea.gif) + +## Troubleshooting + +If the Gemini AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the Gemini API key and model name are correct in the configuration. Check the `GeminiService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the Gemini API endpoint (`https://generativelanguage.googleapis.com/v1beta/models/`) is accessible. Test with HTTP/2 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `GeminiService` and `GeminiInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md new file mode 100644 index 0000000000..22bf4de892 --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md @@ -0,0 +1,237 @@ +--- +layout: post +title: Getting Started with ##Platform_Name## Smart TextArea Control | Syncfusion +description: Checkout and learn about getting started with ##Platform_Name## Smart TextArea of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Getting Started +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Getting Started with ASP.NET Core Smart TextArea Control + +This section briefly explains about how to include `ASP.NET Core Smart TextArea` control in your ASP.NET Core application using Visual Studio. + +## Prerequisites + +[System requirements for ASP.NET Core controls](https://ej2.syncfusion.com/aspnetcore/documentation/system-requirements) + +## Create ASP.NET Core web application with Razor pages + +* [Create a Project using Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-8.0&tabs=visual-studio#create-a-razor-pages-web-app) + +* [Create a Project using Syncfusion® ASP.NET Core Extension](https://ej2.syncfusion.com/aspnetcore/documentation/getting-started/project-template) + +## Install ASP.NET Core package in the application + +To add `ASP.NET Core` controls in the application, open the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search for [Syncfusion.EJ2.AspNet.Core](https://www.nuget.org/packages/Syncfusion.EJ2.AspNet.Core/) and then install it. Alternatively, you can utilize the following package manager command to achieve the same. + +{% tabs %} +{% highlight C# tabtitle="Package Manager" %} + +Install-Package Syncfusion.EJ2.AspNet.Core -Version {{ site.releaseversion }} + +{% endhighlight %} +{% endtabs %} + +N> Syncfusion® ASP.NET Core controls are available in [nuget.org.](https://www.nuget.org/packages?q=syncfusion.EJ2) Refer to [NuGet packages topic](https://ej2.syncfusion.com/aspnetcore/documentation/nuget-packages) to learn more about installing NuGet packages in various OS environments. The Syncfusion.EJ2.AspNet.Core NuGet package has dependencies, [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/) for JSON serialization and [Syncfusion.Licensing](https://www.nuget.org/packages/Syncfusion.Licensing/) for validating Syncfusion® license key. + +## Add Syncfusion® ASP.NET Core Tag Helper +Open `~/Pages/_ViewImports.cshtml` file and import the `Syncfusion.EJ2` TagHelper. + +{% tabs %} +{% highlight C# tabtitle="~/_ViewImports.cshtml" %} + +@addTagHelper *, Syncfusion.EJ2 + +{% endhighlight %} +{% endtabs %} + +## Add stylesheet and script resources + +Here, the theme and script is referred using CDN inside the `` of `~/Pages/Shared/_Layout.cshtml` file as follows, + +{% tabs %} +{% highlight cshtml tabtitle="~/_Layout.cshtml" %} + + + ... + + + + + + +{% endhighlight %} +{% endtabs %} + +N> Checkout the [Themes topic](https://ej2.syncfusion.com/aspnetcore/documentation/appearance/theme) to learn different ways ([CDN](https://ej2.syncfusion.com/aspnetcore/documentation/common/adding-script-references#cdn-reference), [NPM package](https://ej2.syncfusion.com/aspnetcore/documentation/common/adding-script-references#node-package-manager-npm), and [CRG](https://ej2.syncfusion.com/aspnetcore/documentation/common/custom-resource-generator)) to refer styles in ASP.NET Core application, and to have the expected appearance for Syncfusion® ASP.NET Core controls. + +N> Checkout the [Adding Script Reference](https://ej2.syncfusion.com/aspnetcore/documentation/common/adding-script-references) topic to learn different approaches for adding script references in your ASP.NET Core application. + +## Register Syncfusion® Script Manager + +Also, register the script manager `` at the end of `` in the ASP.NET Core application as follows. + +{% tabs %} +{% highlight cshtml tabtitle="~/_Layout.cshtml" %} + + + ... + + + + +{% endhighlight %} +{% endtabs %} + +## Configure AI Service + +To enable AI-powered autocompletion in the Smart TextArea, configure an AI model (OpenAI, Azure OpenAI, or Ollama) in your application. Install the required NuGet packages and update the **~/Program.cs** file as described below. + +### Install AI Service NuGet Packages + +Install the following NuGet packages based on your chosen AI provider: + +{% tabs %} +{% highlight c# tabtitle="Package Manager" %} + +Install-Package Microsoft.Extensions.AI +Install-Package Microsoft.Extensions.AI.OpenAI +@* For Azure OpenAI only *@ +Install-Package Azure.AI.OpenAI +@* For Ollama only *@ +Install-Package OllamaSharp + +{% endhighlight %} +{% endtabs %} + +### OpenAI Configuration + +For OpenAI, obtain an API key from [OpenAI](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key) and specify the desired model (e.g., `gpt-3.5-turbo`, `gpt-4`). Store the API key securely in a configuration file or environment variable. + +Add the following to the **~/Program.cs** file: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +using Microsoft.Extensions.AI; +using OpenAI; +using Syncfusion.EJ2; + + +builder.Services.AddRazorPages(); + +string openAIApiKey = "API-KEY"; +string openAIModel = "OPENAI_MODEL"; +OpenAIClient openAIClient = new OpenAIClient(openAIApiKey); +IChatClient openAIChatClient = openAIClient.GetChatClient(openAIModel).AsIChatClient(); +builder.Services.AddChatClient(openAIChatClient); + +builder.Services.AddSyncfusionSmartComponents() + .InjectOpenAIInference(); + +var app = builder.Build(); +.... + +{% endhighlight %} +{% endtabs %} + +### Azure OpenAI Configuration + +For Azure OpenAI, deploy a resource and model as described in [Azure OpenAI documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource). Obtain the API key, endpoint, and model name from your Azure portal. + +Add the following to the **~/Program.cs** file: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +using Syncfusion.EJ2; +using Microsoft.Extensions.AI; +using Azure.AI.OpenAI; +using System.ClientModel; + +builder.Services.AddRazorPages(); + +string azureOpenAIKey = "AZURE_OPENAI_KEY"; +string azureOpenAIEndpoint = "AZURE_OPENAI_ENDPOINT"; +string azureOpenAIModel = "AZURE_OPENAI_MODEL"; +AzureOpenAIClient azureOpenAIClient = new AzureOpenAIClient( + new Uri(azureOpenAIEndpoint), + new ApiKeyCredential(azureOpenAIKey) +); +IChatClient azureOpenAIChatClient = azureOpenAIClient.GetChatClient(azureOpenAIModel).AsIChatClient(); +builder.Services.AddChatClient(azureOpenAIChatClient); + +builder.Services.AddSyncfusionSmartComponents() + .InjectOpenAIInference(); + +var app = builder.Build(); +.... + +{% endhighlight %} +{% endtabs %} + +### Ollama Configuration + +To use Ollama for self-hosted models: + +1. Download and install Ollama from [Ollama's official website](https://ollama.com). +2. Install a model from the [Ollama Library](https://ollama.com/library) (e.g., `llama2:13b`, `mistral:7b`). +3. Configure the endpoint URL (e.g., `http://localhost:11434`) and model name. + +Add the following to the **~/Program.cs** file: + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +using Syncfusion.EJ2; +using Microsoft.Extensions.AI; +using OllamaSharp; + +builder.Services.AddRazorPages(); + +string ModelName = "MODEL_NAME"; +IChatClient chatClient = new OllamaApiClient("http://localhost:11434", ModelName); +builder.Services.AddChatClient(chatClient); + +builder.Services.AddSyncfusionSmartComponents() + .InjectOpenAIInference(); + +var app = builder.Build(); +.... + +{% endhighlight %} +{% endtabs %} + +## Add ASP.NET Core Smart TextArea Control + +The **user-role** attribute (required) defines the context for AI autocompletion based on the user's role. The **user-phrases** attribute (optional) provides predefined expressions aligned with the application's tone and common phrases. + +Now, add the Syncfusion® ASP.NET Core Smart TextArea tag helper in `~/Pages/Index.cshtml` page. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +@{ + var presets = new { + userRole = "Maintainer of an open-source project replying to GitHub issues", + userPhrases = new[] { "Thank you for contacting us.", "To investigate, we'll need a repro as a public Git repo.", "Could you please post a screenshot of NEED_INFO?", "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.", "We don't accept ZIP files as repros." }, + placeHolder = "Write your response to the GitHub issue..." }; +} + + + +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart TextArea control will be rendered in the default web browser. + +![ASP.NET Core Smart TextArea Control](../images/SmartTextArea.gif) + +## Troubleshooting + +If you encounter issues, try the following: +- **NuGet Installation Errors**: Ensure a stable internet connection and set the NuGet package source to `https://www.nuget.org`. Run `dotnet restore` again. +- **AI Service Configuration Errors**: Verify the API key, endpoint, and model name in **Program.cs**. Check for typos or incorrect values. \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md new file mode 100644 index 0000000000..0d6f0324c0 --- /dev/null +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md @@ -0,0 +1,211 @@ +--- +layout: post +title: Groq AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +description: Learn how to implement a custom AI service using Groq AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. +platform: ej2-asp-core-mvc +control: Groq AI +publishingplatform: ##Platform_Name## +documentation: ug +--- + +# Groq AI Integration with ASP.NET Core Smart TextArea + +The Syncfusion ASP.NET Core Smart TextArea control provides AI-powered autocompletion for context-aware text input, typically using OpenAI or Azure OpenAI. This guide explains how to integrate the Groq AI service with the Smart TextArea using the `IChatInferenceService` interface, enabling custom AI-driven responses in a ASP.NET Core App. + +## Setting Up Groq + +1. **Create a Groq Account** + Visit [Groq Cloud Console](https://console.groq.com), sign up or sign in, and complete the verification process. +2. **Obtain an API Key** + Navigate to [API Keys](https://console.groq.com/keys) in the Groq Console and click "Create API Key." +3. **Review Model Specifications** + Refer to [Groq Models Documentation](https://console.groq.com/docs/models) for details on available models (e.g., `llama3-8b-8192`). + +## Create a Groq AI Service + +Create a service class to manage interactions with the Groq API, including authentication and response processing for the Smart TextArea. + +1. Create a `Services` folder in your project. +2. Add a new file named `GroqService.cs` in the `Services` folder. +3. Implement the service as shown below, storing the API key securely in a configuration file or environment variable (e.g., `appsettings.json` or environment variables). + +```csharp +using Microsoft.Extensions.AI; +using System.Net; +using System.Text; +using System.Text.Json; + +public class GroqService +{ + private readonly string _apiKey; + private readonly string _modelName = "llama-3.3-70b-versatile"; // Example model + private readonly string _endpoint = "https://api.groq.com/openai/v1/chat/completions"; + private static readonly HttpClient HttpClient = new(new SocketsHttpHandler + { + PooledConnectionLifetime = TimeSpan.FromMinutes(30), + EnableMultipleHttp2Connections = true + }) + { + DefaultRequestVersion = HttpVersion.Version20 // Fallback to HTTP/2 for broader compatibility + }; + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + public GroqService(IConfiguration configuration) + { + _apiKey = configuration["Groq:ApiKey"] ?? throw new ArgumentNullException("Groq API key is missing."); + if (!HttpClient.DefaultRequestHeaders.Contains("Authorization")) + { + HttpClient.DefaultRequestHeaders.Clear(); + HttpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}"); + } + } + + public async Task CompleteAsync(IList chatMessages) + { + var requestPayload = new GroqChatParameters + { + Model = _modelName, + Messages = chatMessages.Select(m => new Message + { + Role = m.Role == ChatRole.User ? "user" : "assistant", + Content = m.Text + }).ToList(), + Stop = new List { "END_INSERTION", "NEED_INFO", "END_RESPONSE" } // Configurable stop sequences + }; + + var content = new StringContent(JsonSerializer.Serialize(requestPayload, JsonOptions), Encoding.UTF8, "application/json"); + + try + { + var response = await HttpClient.PostAsync(_endpoint, content); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + var responseObject = JsonSerializer.Deserialize(responseString, JsonOptions); + return responseObject?.Choices?.FirstOrDefault()?.Message?.Content ?? "No response from model."; + } + catch (Exception ex) when (ex is HttpRequestException || ex is JsonException) + { + throw new InvalidOperationException("Failed to communicate with Groq API.", ex); + } + } +} +``` + +N> Store the Groq API key in `appsettings.json` (e.g., `{ "Groq": { "ApiKey": "your-api-key" } }`) or as an environment variable to ensure security. + +## Define Request and Response Models + +Define C# classes to match the Groq API’s request and response format. + +1. Create a new file named `GroqModels.cs` in the `Services` folder. +2. Add the following model classes: + +```csharp +public class Choice +{ + public Message Message { get; set; } +} + +public class Message +{ + public string Role { get; set; } + public string Content { get; set; } +} + +public class GroqChatParameters +{ + public string Model { get; set; } + public List Messages { get; set; } + public List Stop { get; set; } +} + +public class GroqResponseObject +{ + public string Model { get; set; } + public List Choices { get; set; } +} +``` + +## Create a Custom AI Service + +Implement the `IChatInferenceService` interface to connect the Smart TextArea to the Groq service. + +1. Create a new file named `GroqInferenceService.cs` in the `Services` folder. +2. Add the following implementation: + +```csharp +using Syncfusion.EJ2.AI; +using System.Threading.Tasks; + +public class GroqInferenceService : IChatInferenceService +{ + private readonly GroqService _groqService; + + public GroqInferenceService(GroqService groqService) + { + _groqService = groqService; + } + + public async Task GenerateResponseAsync(ChatParameters options) + { + return await _groqService.CompleteAsync(options.Messages); + } +} +``` + +## Configure the ASP.NET Core App + +Register the Groq service and `IChatInferenceService` implementation in the dependency injection container. + +Update the **~/Program.cs** file as follows: + +```csharp +using Syncfusion.EJ2; +using Syncfusion.EJ2.AI; + +builder.Services.AddRazorPages(); +builder.Services.AddSyncfusionSmartComponents(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); +// ... +``` + +## Add ASP.NET Core Smart TextArea Control + +Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the Groq AI integration. + +{% tabs %} +{% highlight cshtml tabtitle="CSHTML" %} + +@{ + var presets = new { + userRole = "Maintainer of an open-source project replying to GitHub issues", + userPhrases = new[] { "Thank you for contacting us.", "To investigate, we'll need a repro as a public Git repo.", "Could you please post a screenshot of NEED_INFO?", "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.", "We don't accept ZIP files as repros." }, + placeHolder = "Write your response to the GitHub issue..." }; +} + + + +{% endhighlight %} +{% endtabs %} + +Press Ctrl+F5 (Windows) or +F5 (macOS) to run the app. Then, the Syncfusion® ASP.NET Core +Smart TextArea control will be rendered in the default web browser. + +![ASP.NET Core Smart TextArea Control](../images/SmartTextArea.gif) + +## Troubleshooting + +If the Groq AI integration does not work, try the following: +- **No Suggestions Displayed**: Verify that the Groq API key and model name are correct in the configuration. Check the `GroqService` implementation for errors. +- **HTTP Request Failures**: Ensure a stable internet connection and that the Groq API endpoint (`https://api.groq.com/openai/v1/chat/completions`) is accessible. Test with HTTP/2 instead of HTTP/3 if compatibility issues arise. +- **Service Registration Errors**: Confirm that `GroqService` and `GroqInferenceService` are registered in **Program.cs**. + +## See Also + +- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) diff --git a/ej2-asp-core-mvc/smart-textarea/images/SmartTextArea-Inline.gif b/ej2-asp-core-mvc/smart-textarea/images/SmartTextArea-Inline.gif new file mode 100644 index 0000000000000000000000000000000000000000..8b1ff768fe5e473ee43599124fbb3264a8f99443 GIT binary patch literal 46939 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 z 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 literal 0 HcmV?d00001 diff --git a/ej2-asp-core-mvc/smart-textarea/images/SmartTextArea-Popup.gif b/ej2-asp-core-mvc/smart-textarea/images/SmartTextArea-Popup.gif new file mode 100644 index 0000000000000000000000000000000000000000..efcbf7fbeb515ff387fe7c4d2c9a1d6a79012223 GIT binary patch literal 53407 zcmeFYWl&tvy0D2f&_DwXK^ku)xCVj~+=5GR3n76JAP^vUaCZq1v~hwvjk~*BFZ^dw=b&Rl95LcdvJ?RnN1Rf|9(D@LN6%Gt?U-%0I$w8p~^z zn1qSO9!^Wk0Hu|J(wah{f>65GP$oVovlmn-0xBC1RY-%Hl|mic>1e6xpmub0oOJB= zbo}mgYMBf&@{G@4G4d)izc6Nj(y}PJunV}eJ9ThK+H$>A;Cf}i^|pYAmYPS_=!J$4 zA2Z!cO-BKTS|N2)A+J6$S{gACA+hjTaR!=KVxq6iq9nw{BwvY3aY#z>GD%BI%g{q* zq$FgeCFNyh6y#(TOdORIq2`#ambIzQ zMysx_uA$7WsivyM|6EH$P20gqJD^QRN9T>UmM)Z5SCU8XjkbRFo`If$Vd0*Unv9XY zu8FacDG!a=*Hm*;8!#%0*4 zy!cE@`&pLmv)w0$W~8H&larmd^B0G&%rsx!+`gvNf2}`p)#P$@G;lW%b9ejd>G9Rm z)6={2-sdS=4t!e={rPGAeSHG;WdZ{OgL0dLMv=j-`ynAAp}|36VPO$gVv*sIQIV0+ zVl**Y&*Kvk65?VK%3G4-rjnDBQ`V5Fj{K?KcBzBMY4S8_s?XEZXw%Zt(k*y1)6=q? zRbWwO+1c57d3pJ@odpK;1<8(uPqBwAe~P(Z6@J>4@2D#a!mB=TR%cb#R8`c})YMmH z)z`usE|731@y2-P#)g`vr&zmfMIzfAplxk!?O&gFc6N5v2KDsx^!kbR_4N(*_6}t_ z4i68HjEszadp>&dF#dp?h!mfinwl*MoQo2g`=LEw`EGuGetCHrQSfbTZEZ6}Y7>dv zg8Of8Z|_XD@3kfG=V*U4!4=-u|hw`t$eZZaMXSr~dx_{$a@X;m`WR!^2~<-Qz{i<5M6nkc*MX zwN&JG7V@wNc~y;kn0k5?Byt0ZM4}*3=#aQ-ayr^FQW|nExOmV}pUQ#m4*&z}sfpts zwegQK3Hisx|1OgMT_pd1EfOFSWd)l`u@cr90DQ(~JW!e49Rg-}ovv7w(;ETdvq210 z<@U!wWx}bHs`CaDShS0c2dndklX>0^r7P7GjHU@W9U=y63dge~18}Hc*A`9YD$4a4 z4b}dfF4V|WpDe?jj#fvT8-A^I1mM!DwZPA}1`^oK##$OL_9k+bv(#Ff zu8tOJKCO+lHsAbO?~Xvys<*ZLx!9jBF&l4dy}LQv8qQL0Z+p1Ay*OGMZ*PB^N-$a0 zeF3D_>wZ9{qIG|e!2WswSe|7gkeFhBJP7ikXd{^F>;6UvG?-;GlrhPAGmNF6XfvFn zet$E9r;lYTl7G&6D@tg$Xe(OmdVecM5|ed1R+jYRcAO&9&+T{>frIS?4SCj`L>=9a zJKyy`{M<=0{(7*JY#z+In_`*tarcLH!Oz`P+xmmuG>1Ocy>#cfk9!$zyFd3by{-@T zvV1Yw_F;jfHv8G3OvU>-kphSNxv}zW2YHFQHV64BABqnO(!U-a6vBep4vX@VYz}`G z6%-#9m)0L1mQ?m3*^WwU=WLG3;Jd{~+NpI zueST^qhIYPSR7{^05aRNP9SsXSr@P3$ZFa@1t@(KJSNyaQq%% zOt$?!$WmDPdx)dq`1deRKgY!g|Ge$RsL)>N#hBR5@x{0#7U$)JEScTqq#|?K<&=ux z$>p?$0_V#nSnOo)tiDy*)ts^G$<@4h2

JWwPD%qIF@}^^$GF$@Q{BKj#g?dEV}3 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 z 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 literal 0 HcmV?d00001 diff --git a/ej2-asp-core-toc.html b/ej2-asp-core-toc.html index bd3e9fc710..f9a7ba8244 100644 --- a/ej2-asp-core-toc.html +++ b/ej2-asp-core-toc.html @@ -147,6 +147,51 @@ +

  • Smart Components + +
  • +
  • Accordion
    • Getting Started
    • From e2a67b8f894360dad76dcc05506a712f8d8a3fe6 Mon Sep 17 00:00:00 2001 From: Arun Kumar Ragu Date: Fri, 24 Oct 2025 18:18:50 +0530 Subject: [PATCH 2/7] 988747: Drafted UG for SmartPaste and SmartTextArea. --- .../smart-paste/EJ2_ASP.NETCORE/deepseek-service.md | 2 +- ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md | 2 +- ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md | 2 +- .../smart-textarea/EJ2_ASP.NETCORE/gemini-service.md | 2 +- ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md index 146bd99697..ecd8ac92a1 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md @@ -176,7 +176,7 @@ var app = builder.Build(); ## Add the Smart Paste Button -Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the DeepSeek AI integration. +Add the Smart Paste Button to a form in the **~/Pages/Index.cshtml** file to test the DeepSeek AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md index beb4f06b08..58c00dffd3 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md @@ -224,7 +224,7 @@ var app = builder.Build(); ## Add the Smart Paste Button -Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the Gemini AI integration. +Add the Smart Paste Button to a form in the **~/Pages/Index.cshtml** file to test the Gemini AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md index 63a8780a92..9fb7be2a43 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md @@ -177,7 +177,7 @@ var app = builder.Build(); ## Add the Smart Paste Button -Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the Gemini AI integration. +Add the Smart Paste Button to a form in the **~/Pages/Index.cshtml** file to test the Gemini AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md index 8dab9fe657..fff732c93c 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md @@ -225,7 +225,7 @@ var app = builder.Build(); ## Add ASP.NET Core Smart TextArea Control -Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the Gemini AI integration. +Add the Smart TextArea in the **~/Pages/Index.cshtml** file to test the Gemini AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md index 0d6f0324c0..86d0c3e6eb 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md @@ -177,7 +177,7 @@ var app = builder.Build(); ## Add ASP.NET Core Smart TextArea Control -Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the Groq AI integration. +Add the Smart TextArea in the **~/Pages/Index.cshtml** file to test the Groq AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} From cb9ba019071be4f4f732a9ffccb69436fe488dee Mon Sep 17 00:00:00 2001 From: Arun Kumar Ragu Date: Fri, 24 Oct 2025 18:20:57 +0530 Subject: [PATCH 3/7] 988747: Drafted UG for SmartPaste and SmartTextArea. --- .../smart-textarea/EJ2_ASP.NETCORE/claude-service.md | 2 +- .../smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md index 5182956eb8..e6a8bbc6bc 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md @@ -178,7 +178,7 @@ var app = builder.Build(); ## Add ASP.NET Core Smart TextArea Control -Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the Claude AI integration. +Add the Smart TextArea in the **~/Pages/Index.cshtml** file to test the Claude AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md index e3e00199ed..2757a6bccf 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md @@ -176,7 +176,7 @@ var app = builder.Build(); ## Add ASP.NET Core Smart TextArea Control -Add the Smart TextArea in the **~/Pages/Index.chtml** file to test the DeepSeek AI integration. +Add the Smart TextArea in the **~/Pages/Index.cshtml** file to test the DeepSeek AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} From 84552dfe08ffe3e2144beb10dc1ecc0a05200a7e Mon Sep 17 00:00:00 2001 From: Arun Kumar Ragu Date: Mon, 27 Oct 2025 10:10:44 +0530 Subject: [PATCH 4/7] 988747: Drafted UG for SmartPaste and SmartTextArea. --- .../smart-paste/EJ2_ASP.NETCORE/annotation.md | 4 ---- .../smart-paste/EJ2_ASP.NETCORE/claude-service.md | 10 +++------- .../EJ2_ASP.NETCORE/custom-inference-backend.md | 7 +------ .../smart-paste/EJ2_ASP.NETCORE/customization.md | 3 +-- .../smart-paste/EJ2_ASP.NETCORE/deepseek-service.md | 8 ++------ .../smart-paste/EJ2_ASP.NETCORE/gemini-service.md | 8 ++------ .../smart-paste/EJ2_ASP.NETCORE/groq-service.md | 8 ++------ .../smart-textarea/EJ2_ASP.NETCORE/claude-service.md | 6 +----- .../EJ2_ASP.NETCORE/custom-inference-backend.md | 6 +----- .../smart-textarea/EJ2_ASP.NETCORE/customization.md | 6 +----- .../smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md | 6 +----- .../smart-textarea/EJ2_ASP.NETCORE/gemini-service.md | 6 +----- .../smart-textarea/EJ2_ASP.NETCORE/groq-service.md | 6 +----- 13 files changed, 17 insertions(+), 67 deletions(-) diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md index bcad4400b0..77238358f2 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/annotation.md @@ -75,7 +75,3 @@ Use the `data-smartpaste-description` attribute to provide custom instructions f {% endtabs %} ![Syncfusion ASP.NET Core Smart Paste Button with Annotation](../images/SmartPaste_Annotation.gif) - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md index 99494db74b..92f6ea46f2 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/claude-service.md @@ -1,6 +1,6 @@ --- layout: post -title: Claude AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +title: Claude AI in ##Platform_Name## Smart Paste Button Control | Syncfusion description: Learn how to implement a custom AI service using Claude AI with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Claude AI @@ -179,7 +179,7 @@ var app = builder.Build(); ## Add the Smart Paste Button -Add the Smart Paste Button to a form in the **~/Pages/Index.chtml** file to test the Claude AI integration. +Add the Smart Paste Button to a form in the **~/Pages/Index.cshtml** file to test the Claude AI integration. {% tabs %} {% highlight cshtml tabtitle="CSHTML" %} @@ -249,8 +249,4 @@ Smart Paste Button control will be rendered in the default web browser. If the Claude AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the Claude API key and model name are correct in the configuration. Check the `ClaudeAIService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the Claude API endpoint (`https://api.anthropic.com/v1/messages`) is accessible. Test with HTTP/2 if compatibility issues arise. -- **Service Registration Errors**: Confirm that `ClaudeAIService` and `ClaudeInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) +- **Service Registration Errors**: Confirm that `ClaudeAIService` and `ClaudeInferenceService` are registered in **Program.cs**. \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md index 5c235ebfe7..a8b829f83b 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/custom-inference-backend.md @@ -1,6 +1,6 @@ --- layout: post -title: Custom AI Service Integration with ##Platform_Name## Smart Paste Button Control | Syncfusion +title: Custom AI with ##Platform_Name## Smart Paste Button Control | Syncfusion description: Learn how to integrate custom AI services with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Custom AI Service @@ -75,8 +75,3 @@ If the custom AI integration does not work as expected, try the following: - **Fields Not Populating**: Verify that the custom AI service’s endpoint, model, and API key are correct in `appsettings.json`. Ensure the `GenerateResponseAsync` method returns valid data. - **Service Registration Errors**: Confirm that `CustomAIService` and `CustomInferenceService` are registered in **Program.cs**. - **AI Parsing Errors**: Check the AI service’s response format and ensure it matches the expected `CustomAIResponse` structure. Test the API independently to verify connectivity. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) - diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md index c6d1e17811..6788ca4a80 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/customization.md @@ -17,5 +17,4 @@ The Syncfusion® ASP.NET Core Smart Paste Bu ## See Also -- [ASP.NET Core Button Control: Types and Styles](https://ej2.syncfusion.com/aspnetcore/documentation/button/types-and-styles) -- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) +- [ASP.NET Core Button Control: Types and Styles](https://ej2.syncfusion.com/aspnetcore/documentation/button/types-and-styles) \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md index ecd8ac92a1..a0de60915e 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/deepseek-service.md @@ -1,6 +1,6 @@ --- layout: post -title: DeepSeek AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +title: DeepSeek AI in ##Platform_Name## Smart Paste Button Control | Syncfusion description: Learn how to implement a custom AI service using DeepSeek AI with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: DeepSeek AI @@ -246,8 +246,4 @@ Smart Paste Button control will be rendered in the default web browser. If the DeepSeek AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the DeepSeek API key and model name are correct in the configuration. Check the `DeepSeekAIService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the DeepSeek API endpoint (`https://api.deepseek.com/v1/chat/completions`) is accessible. Test with HTTP/2 if compatibility issues arise. -- **Service Registration Errors**: Confirm that `DeepSeekAIService` and `DeepSeekInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file +- **Service Registration Errors**: Confirm that `DeepSeekAIService` and `DeepSeekInferenceService` are registered in **Program.cs**. \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md index 58c00dffd3..0819c089ff 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/gemini-service.md @@ -1,6 +1,6 @@ --- layout: post -title: Gemini AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +title: Gemini AI in ##Platform_Name## Smart Paste Button Control | Syncfusion description: Learn how to implement a custom AI service using Google's Gemini API with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Gemini AI @@ -294,8 +294,4 @@ Smart Paste Button control will be rendered in the default web browser. If the Gemini AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the Gemini API key and model name are correct in the configuration. Check the `GeminiService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the Gemini API endpoint (`https://generativelanguage.googleapis.com/v1beta/models/`) is accessible. Test with HTTP/2 if compatibility issues arise. -- **Service Registration Errors**: Confirm that `GeminiService` and `GeminiInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file +- **Service Registration Errors**: Confirm that `GeminiService` and `GeminiInferenceService` are registered in **Program.cs**. \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md index 9fb7be2a43..6efb844873 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/groq-service.md @@ -1,6 +1,6 @@ --- layout: post -title: Groq AI Integration in ##Platform_Name## Smart Paste Button Control | Syncfusion +title: Groq AI in ##Platform_Name## Smart Paste Button Control | Syncfusion description: Learn how to implement a custom AI service using Groq AI with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Groq AI @@ -247,8 +247,4 @@ Smart Paste Button control will be rendered in the default web browser. If the Groq AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the Groq API key and model name are correct in the configuration. Check the `GroqService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the Groq API endpoint (`https://api.groq.com/openai/v1/chat/completions`) is accessible. Test with HTTP/2 instead of HTTP/3 if compatibility issues arise. -- **Service Registration Errors**: Confirm that `GroqService` and `GroqInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart Paste Button](https://ej2.syncfusion.com/aspnetcore/documentation/smart-paste/getting-started) \ No newline at end of file +- **Service Registration Errors**: Confirm that `GroqService` and `GroqInferenceService` are registered in **Program.cs**. \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md index e6a8bbc6bc..1b69f3f3dc 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/claude-service.md @@ -1,6 +1,6 @@ --- layout: post -title: Claude AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +title: Claude AI in ##Platform_Name## Smart TextArea Control | Syncfusion description: Learn how to implement a custom AI service using Claude AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Claude AI @@ -206,7 +206,3 @@ If the Claude AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the Claude API key and model name are correct in the configuration. Check the `ClaudeAIService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the Claude API endpoint (`https://api.anthropic.com/v1/messages`) is accessible. Test with HTTP/2 if compatibility issues arise. - **Service Registration Errors**: Confirm that `ClaudeAIService` and `ClaudeInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md index 75e7fba538..083a4f2c9e 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/custom-inference-backend.md @@ -1,6 +1,6 @@ --- layout: post -title: Custom AI Service Integration with ##Platform_Name## Smart TextArea Control | Syncfusion +title: Custom AI with ##Platform_Name## Smart TextArea Control | Syncfusion description: Learn how to integrate custom AI services with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Custom AI Service @@ -78,7 +78,3 @@ If the custom AI service does not work as expected, try the following: - **Dependency Issues**: Verify that all required NuGet packages are installed. Run `dotnet restore` to resolve dependencies. - **Incorrect Responses**: Debug the custom AI service implementation to ensure it processes `ChatParameters` correctly and returns expected responses. -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) - diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md index 10979f5635..48b3fea419 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/customization.md @@ -65,8 +65,4 @@ Add the following code in the `~/Pages/Index.cshtml`: ## Troubleshooting If suggestions do not appear, try the following: -- **AI Configuration Errors**: Verify that the API key, endpoint, and model name are correctly configured in **Program.cs**. Check for typos or invalid credentials. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) \ No newline at end of file +- **AI Configuration Errors**: Verify that the API key, endpoint, and model name are correctly configured in **Program.cs**. Check for typos or invalid credentials. \ No newline at end of file diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md index 2757a6bccf..86e8c30e1d 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/deepseek-service.md @@ -1,6 +1,6 @@ --- layout: post -title: DeepSeek AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +title: DeepSeek AI in ##Platform_Name## Smart TextArea Control | Syncfusion description: Learn how to implement a custom AI service using DeepSeek AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: DeepSeek AI @@ -204,7 +204,3 @@ If the DeepSeek AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the DeepSeek API key and model name are correct in the configuration. Check the `DeepSeekAIService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the DeepSeek API endpoint (`https://api.deepseek.com/v1/chat/completions`) is accessible. Test with HTTP/2 if compatibility issues arise. - **Service Registration Errors**: Confirm that `DeepSeekAIService` and `DeepSeekInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md index fff732c93c..aa5d9275a4 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/gemini-service.md @@ -1,6 +1,6 @@ --- layout: post -title: Gemini AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +title: Gemini AI in ##Platform_Name## Smart TextArea Control | Syncfusion description: Learn how to implement a custom AI service using Google's Gemini AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Gemini AI @@ -253,7 +253,3 @@ If the Gemini AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the Gemini API key and model name are correct in the configuration. Check the `GeminiService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the Gemini API endpoint (`https://generativelanguage.googleapis.com/v1beta/models/`) is accessible. Test with HTTP/2 if compatibility issues arise. - **Service Registration Errors**: Confirm that `GeminiService` and `GeminiInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md index 86d0c3e6eb..dabbe6d793 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/groq-service.md @@ -1,6 +1,6 @@ --- layout: post -title: Groq AI Integration in ##Platform_Name## Smart TextArea Control | Syncfusion +title: Groq AI in ##Platform_Name## Smart TextArea Control | Syncfusion description: Learn how to implement a custom AI service using Groq AI with ##Platform_Name## Smart TextArea control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Groq AI @@ -205,7 +205,3 @@ If the Groq AI integration does not work, try the following: - **No Suggestions Displayed**: Verify that the Groq API key and model name are correct in the configuration. Check the `GroqService` implementation for errors. - **HTTP Request Failures**: Ensure a stable internet connection and that the Groq API endpoint (`https://api.groq.com/openai/v1/chat/completions`) is accessible. Test with HTTP/2 instead of HTTP/3 if compatibility issues arise. - **Service Registration Errors**: Confirm that `GroqService` and `GroqInferenceService` are registered in **Program.cs**. - -## See Also - -- [Getting Started with Syncfusion ASP.NET Core Smart TextArea](https://ej2.syncfusion.com/aspnetcore/documentation/smart-textarea/getting-started) From 446998c1b2f57fb99eec8be1b1a400334363f63f Mon Sep 17 00:00:00 2001 From: Arun Kumar Ragu Date: Mon, 27 Oct 2025 10:32:26 +0530 Subject: [PATCH 5/7] 988747: Drafted UG for SmartPaste and SmartTextArea. --- ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md | 2 +- ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md index bad130b8dc..68d66a9ba7 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md @@ -1,6 +1,6 @@ --- layout: post -title: Getting Started with ##Platform_Name## Smart Paste Button Control | Syncfusion +title: Getting Started with ##Platform_Name## Smart Paste Button | Syncfusion description: Checkout and learn about getting started with ##Platform_Name## Smart Paste Button control of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Getting Started diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md index c801bc2a9a..2120fa3d33 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/features.md @@ -1,6 +1,6 @@ --- layout: post -title: Styles and Appearances in ##Platform_Name## Smart TextArea Control | Syncfusion +title: Styles and Appearances in ##Platform_Name## Smart TextArea | Syncfusion description: Checkout and learn here all about Styles and Appearances in ##Platform_Name## Smart TextArea of Syncfusion Essential JS 2 and more details. platform: ej2-asp-core-mvc control: Features From a01bad3535dd36c923a06e80de3bf3c579e7b083 Mon Sep 17 00:00:00 2001 From: ArunKumar-SF3979 <121280793+ArunKumar-SF3979@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:36:54 +0530 Subject: [PATCH 6/7] 988747: Update project creation link for Syncfusion ASP.NET Core --- ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md index 68d66a9ba7..710c723db8 100644 --- a/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md +++ b/ej2-asp-core-mvc/smart-paste/EJ2_ASP.NETCORE/getting-started.md @@ -20,7 +20,7 @@ This section briefly explains about how to include `ASP.NET Core Smart Paste But * [Create a Project using Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-8.0&tabs=visual-studio#create-a-razor-pages-web-app) -* [Create a Project using Syncfusion® ASP.NET Core Extension](https://ej2.syncfusion.com/aspnetcore/documentation/getting-started/project-template) +* [Create a Project using Syncfusion® ASP.NET Core Extension](https://ej2.syncfusion.com/aspnetcore/documentation/visual-studio-integration/create-project) ## Install ASP.NET Core package in the application From 95fa9fc9251104faf2932c0a2a4d171fe8b52fae Mon Sep 17 00:00:00 2001 From: ArunKumar-SF3979 <121280793+ArunKumar-SF3979@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:37:35 +0530 Subject: [PATCH 7/7] 988747: Update project creation link for Syncfusion ASP.NET Core --- .../smart-textarea/EJ2_ASP.NETCORE/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md index 22bf4de892..7e2f8536fe 100644 --- a/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md +++ b/ej2-asp-core-mvc/smart-textarea/EJ2_ASP.NETCORE/getting-started.md @@ -20,7 +20,7 @@ This section briefly explains about how to include `ASP.NET Core Smart TextArea` * [Create a Project using Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-8.0&tabs=visual-studio#create-a-razor-pages-web-app) -* [Create a Project using Syncfusion® ASP.NET Core Extension](https://ej2.syncfusion.com/aspnetcore/documentation/getting-started/project-template) +* [Create a Project using Syncfusion® ASP.NET Core Extension](https://ej2.syncfusion.com/aspnetcore/documentation/visual-studio-integration/create-project) ## Install ASP.NET Core package in the application @@ -234,4 +234,4 @@ Smart TextArea control will be rendered in the default web browser. If you encounter issues, try the following: - **NuGet Installation Errors**: Ensure a stable internet connection and set the NuGet package source to `https://www.nuget.org`. Run `dotnet restore` again. -- **AI Service Configuration Errors**: Verify the API key, endpoint, and model name in **Program.cs**. Check for typos or incorrect values. \ No newline at end of file +- **AI Service Configuration Errors**: Verify the API key, endpoint, and model name in **Program.cs**. Check for typos or incorrect values.