Laden...

Forenbeiträge von TomSchmitz Ingesamt 22 Beiträge

02.10.2024 - 19:08 Uhr

Ich habe das Prerendering einfach in der App.razor deaktiviert. Zwar keine sehr schöne, aber funktionale Lösung.

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <base href="/" />  
   <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
   <link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />  
   <link rel="icon" type="image/ico" href="favicon.ico" />
   <HeadOutlet @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
</head>
<body>
   <Routes @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
   <script>process = undefined;</script> <!-- https://github.com/ElectronNET/Electron.NET/issues/823 -->
   <script src="_framework/blazor.web.js"></script>
   <script src="_content/MudBlazor/MudBlazor.min.js"></script>
</body>
</html>
02.10.2024 - 18:44 Uhr

Moin Moin,

ich habe einen CustomAuthStateProvider und einen LocalStorageService. Ich verwende zudem Electron.NET, falls das wichtig zu wissen ist.

App.razor:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <base href="/" />  
   <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
   <link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />  
   <link rel="icon" type="image/ico" href="favicon.ico" />
   <HeadOutlet @rendermode="InteractiveServer" />
</head>
<body>
   <Routes @rendermode="InteractiveServer" />
   <script>process = undefined;</script> <!-- https://github.com/ElectronNET/Electron.NET/issues/823 -->
   <script src="_framework/blazor.web.js"></script>
   <script src="_content/MudBlazor/MudBlazor.min.js"></script>
</body>
</html>

Routes.razor:

<Router AppAssembly="@typeof(Program).Assembly">
   <Found Context="routeData">
       <AuthorizeRouteView RouteData="@routeData" DefaultLayout="typeof(Layout.MainLayout)">
           <NotAuthorized>
               <Redirect To="/login" />
           </NotAuthorized>
       </AuthorizeRouteView>
       <FocusOnNavigate RouteData="routeData" Selector="h1" />
   </Found>
   <NotFound>
       <LayoutView Layout="typeof(Layout.MainLayout)">
           <p>Sorry, there's nothing at this address.</p>
       </LayoutView>
   </NotFound>
</Router>

CustomAuthStateProvider:

public class CustomAuthStateProvider : AuthenticationStateProvider
{
   private readonly LocalStorageService _localStorageService;
   public CustomAuthStateProvider(LocalStorageService localStorageService, HttpClient http)
   {
       _localStorageService = localStorageService;
   }
   public override async Task<AuthenticationState> GetAuthenticationStateAsync()
   {
       string accessToken = await _localStorageService.GetValueAsyncOrDefault<string>("accessToken");
       var identity = new ClaimsIdentity();
       if (!string.IsNullOrEmpty(accessToken))
       {
           identity = new ClaimsIdentity(ParseClaimsFromJwt(accessToken), "jwt");
           var claims = ParseClaimsFromJwt(accessToken);
           foreach (var claim in claims)
           {
               if (claim.Type == ClaimTypes.Role)
               {
                   try
                   {
                       var rolesArray = JsonSerializer.Deserialize<List<string>>(claim.Value);
                       foreach (var role in rolesArray)
                       {
                           identity.AddClaim(new Claim(ClaimTypes.Role, role));
                       }
                   }
                   catch (JsonException)
                   {
                   }
               }
           }
       }
       var user = new ClaimsPrincipal(identity);
       var state = new AuthenticationState(user);
       NotifyAuthenticationStateChanged(Task.FromResult(state));
       return state;
   }
   public static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
   {
       var payload = jwt.Split('.')[1];
       var jsonBytes = ParseBase64WithoutPadding(payload);
       var keyValuePairs = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonBytes);
       return keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString()));
   }
   private static byte[] ParseBase64WithoutPadding(string base64)
   {
       switch (base64.Length % 4)
       {
           case 2: base64 += "=="; break;
           case 3: base64 += "="; break;
       }
       return Convert.FromBase64String(base64);
   }
}

