Ordnerstruktur aufgeräumt

This commit is contained in:
2025-10-22 11:35:49 +02:00
parent 61e4e3fff3
commit be86ad1604
78 changed files with 17 additions and 712 deletions

View File

@@ -57,10 +57,6 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AICore\AICore.csproj">
<Project>{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}</Project>
<Name>AICore</Name>
</ProjectReference>
<ProjectReference Include="..\Data\Data.csproj">
<Project>{B0D73E3D-4AE7-4024-93A6-DB1F46D7CCEE}</Project>
<Name>Data</Name>

View File

@@ -43,11 +43,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Translation", "Translation"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TranslationUnitTest", "TranslationUnitTest\TranslationUnitTest.csproj", "{83C43FEC-233D-49EF-BD23-BF842A3EBDF5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Features", "Features", "{830D2912-108B-4946-A3BE-CE4ECD50819F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AICore", "AICore\AICore.csproj", "{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerUtils", "ServiceUtils\ServerUtils.csproj", "{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Components", "Components", "{830D2912-108B-4946-A3BE-CE4ECD50819F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AI", "AI", "{084C391D-FCE1-4984-87FA-F8F9CFCC6A4F}"
EndProject
@@ -199,30 +195,6 @@ Global
{83C43FEC-233D-49EF-BD23-BF842A3EBDF5}.Release|Any CPU.Build.0 = Release|Any CPU
{83C43FEC-233D-49EF-BD23-BF842A3EBDF5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{83C43FEC-233D-49EF-BD23-BF842A3EBDF5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|.NET.ActiveCfg = Debug|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|.NET.Build.0 = Debug|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|.NET.ActiveCfg = Release|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|.NET.Build.0 = Release|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Any CPU.Build.0 = Release|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|.NET.ActiveCfg = Debug|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|.NET.Build.0 = Debug|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|.NET.ActiveCfg = Release|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|.NET.Build.0 = Release|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Any CPU.Build.0 = Release|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{68C1F8EA-7828-4E46-8F04-91105C55860E}.Debug|.NET.ActiveCfg = Debug|Any CPU
{68C1F8EA-7828-4E46-8F04-91105C55860E}.Debug|.NET.Build.0 = Debug|Any CPU
{68C1F8EA-7828-4E46-8F04-91105C55860E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -254,8 +226,6 @@ Global
{B331128C-7E9F-4BDC-B509-A8DAE1B94E5C} = {CCD6B644-49E7-4A11-BD8F-607088A4AC83}
{83C43FEC-233D-49EF-BD23-BF842A3EBDF5} = {B331128C-7E9F-4BDC-B509-A8DAE1B94E5C}
{830D2912-108B-4946-A3BE-CE4ECD50819F} = {FEB0336B-F053-40B6-92DD-7DE56AB9408A}
{69D70CA9-0DF9-419E-BFAF-F4539F129BD9} = {830D2912-108B-4946-A3BE-CE4ECD50819F}
{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57} = {FEB0336B-F053-40B6-92DD-7DE56AB9408A}
{084C391D-FCE1-4984-87FA-F8F9CFCC6A4F} = {CCD6B644-49E7-4A11-BD8F-607088A4AC83}
{68C1F8EA-7828-4E46-8F04-91105C55860E} = {084C391D-FCE1-4984-87FA-F8F9CFCC6A4F}
EndGlobalSection

View File

@@ -541,7 +541,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Dakota\Dakota.csproj">
<Project>{47331732-DD96-4075-869F-83AA9F3F9937}</Project>
<Project>{47331732-dd96-4075-869f-83aa9f3f9937}</Project>
<Name>Dakota</Name>
</ProjectReference>
<ProjectReference Include="..\Data\Data.csproj">

View File

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BeWo.Server.ApiFacade</RootNamespace>
<AssemblyName>BeWo.Server.ApiFacade</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Core\HttpClientFacade.cs" />
<Compile Include="Core\JsonHttpClientFacade.cs" />
<Compile Include="Core\WebClientFacade.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Shared\Shared.csproj">
<Project>{2F50B83D-A3F0-4EC4-979A-3F9B7E3D8ED4}</Project>
<Name>Shared</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="README.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,231 +0,0 @@
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Exceptions;
using BS.Shared.Interface;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace BeWo.Server.ApiFacade.Core
{
public class HttpClientFacade
{
public HttpClientFacade(string base_url, string api_key, bool directConntect = true)
{
if (string.IsNullOrEmpty(base_url))
throw new ArgumentNullException("HttpClient: base_url is missing");
if (string.IsNullOrWhiteSpace(api_key))
throw new ArgumentNullException("HttpClient: token is missing");
Base_Url = base_url;
SetToken(api_key);
DirectConnect = directConntect;
}
public bool DirectConnect { get; private set; }
public string Base_Url { get; private set; }
public HttpMethod Method { get; set; } = HttpMethod.Get;
public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
public Dictionary<string, string> Parameters { get; set; } = new Dictionary<string, string>();
public string ContentType { get; set; } = "application/x-www-form-urlencoded";
public Encoding Encoding { get; set; } = Encoding.UTF8;
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
/// <summary>
/// Führt einen Request aus, erwartet einen komplexen Datentyp: Schaue Verweise für Beispiele.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="method"></param>
/// <param name="anonymousType"></param>
/// <param name="extractor"></param>
/// <returns></returns>
public virtual async Task<ApiResponse<T>> GetAnonymousTypeAsync<T>(string method, T anonymousType, IApiErrorExtractor extractor)
{
var http_response = await getResponseAsync(method).ConfigureAwait(false);
if (!http_response.IsSuccessStatusCode)
{
return ApiResponse<T>.FailureResponse(AppError.ApiResponseFailed, http_response.ReasonPhrase, (int)http_response.StatusCode);
}
var json = await http_response.Content.ReadAsStringAsync().ConfigureAwait(false);
return parse(() => JsonConvert.DeserializeAnonymousType<T>(json, anonymousType), json, extractor);
}
/// <summary>
/// Führt einen Request aus, erwartet einen einfachen Datentyp wie: string, int, decimal, byte[] -
/// Liste kann gerne erweitert werden
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="method"></param>
/// <param name="extractor"></param>
/// <returns></returns>
/// <exception cref="BeWoInvalidOperationException"></exception>
public virtual async Task<ApiResponse<T>> GetAsync<T>(string method, IApiErrorExtractor extractor)
{
var http_response = await getResponseAsync(method).ConfigureAwait(false);
if (!http_response.IsSuccessStatusCode)
{
return ApiResponse<T>.FailureResponse(AppError.ApiResponseFailed, http_response.ReasonPhrase, (int)http_response.StatusCode);
}
var content = await http_response.Content.ReadAsStringAsync().ConfigureAwait(false);
object result;
var type = typeof(T);
if (type == typeof(string))
{
result = content;
}
else if (type == typeof(int))
{
result = int.Parse(content);
}
else if (type == typeof(decimal))
{
result = decimal.Parse(content);
}
else if (type == typeof(byte[]))
{
result = await http_response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
}
else
{
throw new BeWoInvalidOperationException(AppError.UnsupportedType(typeof(T)));
}
return parse(() => (T)result, content, extractor);
}
private static bool ServerCertificateCustomValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslErrors)
{
// It is possible to inspect the certificate provided by the server.
Console.WriteLine($"Requested URI: {requestMessage.RequestUri}");
Console.WriteLine($"Effective date: {certificate?.GetEffectiveDateString()}");
Console.WriteLine($"Exp date: {certificate?.GetExpirationDateString()}");
Console.WriteLine($"Issuer: {certificate?.Issuer}");
Console.WriteLine($"Subject: {certificate?.Subject}");
// Based on the custom logic it is possible to decide whether the client considers certificate valid or not
Console.WriteLine($"Errors: {sslErrors}");
return sslErrors == SslPolicyErrors.None;
}
private protected virtual async Task<HttpResponseMessage> getResponseAsync(string method)
{
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = ServerCertificateCustomValidation,
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls,
};
using (var client = new HttpClient(handler) { Timeout = Timeout })
{
var requestUri = BS.Shared.Core.Utilities.WebUtils.CombineUrl(Base_Url, method);
if (Method == HttpMethod.Get && Parameters.Count > 0)
{
var query = string.Join("&", Parameters.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}"));
requestUri += (Base_Url.Contains("?") ? "&" : "?") + query;
}
using (var request = new HttpRequestMessage(Method, requestUri))
{
await checkForDirect(request).ConfigureAwait(false);
// Add headers
foreach (var header in Headers)
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
// Add body if POST or PUT
if (Method == HttpMethod.Post || Method == HttpMethod.Put)
{
var content = new FormUrlEncodedContent(Parameters);
var bytes = await content.ReadAsByteArrayAsync().ConfigureAwait(false);
request.Content = new ByteArrayContent(bytes);
request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType);
}
return await client.SendAsync(request).ConfigureAwait(false);
}
}
}
private protected async Task checkForDirect(HttpRequestMessage request)
{
if (!DirectConnect || request.RequestUri is null)
return;
var host = request.RequestUri.DnsSafeHost;
var isSslSession = request.RequestUri.ToString().StartsWith("https://");
try
{
// DNS-Auflösung für den Hostnamen durchführen
var ipAddresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false);
// Erste verfügbare IP-Adresse verwenden (IPv4 bevorzugen)
var targetIp = ipAddresses.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork)
?? ipAddresses.FirstOrDefault();
if (targetIp != null)
{
request.RequestUri = new Uri($"{(isSslSession ? "https://" : "http://")}{targetIp}{request.RequestUri.PathAndQuery}");
request.Headers.Host = host;
}
}
catch (Exception ex)
{
// Fallback: Original URI beibehalten bei DNS-Fehlern
// Optional: Logging des Fehlers
Console.WriteLine($"DNS resolution failed for {host}: {ex.Message}");
}
}
private void SetToken(string api_key)
{
var key = nameof(HttpRequestHeader.Authorization);
var token = $"Bearer {api_key}";
if (Headers.ContainsKey(key))
{
Headers[key] = token;
}
else
{
Headers.Add(key, token);
}
}
private ApiResponse<T> parse<T>(Func<T> func, string json, IApiErrorExtractor errorExtractor)
{
try
{
// Versuch, die erwartete Struktur zu deserialisieren
var data = func();
return ApiResponse<T>.SuccessResponse(data);
}
catch (JsonException)
{
// Falls normale Deserialisierung fehlschlägt, versuche Fehler zu extrahieren
return ApiResponse<T>.FailureResponse(AppError.JsonParsingError, errorExtractor.ExtractError(json).ToList());
}
}
}
}

