- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 14
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5259",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://0.0.0.0:7216;https://0.0.0.0:7217",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
This means that the controller was accessible via the following endpoint:
https://192.168.2.50:7217/WeatherForecastIn OpenWebUI tools, I wrote:
import requests
import urllib3
class Tools:
def today_from_csharp_http(self) -> str:
"""
Get the current weather.
"""
url = "https://192.168.2.50:7217/WeatherForecast"
try:
r = requests.get(url, timeout=5, verify=False)
r.raise_for_status()
data = r.json()
if not isinstance(data, list) or len(data) == 0:
return f"Unexpected JSON: {type(data).__name__}: {data}"
first = data[0]
date = first.get("date")
summary = first.get("summary")
temp = first.get("temperatureC")
return f"OK: {date} | {summary} | {temp}°C"
except Exception as e:
return f"HTTP request failed: {e}"
The tool must be enabled for this model by checking the corresponding tool checkbox.
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 1156
Here is my Example how to post Joomla! article from .NET.
Four steps are needed:
- Open Joomla! admin page
- Login to Joomla!
- Open add article page
- Save and close
First we will create HttpClient and same instance I will use for every step:
HttpClientHandler httpClientHandler = new HttpClientHandler
{
CookieContainer = new CookieContainer(),
UseCookies = true,
AllowAutoRedirect = true
};
HttpClient client = new HttpClient(httpClientHandler);
For every step we will need token
static string ExtractTokenName(string html)
{
var regex = new Regex(@"""csrf\.token"":""(?<token>[a-f0-9]{32})""");
var match = regex.Match(html);
if (match.Success)
{
return match.Groups["token"].Value;
}
throw new Exception("CSRF-Token not found.");
}
- Open Joomla! admin page:
async Task<string> OpenJoomlaAdminPage(HttpClient httpClient, string url) { HttpResponseMessage getResponse = await httpClient.GetAsync(url); string html = await getResponse.Content.ReadAsStringAsync(); return html; } - Login to Joomla!:
async Task<bool> LoginToJoomla(HttpClient httpClient, string url, string username, string password, string joomlaAdminPagehtml) { var tokenName = ExtractTokenName(joomlaAdminPagehtml); var tokenValue = "1"; var formContent = new FormUrlEncodedContent([ new KeyValuePair<string, string>("username", username), new KeyValuePair<string, string>("passwd", password), new KeyValuePair<string, string>("option", "com_login"), new KeyValuePair<string, string>("task", "login"), new KeyValuePair<string, string>(tokenName, tokenValue) ]); HttpResponseMessage postResponse = await httpClient.PostAsync(url, formContent); string postResult = await postResponse.Content.ReadAsStringAsync(); return postResult.Contains("mod_quickicon") || postResult.Contains("cpanel"); } - Open add article page:
async Task<string> OpenAddArticle(HttpClient httpClient, string addArticleUrl) { HttpResponseMessage createResponse = await httpClient.GetAsync(addArticleUrl); string createHtml = await createResponse.Content.ReadAsStringAsync(); return ExtractTokenName(createHtml); } - Save and close:
async Task<bool> PostArticleToJoomla(HttpClient httpClient, string url, string articleToken, string title, string catid, string articletext) { var formData = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("jform[title]", title), new KeyValuePair<string, string>("jform[catid]", catid), new KeyValuePair<string, string>("jform[language]", "*"), new KeyValuePair<string, string>("jform[state]", "1"), new KeyValuePair<string, string>("jform[articletext]", articletext), new KeyValuePair<string, string>("task", "article.save"), new KeyValuePair<string, string>(articleToken, "1") }); HttpResponseMessage postResponse = await httpClient.PostAsync(url, formData); string postResultHtml = await postResponse.Content.ReadAsStringAsync(); return postResultHtml.Contains("Article saved."); }
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 1185
cancellationToken CancellationToken A cancellation token that can be used to cancel the work if it has not yet started. Run(FuncFrom here. If you have an async method that you want to cancel, you need to provide a CancellationTokenSource to that method. Example:, CancellationToken) does not pass cancellationToken to action.
public void ExecuteWithCancellationTokenSource(string path, CancellationTokenSource cancellationTokenSource)
{
foreach (var fileName in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
fileNameProgress.Report(fileName);
Thread.Sleep(1000);
if (cancellationTokenSource.IsCancellationRequested) break;
}
}
Otherwise, you can't cancel it if you have a method like this:
public void ExecuteWithoutCancellationTokenSource(string path)
{
foreach (var fileName in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
fileNameProgress.Report(fileName);
Thread.Sleep(1000);
}
}
and you start execution something like this:
Task task = Task.Run(() => { readFromHdd.ExecuteWithoutCancellationTokenSource(_path); }, _cancellationTokenSource.Token);
try
{
await Task.WhenAll(task);
}
catch (Exception ex)
{
tbFileNames.AppendText(ex.Message + Environment.NewLine);
}
finally
{
tbFileNames.AppendText("Done" + Environment.NewLine);
}
it will never stop. Or even worse, if you start like this:
Task task = Task.Run(() => { readFromHdd.ExecuteWithoutCancellationTokenSource(_path); }, _cancellationTokenSource.Token);
Task groupOfAllTasks = Task.WhenAll(task).ContinueWith(t =>
{
if (t.IsFaulted)
{
throw new Exception("rException!");
}
}, _cancellationTokenSource.Token);
List<Task> allTasks =
[
groupOfAllTasks
];
try
{
await Task.WhenAll(allTasks);
}
catch (Exception ex)
{
tbFileNames.AppendText(ex.Message + Environment.NewLine);
}
finally
{
tbFileNames.AppendText("Done" + Environment.NewLine);
}
It will raise a TaskCanceledException, but the operation will continue executing in the background.
Example download from here.
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 999
CREATE TABLE [dbo].[BigFiles]( [ID] [uniqueidentifier] NOT NULL, [Name] [nvarchar](255) NOT NULL, [Size] [bigint] NOT NULL, [Data] [image] NULL, CONSTRAINT [PK_File] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GOand I inserted some file approx big 700mb:
INSERT INTO [BigFiles] (ID, Name, Size, Data)
SELECT
NEWID(),
'bigFile.zip',
DATALENGTH(BulkColumn),
BulkColumn
FROM OPENROWSET(BULK N'bigFile.zip', SINGLE_BLOB) AS FileData;
Then I have created 32bit project in Visual Studio, where my csproj looks like this:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net9.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <PlatformTarget>x86</PlatformTarget> <Prefer32Bit>true</Prefer32Bit> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" /> </ItemGroup> </Project>Notice:
<PlatformTarget>x86</PlatformTarget> <Prefer32Bit>true</Prefer32Bit>Standard way with Ado.Net will not work:
using Microsoft.Data.SqlClient;
string connectionString = "Server=localhost;Database=saveBigData;User Id=myUserId;Password=myPass;TrustServerCertificate=True;Encrypt=False;";
using SqlConnection sqlConnection = new SqlConnection();
using SqlCommand sqlCommand = new SqlCommand();
sqlConnection.ConnectionString = connectionString;
sqlConnection.Open();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "SELECT * FROM [dbo].[BigFiles]";
sqlCommand.CommandTimeout = 0;
using SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
object[] values = new object[4];
sqlDataReader.GetValues(values);
}
In the line:
sqlDataReader.GetValues(values);will be System.OutOfMemoryException raised. Instead the one should use SequentialAccess:
string fileName = Path.Combine(AppContext.BaseDirectory, $"{Guid.NewGuid()}.bin");
using SqlConnection sqlConnection = new SqlConnection();
using SqlCommand sqlCommand = new SqlCommand();
sqlConnection.ConnectionString = connectionString;
sqlConnection.Open();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "SELECT * FROM [dbo].[BigFiles]";
sqlCommand.CommandTimeout = 0;
using SqlDataReader reader = sqlCommand.ExecuteReader(CommandBehavior.SequentialAccess);
while (reader.Read())
{
using Stream sqlStream = reader.GetStream(3);
using FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
byte[] buffer = new byte[81920];
int bytesRead;
while ((bytesRead = sqlStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, bytesRead);
}
}
Example download from here.