LocalStorageService:

public class LocalStorageService
{
   private readonly ILocalStorageService _localStorage;
   public LocalStorageService(ILocalStorageService localStorage)
   {
       _localStorage = localStorage;
   }
   public async Task SetValueAsync<T>(string key, T value, TimeSpan? expiration = null)
   {
       var item = new LocalStorageItem<T>
       {
           Value = value,
           Expiration = expiration.HasValue ? DateTime.UtcNow.Add(expiration.Value) : DateTime.MaxValue
       };
       await _localStorage.SetItemAsync(key, item);
   }
   public async Task<T> GetValueAsync<T>(string key)
   {
       var item = await _localStorage.GetItemAsync<LocalStorageItem<T>>(key);
       if (item == null || item.IsExpired)
       {
           await RemoveValueAsync(key);
           throw new LocalStorageItemExpiredException();
       }
       return item.Value;
   }
   public async Task<T> GetValueAsyncOrDefault<T>(string key)
   {
       var item = await _localStorage.GetItemAsync<LocalStorageItem<T>>(key);
       if (item == null || item.IsExpired)
       {
           await RemoveValueAsync(key);
           return default;
       }
       return item.Value;
   }
   public async Task<bool> HasKeyAsync(string key)
   {
       var item = await _localStorage.GetItemAsync<LocalStorageItem<object>>(key);
       return item != null && !item.IsExpired;
   }
   public async Task UpdateValueAsync<T>(string key, T value, TimeSpan? expiration = null)
   {
       await SetValueAsync(key, value, expiration);
   }
   public async Task RemoveValueAsync(string key)
   {
       await _localStorage.RemoveItemAsync(key);
   }
   public async Task ClearAsync()
   {
       await _localStorage.ClearAsync();
   }
}

Das Problem ist konkret folgendes:
JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendered. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.

Sprich, ich kann den LocalStorage in der Prerendering-Phase nicht verwenden. Ich habe dazu bisher nur blöde Workarounds gefunden. Gibt es da nicht eine recht einfache Möglichkeit?

Oder habe ich einfach nur was falsch konfiguriert? Ich habe den Auth-State-Provider natürlich richtig registriert.

Danke im Voraus für jede Hilfe!

06.05.2024 - 08:16 Uhr

Ich habe die Lösung.

Ich konnte manuell das Enum erweitern.

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; // TLS 1.2

jetzt funktioniert es.

06.05.2024 - 07:55 Uhr

Moin Moin,

ich habe folgenden Code:

public static void HandleRequest(HttpListenerContext context)
{
   ServiceResponse response = new ServiceResponse();
   try
   {
       OpenProfileArticleDto openProfileArticleDto = JsonHelper.DeserializeFromStream<OpenProfileArticleDto>(context.Request.InputStream);
       if (openProfileArticleDto == null || string.IsNullOrEmpty(openProfileArticleDto.ArticleId))
       {
           throw new Exception("Invalid request data");
       }
       string baseUrl = "https://localhost:8099/api/profile";
       string url = $"{baseUrl}/get-partid-from-articleId?articleId={openProfileArticleDto.ArticleId}";                                
       HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
       request.Method = "GET";
       request.AllowWriteStreamBuffering = true;
       request.Timeout = 10000;
       request.AllowAutoRedirect = true;
       ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
       using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
       {
           if (webResponse.StatusCode == HttpStatusCode.OK)
           {
               using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
               {
                   string result = reader.ReadToEnd();
                   Console.WriteLine("Part ID received: " + result);
                   var partId = int.Parse(result);
                   if (partId > 0)
                   {
                       new Thread(() =>
                       {
                           try
                           {
                               System.Diagnostics.Process.Start($"....");
                           }
                           catch (Exception ex)
                           {
                               Logger.Log($"Error opening link: {ex.Message}", Logger.LogPriority.Error);
                           }
                       })
                       { IsBackground = true }.Start();
                       response = new ServiceResponse<int> { StatusCode = 200, Message = "Wird gestartet..." };
                   }
               }
           }
           else
           {
               throw new Exception("Error getting part ID");
           }
       }
   }
   catch (Exception ex)
   {
       Logger.Log(ex.Message, Logger.LogPriority.Error);
       response = ErrorHandler.ThrowErrorAsync(500);
   }
   finally
   {
       SendResponse(context, response);
   }
}