View File

@@ -1,48 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
namespace BeWo.Server.ApiFacade.Core
{
public class JsonHttpClientFacade : HttpClientFacade
{
public object JsonObject { get; set; }
public JsonHttpClientFacade(string base_url, string api_key, bool directConnect = true) : base(base_url, api_key, directConnect)
{
ContentType = "application/json";
Method = HttpMethod.Post;
}
private protected override async Task<HttpResponseMessage> getResponseAsync(string method)
{
using (var client = new HttpClient { Timeout = Timeout })
{
var requestUri = BS.Shared.Core.Utilities.WebUtils.CombineUrl(Base_Url, method);
using (var request = new HttpRequestMessage(Method, requestUri))
{
await checkForDirect(request).ConfigureAwait(false);
// Add headers
foreach (var header in Headers)
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
// Add body if POST or PUT
if (Method == HttpMethod.Post || Method == HttpMethod.Put)
{
var json = JsonConvert.SerializeObject(JsonObject);
request.Content = new StringContent(json, Encoding, "application/json");
}
return await client.SendAsync(request).ConfigureAwait(false);
}
}
}
}
}

View File

@@ -1,268 +0,0 @@
using BS.Shared.Extensions;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
namespace BeWo.Server.ApiFacade.Core
{
public class WebClientFacade
{
//
// GET
//
protected TRes SendGet<TRes>(string sub_url, string token = null)
=> Get<TRes>(sub_url, token);
protected Task<TRes> SendGetAsync<TRes>(string sub_url, string token = null)
=> GetAsync<TRes>(sub_url, token);
//
// POST
//
protected TRes SendPostUploadString<TReq, TRes>(string sub_url, TReq req, string token = null)
=> SendUploadString<TReq, TRes>(sub_url, "POST", req, token);
protected TRes SendPostUploadValues<TReq, TRes>(string sub_url, TReq req, string token = null)
=> SendUploadValues<TReq, TRes>(sub_url, "POST", req, token);
protected byte[] SendPostUploadValuesRaw<TReq>(string sub_url, TReq req, string token = null)
=> SendUploadValuesRaw(sub_url, "POST", req, token);
protected Task<TRes> SendPostUploadStringAsync<TReq, TRes>(string sub_url, TReq req, string token = null)
=> SendUploadStringAsync<TReq, TRes>(sub_url, "POST", req, token);
protected Task<TRes> SendPostUploadValuesAsync<TReq, TRes>(string sub_url, TReq req, string token = null)
=> SendUploadValuesAsync<TReq, TRes>(sub_url, "POST", req, token);
protected Task<byte[]> SendPostUploadValuesAsyncRaw<TReq, TRes>(string sub_url, TReq req, string token = null)
=> SendUploadValuesRawAsync<TReq, TRes>(sub_url, "POST", req, token);
#region private
//
// Requests
//
private TRes Get<TRes>(string sub_url, string token = null)
{
var url = getUrl(sub_url);
string response = Get(url, token);
return deserialize<TRes>(response);
}
private TRes SendUploadString<TReq, TRes>(string sub_url, string method, TReq req, string token = null)
{
var data = serializeJson(req);
var url = getUrl(sub_url);
string response = SendUploadString<TRes>(url, method, data, token);
return deserialize<TRes>(response);
}
private TRes SendUploadValues<TReq, TRes>(string sub_url, string method, TReq req, string token = null)
{
var data = serialize(req);
var url = getUrl(sub_url);
string response = SendUploadValues(url, method, data, token);
return deserialize<TRes>(response);
}
private byte[] SendUploadValuesRaw<TReq>(string sub_url, string method, TReq req, string token = null)
{
var data = serialize(req);
var url = getUrl(sub_url);
var response = SendUploadValuesRaww(url, method, data, token);
return response;
}
private async Task<TRes> GetAsync<TRes>(string sub_url, string token = null)
{
var url = getUrl(sub_url);
string response = await GetAsync(url, token);
return deserialize<TRes>(response);
}
private async Task<TRes> SendUploadStringAsync<TReq, TRes>(string sub_url, string method, TReq req, string token = null)
{
var data = serializeJson(req);
var url = getUrl(sub_url);
string response = await SendUploadStringAsync<TRes>(url, method, data, token);
return deserialize<TRes>(response);
}
private async Task<TRes> SendUploadValuesAsync<TReq, TRes>(string sub_url, string method, TReq req, string token = null)
{
var data = serialize(req);
var url = getUrl(sub_url);
string response = await SendUploadValuesAsync(url, method, data, token);
return deserialize<TRes>(response);
}
private async Task<byte[]> SendUploadValuesRawAsync<TReq, TRes>(string sub_url, string method, TReq req, string token = null)
{
var data = serialize(req);
var url = getUrl(sub_url);
var response = await SendUploadValuesRawAsync(url, method, data, token);
return response;
}
//
// String
//
private string Get(string url, string token = null)
=> exec(true, client => client.DownloadString(url), token);
private string SendUploadString<T>(string url, string method, string request, string token = null)
=> exec(false, client => client.UploadString(url, method, request), token);
private string SendUploadValues<T>(string url, string method, T request, string token = null)
=> exec(false, client => Encoding.UTF8.GetString(client.UploadValues(url, method, request?.ToNameValueCollection())), token);
private byte[] SendUploadValuesRaww<T>(string url, string method, T request, string token = null)
=> execraw(false, client => client.UploadValues(url, method, request?.ToNameValueCollection()), token);
private Task<string> GetAsync(string url, string token = null)
=> execasync(true, client => client.DownloadStringTaskAsync(url), token);
private Task<string> SendUploadStringAsync<T>(string url, string method, string request, string token = null)
=> execasync(false, client => client.UploadStringTaskAsync(url, method, request), token);
private Task<string> SendUploadValuesAsync<T>(string url, string method, T request, string token = null)
=> execasync(false, async client => Encoding.UTF8.GetString(await client.UploadValuesTaskAsync(url, method, request?.ToNameValueCollection()).ConfigureAwait(false)), token);
private Task<byte[]> SendUploadValuesRawAsync<T>(string url, string method, T request, string token = null)
=> execasyncraw(false, async client => await client.UploadValuesTaskAsync(url, method, request?.ToNameValueCollection()).ConfigureAwait(false), token);
//
// Base
//
private string exec(bool override_header, Func<WebClient, string> action, string token = null)
{
string response;
using (WebClient client = new WebClient())
{
//client.Encoding = Encoding.Default;
client.Encoding = Encoding.UTF8;
if (override_header)
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
if (token != null)
client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token);
response = action(client);
}
return response;
}
private byte[] execraw(bool override_header, Func<WebClient, byte[]> action, string token = null)
{
byte[] response;
using (WebClient client = new WebClient())
{
//client.Encoding = Encoding.Default;
client.Encoding = Encoding.UTF8;
if (override_header)
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
if (token != null)
client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token);
response = action(client);
}
return response;
}
private async Task<string> execasync(bool override_header, Func<WebClient, Task<string>> action, string token = null)
{
string response;
using (WebClient client = new WebClient())
{
//client.Encoding = Encoding.Default;
client.Encoding = Encoding.UTF8;
if (override_header)
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
if (token != null)
client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token);
response = await action(client);
}
return response;
}
private async Task<byte[]> execasyncraw(bool override_header, Func<WebClient, Task<byte[]>> action, string token = null)
{
byte[] response;
using (WebClient client = new WebClient())
{
//client.Encoding = Encoding.Default;
client.Encoding = Encoding.UTF8;
if (override_header)
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
if (token != null)
client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token);
response = await action(client);
}
return response;
}
private T deserialize<T>(string input)
{
if (string.IsNullOrEmpty(input))
return default;
if (typeof(T) == typeof(string))
return (T)(object)input;
if (typeof(T) == typeof(byte[]))
return (T)(object)Encoding.UTF8.GetBytes(input);
var t = JsonConvert.DeserializeObject<T>(input);
return t;
}
private IDictionary<string, string> serialize<T>(T input)
{
return input?.ToKeyValue();
}
private string serializeJson<T>(T input)
{
if (typeof(T) == typeof(string))
return input as string;
var t = JsonConvert.SerializeObject(input);
return t;
}
#endregion
protected virtual string getKey()
{
return null;
}
protected virtual string getUrl()
{
return null;
}
private string getUrl(string sub_url)
{
var root = getUrl();
var baseUri = new Uri(root);
var uri = new Uri(baseUri, sub_url);
var url = uri.ToString();
return url;
}
}
}