Ich bekomme die Fehlermeldung: ex = {"Die zugrunde liegende Verbindung wurde geschlossen: Unerwarteter Fehler beim Senden.."}
Er fliegt bei "using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))"

In der Inner-Exception habe ich folgenden Stack-Trace:

bei System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
bei System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
bei System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
bei System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
bei System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
bei System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
bei System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
bei System.Net.TlsStream.CallProcessAuthentication(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
bei System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
bei System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
bei System.Net.ConnectStream.WriteHeaders(Boolean async)

Das Zertifikat funktioniert so weit. Mit Postman habe ich diesen Endpunkt auch soweit richtig getestet. Er funktioniert also.

Der REST-API-Endpunkt in .NET 7 sieht so aus:


       [HttpGet("get-partid-from-articleId")]
       public async Task<ActionResult<ServiceResponse<int>>> GetPartIdFromArticleId(string articleId)
       {
           return await ServiceResponseProcessor.ProcessServiceResponse(this, await _profileService.GetPartId(articleId));
       }

Ich habe mal testweise google.com über meinen oben dargestellten Code angefragt. Ich habe ganz normal einen 200er bekommen.

Woran könnte das liegen, dass der Request in Postman, aber nicht hier oben im Code funktioniert?

Kann es eventuell daran liegen, dass die TLS-Version von dem HttpClient aus dem .NET Framework 3.5 nicht mehr mit den aktuellen kompatibel ist? Ich habe nämlich nur die Wahl zwischen Tls und Ssl3

LG

18.03.2024 - 11:40 Uhr

Oh, wunderbar! Im Grunde genau das, was ich brauche! Danke Dir!

18.03.2024 - 11:23 Uhr

Ich versuche im Moment ein Workflow-System in C# umzusetzen.

Ich habe Module. Diese Module haben folgende Eigenschaften:

  • Inputs (können mehrere sein)
  • Outputs (können an mehrere gehen)
  • Methode zum Auswerten des Inputs.

Diese Auswertung wird dann als Output zurückgegeben.

Die Besonderheit ist, dass man diese Module verknüpfen kann.

Also sagen wir mal, wir haben Modul A, B, C und D. Dabei ist A das erste Modul im Workflow und hat 1x Input Quelle und nimmt eine Zahlenfolge als Input, die addiert wird und gibt diese an ihren Output.

Der Output von A soll nun an B und C gehen. Diese nehmen jeweils 1x Input. Dabei gibt B seinen Input dividiert durch 2 an seinen Output weiter und C gibt seinen Input multipliziert mit 2 an seinen Output weiter.

D nimmt dabei zwei Inputs. B und C.

D ist das letzte, also das entgültige Output Modul und gibt sein Ergebnis zurück.

Dabei muss natürlich beachtet werden, dass jedes Modul auf all seine Inputs wartet. Alle Module sollen parallel ausgeführt werden.

Sehr wichtig ist, dass jedes Modul außerdem andere Datentypen annehmen kann. Also man soll bei jedem Modul frei entscheiden können, welchen Typen man als Input und Output nimmt. Außerdem müssen Input und Output Typen übereinstimmen, wenn man Module miteinander verknüpfen möchte. Die Methode zum Auswerten soll immer einen return Wert haben, der dann als Output des Moduls gezählt wird.

Ich habe das im Anhang mal grafisch dargestellt.

Ich komme da einfach nicht weiter. Hat da eventuell wer einen Code-Ansatz oder sonstiges?

18.12.2023 - 16:21 Uhr

Also ich habe jetzt schon viel rausbekommen. Aber diese Auth-Provider...

07.12.2023 - 19:01 Uhr

Moin T-Virus.

Ich meine die Integration ein Projekt, was du bekommst, wenn du die Blazor Web-App Vorlage verwendest und als interactive render mode "Auto" wählst.

Ich kann dir mein Problem auch nur schwerlich mit Code erklären, da es so gesehen keinen fehlerhaften Code gibt und das Projekt schlichtweg zu groß ist, um es hier mal eben zu posten.

Wenn du dir mal ein Blazor WASM-Projekt anschaust (.NET 7) siehst du, dass es anders von der Struktur ist.

Ich war jetzt einfach von der neuen Struktur verwundert.

Sprich, gehört der Auth-State-Provider nun in das Client-Projekt, der Blazor Web App, oder in das "Base"-Project?

Zudem ist die App.razor aus .NET 7 auf einmal zu einer Routes.razor geworden, wo auch wieder vieles verschieden ist. Ich finde z.B. die CascadingAuthenticationState nicht mehr.

07.12.2023 - 17:49 Uhr

Naja, wie gesagt.. Ich weiß nicht, wie ich den AuthStateProvider richtig in .NET 8 "Auto" einbinden soll.

Ich finde die Grenzen zwischen Blazor Server und Blazor WASM in der Blazor Web App (.NET 8) etwas komisch. Ich finde mich da noch nicht so zurecht.

Jedenfalls bräuchte ich ggf. eine Anleitung aus dem Internet oder so, wo beschrieben wird, wie man ein Auth-System (nicht Identity) in Blazor .NET 8 "Auto" umsetzt. Ich denke das würde am meisten helfen.

Ich möchte auch nur migrieren, weil ich von SSR profitieren möchte.

06.12.2023 - 14:24 Uhr

Hallo zusammen,

ich habe vor etwa einem halben Jahr ein Projekt mit ASP .NET Core Web API und Blazor WASM .NET 7 begonnen.

Nun ist .NET 8 erschienen und es scheinen sich einige Dinge verändert zu haben.

Zu diesen Dingen gehört offensichtlich auch der AuthenticationStateProvider.

Aktuell läuft mein ganzes Frontend-Auth System über diesen und Librarys, wie BlazoredLocalStorage.

Mir gelingt es einfach nicht mein aktuelles Projekt zu migrieren. 
Kennt eventuell jemand einen Beitrag, der dieses Problem angeht, oder kann mir anderweitig Tipps geben?

Hier sind ein paar Schnipsel, die Zeigen, wie mein aktuelles Projekt aufgebaut ist.


        public static async Task Main(string[] args)
       {
           var builder = WebAssemblyHostBuilder.CreateDefault(args);
           builder.RootComponents.Add<App>("#app");
           builder.RootComponents.Add<HeadOutlet>("head::after");
           builder.Services.AddBlazoredLocalStorage();
           //builder.Services.AddScoped<HttpClient>((_) => new HttpClient() { BaseAddress = new Uri("https://localhost:7266/") });
           builder.Services.AddHttpClient("Default", (x) => x.BaseAddress = new Uri("https://localhost:7266/"));
           builder.Services.AddScoped<TokenService>(); // Ändern Sie die Registrierung zu AddScoped
           builder.Services.AddTransient<AuthHandler>(); // AuthHandler als Transient Service registrieren
           builder.Services.AddHttpClient("AuthClient", (httpClient) =>
           {
               httpClient.BaseAddress = new Uri("https://localhost:7266/");
           })
           .ConfigurePrimaryHttpMessageHandler((services) =>
           {
               return services.GetRequiredService<AuthHandler>();
           });
           builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
           builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
           builder.Services.AddAuthorizationCore();
           builder.Services.AddScoped<IAdminService, AdminService>();
           builder.Services.AddScoped<IAuthService, AuthService>();
           builder.Services.AddScoped<IUserProfileService, UserProfileService>();
           builder.Services.AddScoped<ILearningPathService, LearningPathService>();
           builder.Services.AddScoped<ICreationToolService, CreationToolService> ();
           builder.Services.AddScoped<LocalStorageService>();
           await builder.Build().RunAsync();
       }
public class CustomAuthStateProvider : AuthenticationStateProvider
{
   private readonly ILocalStorageService _localStorage;
   public CustomAuthStateProvider(ILocalStorageService localStorage, HttpClient http)
   {
       _localStorage = localStorage;
   }
   public override async Task<AuthenticationState> GetAuthenticationStateAsync()
   {
       string accessToken = await _localStorage.GetItemAsStringAsync("accessToken");
       var identity = new ClaimsIdentity();
       if (!string.IsNullOrEmpty(accessToken) && accessToken != "\"\"")
       {
           identity = new ClaimsIdentity(ParseClaimsFromJwt(accessToken), "jwt");
           var claims = ParseClaimsFromJwt(accessToken);
           foreach (var claim in claims)
           {
               if (claim.Type == ClaimTypes.Role)
               {
                   // Extrahiere Rollen aus dem JSON-Array im "Value" des Anspruchs
                   try
                   {
                       var rolesArray = JsonSerializer.Deserialize<List<string>>(claim.Value);
                       foreach (var role in rolesArray)
                       {
                           identity.AddClaim(new Claim(ClaimTypes.Role, role));
                       }
                   }
                   catch (JsonException)
                   {
                       // Fehler beim Deserialisieren des JSON-Arrays behandeln, falls erforderlich
                       // Hier können Sie geeignete Fehlerbehandlung durchführen oder die Rolle ignorieren
                   }
               }
           }
       }
       var user = new ClaimsPrincipal(identity);
       var state = new AuthenticationState(user);
       NotifyAuthenticationStateChanged(Task.FromResult(state));
       return state;
   }
   public static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
   {
       var payload = jwt.Split('.')[1];
       var jsonBytes = ParseBase64WithoutPadding(payload);
       var keyValuePairs = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonBytes);
       return keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString()));
   }
   private static byte[] ParseBase64WithoutPadding(string base64)
   {
       switch (base64.Length % 4)
       {
           case 2: base64 += "=="; break;
           case 3: base64 += "="; break;
       }
       return Convert.FromBase64String(base64);
   }
}
<CascadingAuthenticationState>
   <Router AppAssembly="@typeof(App).Assembly">
       <Found Context="routeData">
           <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
               <NotAuthorized>
                   @if (!context.User.Identity.IsAuthenticated)
                   {
                       <Redirect To="login"/>
                   }
                   else
                   {
                       <Redirect To="unauthorized" />
                   }
               </NotAuthorized>
           </AuthorizeRouteView>
           <FocusOnNavigate RouteData="@routeData" Selector="h1" />
       </Found>
       <NotFound>
           <PageTitle>Not found</PageTitle>
           <LayoutView Layout="@typeof(MainLayout)">
               <p role="alert">Sorry, there's nothing at this address.</p>
           </LayoutView>
       </NotFound>
   </Router>
</CascadingAuthenticationState>

Ansonsten verwende ich eben noch Tokenspeicherung via BlazoredLocalStorage. Aber ich denke der oben gezeigte Code, sollte für mein Problem am relevantesten sein.

Danke im voraus!

20.11.2023 - 12:12 Uhr

Ich habe zuerst selber über Berechnungen im Bild die Header-Elemente manuell gesetzt.

Glücklicherweise gibt es aber auch die Library: iTextSharp.text.pdf

private static bool CombinePDFs(string srcPath, string pdfToCombinePath, string pathToSave)
{
   try
   {
       PdfReader reader = new PdfReader(srcPath);
       PdfReader sReader = new PdfReader(pdfToCombinePath);
       PdfStamper stamper = new PdfStamper(reader, new FileStream(pathToSave, FileMode.Create));
       PdfImportedPage page = stamper.GetImportedPage(sReader, 1);
       int n = reader.NumberOfPages;
       PdfContentByte background;
       for (int i = 1; i <= n; i++)
       {
           background = stamper.GetUnderContent(i);
           background.AddTemplate(page, 0, 0);
       }
       stamper.Close();
       return true;
   }
   catch (Exception ex)
   {
       throw new Exception("Could not combine PDFs.", innerException: ex);
   }
}

Also, falls jemand mal das gleiche Problem hat, hat er nun eine Antwort.