View File

@@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("ClassLibrary1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ClassLibrary1")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("4b2f3959-3cda-4514-83a2-fa3c24e57bb7")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,23 +0,0 @@
Betreff: Projektübersicht: API-Kommunikations-Facade
Hallo zusammen! Dies ist eine kleine Info über das Projekt.
Ich habe mir dieses Projekt auf der selben Ebenen wie Data gedacht.
Data: ist ein Projekt, was speziell für die Datenbank Logik dient.
ApiFacade: soll im Gegenzug ein Projekt darstellen, was rein für die API Kommunikation gedacht ist.
Aktuell beinhaltet es die basischen Klassen HttpClientFacade und JsonHttpClientFacade.
WebClientFacade wird nicht benutzt.
HttpClientFacade stellt eine Facade für einen Api Endpunkt bereit, welche mit GET angesporchen werden.
Parameter werden dabei in der Query übergeben, der Body bleibt unberüht!
JsonClientFacade stellt eine Facade für Api Endpunkte bereit, welche mit POST angesprochen werden.
Es wäre hier definitiv eine Überlegung wert, ob man die konkreten Implentiereungen nicht doch auch hier vornimmt,
sauber getrennt durch Ordner.
Das wäre auch nicht so schlecht, weil Data als Idee auch abgeschlossen für die DB Interaktionen dient.
Ich behalte das mal im Hinterkopf, es würde wenn den gesamten Ordner Server/Features/AICore/Facade betreffen.
Danke fürs lesen :)