14.11.2023 - 08:04 Uhr

Gibt es in C# eine Library, die es mir ermöglicht PDFs zu mergen? Mit mergen meine ich nicht das klassische Zusammenführen, im Sinne von untereinander anhängen.

Ich habe eine PDF mit einem Header und eine PDF mit einem Body.

Ist es möglich diese zu verschmelzen?

Hat das eventuell schon mal jemand gemacht, oder hätte ein Code-Schnipsel für mich?

25.10.2023 - 10:29 Uhr

Kurzer Edit an der Stelle. 
Ich habe das Ganze mal andersherum getestet. Komischerweise kann ich Computer so verschieben.. Bedeutet also, dass er mir den falschen Fehler wirft. Er hat dazu schlichtweg keine Berechtigungen. Wenn ich nämlich versuche manuell im ADExplorer zu verschieben, bekomme ich den Fehler "Zugriff verweigert".

25.10.2023 - 08:25 Uhr

Mein Fehler ist: Es wurde eine ungültige dn-Syntax angegeben.

Detailed: 00002125: NameErr: DSID-031B0344, problem 2006 (BAD_NAME), data 0, best match of:
'CN=TestRechner,OU=KOM,OU=ASS-Clients,DC=DOMASS,DC=local'

Ein Computer in CN=Computers,DC=DOMASS,DC=local soll nach OU=KOM,OU=ASS-Clients,DC=DOMASS,DC=local

Mein Code:


public async Task<ServiceResponse> AssignNewWorkstation(AssignNewWorkstation assignNewWorkstation)
{
   try
   {
       DirectoryEntry computerEntry = new DirectoryEntry("LDAP://CN=Computers,DC=DOMASS,DC=local", _user, _password);
       computerEntry.AuthenticationType = AuthenticationTypes.Secure;
       DirectorySearcher computerSearcher = new DirectorySearcher(computerEntry);
       computerSearcher.Filter = $"(&(objectClass=computer)(cn={assignNewWorkstation.WorkstationName}))";
       SearchResult computerResult = computerSearcher.FindOne();
       if (computerResult != null)
       {
           DirectoryEntry computer = computerResult.GetDirectoryEntry();
           DirectoryEntry newParent = new DirectoryEntry($"LDAP://OU=KOM,OU=ASS-Clients,DC=DOMASS,DC=local", _user, _password);
           computer.MoveTo(newParent);
           if (assignNewWorkstation.AssignAutomatically)
           {
               DirectoryEntry ouEntry = new DirectoryEntry("LDAP://OU=ASS-Benutzer,DC=DOMASS,DC=local", _user, _password);
               ouEntry.AuthenticationType = AuthenticationTypes.Secure;
               DirectorySearcher userSearcher = new DirectorySearcher(ouEntry);
               userSearcher.Filter = "(objectClass=user)";
               SearchResultCollection userResults = userSearcher.FindAll();
               foreach (SearchResult userResult in userResults)
               {
                   DirectoryEntry user = userResult.GetDirectoryEntry();
                   object userWorkstations = user.Properties["userWorkstations"].Value;
                   string updatedValue = (userWorkstations != null) ? userWorkstations.ToString() + "," + assignNewWorkstation.WorkstationName : assignNewWorkstation.WorkstationName;
                   user.Properties["userWorkstations"].Value = updatedValue;
                   user.CommitChanges();
                   user.Close();
               }
               ouEntry.Close();
           }
           computer.Close();
           return new ServiceResponse { StatusCode = 200, Message = $"Successfully moved the computer to {assignNewWorkstation.OU} and added it to users in the OU." };
       }
       else
       {
           return new ServiceResponse { StatusCode = 404, Message = "Computer not found." };
       }
   }
   catch (Exception ex)
   {
       Logger.Log(ex.ToString(), Logger.LogPriority.Error);
       return await ErrorHandler.ThrowErrorAsync(500);
   }
}