View File

@@ -8,7 +8,7 @@
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AICore</RootNamespace>
<AssemblyName>BeWo.Features.AICore</AssemblyName>
<AssemblyName>BeWo.Components.AICore</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
@@ -115,11 +115,7 @@
<EmbeddedResource Include="Prompt\SystemPrompts\system_prompt3.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ServiceUtils\ServerUtils.csproj">
<Project>{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}</Project>
<Name>ServerUtils</Name>
</ProjectReference>
<ProjectReference Include="..\Shared\Shared.csproj">
<ProjectReference Include="..\..\..\Shared\Shared.csproj">
<Project>{2f50b83d-a3f0-4ec4-979a-3f9b7e3d8ed4}</Project>
<Name>Shared</Name>
</ProjectReference>

View File

@@ -0,0 +1,10 @@
Projekte der Component haben die Idee, dass sie nur Shared referenzieren.
Component sind etwa das Shared für Server.
Vorteil:
- Component können von jedem Server Projekt verwendet werden
- Component bietet Basis Funktionalitäten (ConfigReader, ApiRequests)
FAQ:
Wieso nicht in Shared?
Components können Server Version haben (4.7.2) und sind nicht vom Client limitiert.

View File

@@ -7,8 +7,8 @@
<ProjectGuid>{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BeWo.ServiceUtils</RootNamespace>
<AssemblyName>BeWo.ServiceUtils</AssemblyName>
<RootNamespace>BeWo.ServerUtils</RootNamespace>
<AssemblyName>BeWo.Components.ServerUtils</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
@@ -51,7 +51,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj">
<ProjectReference Include="..\..\..\Shared\Shared.csproj">
<Project>{2f50b83d-a3f0-4ec4-979a-3f9b7e3d8ed4}</Project>
<Name>Shared</Name>
</ProjectReference>

View File

@@ -577,10 +577,6 @@
<Compile Include="XAMLInformation\InfoViaXAMLManager.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AICore\AICore.csproj">
<Project>{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}</Project>
<Name>AICore</Name>
</ProjectReference>
<ProjectReference Include="..\Dakota\Dakota.csproj">
<Project>{47331732-dd96-4075-869f-83aa9f3f9937}</Project>
<Name>Dakota</Name>