Die Variable computer ist auch gefüllt. Sprich, er findet den Comuter in LDAP://CN=Computers,DC=DOMASS,DC=local

Er fliegt bei

computer.MoveTo(newParent);
11.10.2023 - 14:48 Uhr

Ah ok. Darüber habe ich nicht nachgedacht.


Was bewirkt diese deps.json denn genau?

11.10.2023 - 12:36 Uhr

Ich binde eine externe DLL ein. Diese verwendet verschiedene andere DLLs und benutzt auch System.Web.

Im Anhang die Datei, um die es geht.

Wichtig sind da eigentlich nur die usings und die Hinweise ganz unten.

Jedenfalls bekomme ich folgenden Fehler (während der Laufzeit) wenn ich ein Objekt dieser Klasse erstelle: 
System.TypeInitializationException: "The type initializer for 'Procad.Profile.Engine.EngineClass' threw an exception."

Inner-Exception: TypeLoadException: Could not load type 'System.Web.HttpContext' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

Code:


               EngineClass engine = new EngineClass(); //Fehler wird hier geworfen
               engine.UserLogin("test", "test");
               ProfileUserManagement PUM = new ProfileUserManagement(engine);
               var user = PUM.CreateUser("Max Usermann");
               var result = PUM.SaveUser(user);
21.07.2023 - 15:53 Uhr

Ich habe die Samples doch noch ans laufen bekommen. Auf GitHub unter GitHub Issue ist beschrieben, wie man die Samples trotz Fehlermeldung ans laufen bekommt. Lag an der falschen SDK, die ich installiert hatte.

21.07.2023 - 14:15 Uhr

Ok. Danke für deine Hilfe. Dann werde ich jetzt wohl den Source-Code lesen müssen xD

21.07.2023 - 14:09 Uhr

Also komischerweise stehen auch Beiträge unter issues, die vom selben Problem berichten... Hast du eventuell nen Tipp, wie man das ans laufen bekommt?

21.07.2023 - 14:05 Uhr

Hi. Ich bin mal auf Blazor WASM umgestiegen. Problem: Try.NET scheint out of support zu sein (Samples funktionieren nicht).. Gibt es da eine alternative zu? Also eine andere Lib, die den C#-Code aufm Client ausführt?

28.06.2023 - 15:39 Uhr

Try .NET hört sich erstmal gut an, nur ist das halt Blazor WASM. Dann wäre mein API-Endpoint ja unnötig. Nur habe ich meine ganze Web-App so aufgebaut, dass das Frontend (React) nur Anfragen an meine API sendet.. Gibt es vielleicht noch eine andere Möglichkeit?

28.06.2023 - 12:54 Uhr

Ich hoffe, der Forenbereich ist richtig gewählt 😃.
Ich habe eine ASP .NET Core Web API und bekomme C# Code an einen Endpoint. Ich möchte diesen Code ausführen und den return-Wert an den User zurückgeben. Wie ist es mir möglich den Code in einer isolierten Umgebung auszuführen, sodass der Code keine Auswirkungen auf meine Maschine hat? Ich habe die Lib Microsoft.CodeAnalysis verwendet. Das Ausführen funktioniert. Problem ist eben nur, dass es nicht in einer abgesicherten Umgebung passiert. Klar, ich könnte eine zusätzliche API in einer VM machen, aber das wäre die letzte Option, die ich in Erwägung ziehen würde.