Dabei stelle ich fest, dass der Filter dafür gar nicht gebraucht wird.
Lieben Dank! Ich denke, ich bin selbst durcheinander gekommen, nach einer langen Nacht.
Ich habe zwar die Fehler in der Response gesehen, nicht jedoch im Log. Nun habe ich mir das ganze genauer angeschaut und im Program.cs
nach dem Build()
folgenden Code eingefügt:
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var logger = context.RequestServices.GetRequiredService<ILogger<Program>>();
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.ContentType = "application/json";
// Exception-Details abrufen.
var exceptionHandlerFeature = context.Features.Get<IExceptionHandlerFeature>();
if (exceptionHandlerFeature?.Error is Exception exception)
{
// Fehler mit Stacktrace nur ins Log schreiben. "context.TraceIdentifier" hilft bei der Fehlerverfolgung im Log.
logger.LogError(exception, "Fehler {TraceId}: {ErrorMessage}", context.TraceIdentifier, exception.Message);
}
else
{
// Allgemeiner Fehler ohne Exception. "context.TraceIdentifier" hilft bei der Fehlerverfolgung im Log.
logger.LogError($"Unbekannter Fehler {context.TraceIdentifier}");
}
var errorDetails = new
{
error = "Ein interner Serverfehler ist aufgetreten.",
traceId = context.TraceIdentifier // Hilft bei der Fehlerverfolgung im Log.
};
await context.Response.WriteAsJsonAsync(errorDetails);
});
});
Nun scheint es jetzt zu funktionieren, auch wenn Müll frei Haus geliefert wird.
Die Middleware sorgt dafür, dass alle Fehler, die während einer HTTP-Anfrage passieren können, abgefangen werden. Dabei wird der Fehler ausführlich im Log gespeichert. An den Client wird nicht zu viel geschickt. Der bekommt nur eine allgemeine Fehlermeldung, allerdings mit der TraceId
– Diese hilft, den Fehler im Log später nachzuvollziehen. Im Log steht, was genau schiefgelaufen ist, auch mit dem Stacktrace.
Nochmals lieben Dank und herzliche Grüße!
René
Hallo!
Ich brauche Hilfe von den Experten. Folgendes Problem: Ich baue eine API mit ASP.NET Core 8, die mit JSON-Strings gefüttert wird. Diese API empfängt Daten von einem Möbelkonfigurator, der noch fertig entwickelt werden muss. Dadurch gestaltet sich alles seitens der Firma, die den Konfigurator entwickelt, etwas zu dynamisch.
An sich ist die API fertig und betriebsbereit. Allerdings möchte die andere Softwarefirma mehr Infos, wenn sie die API testen und dabei auf Probleme stoßen. Warum sie das nicht einfach mit Postman machen, weiß ich nicht.
Auf jeden Fall lasse ich ein Log mit Serilog laufen. Die Logausgabe erfolgt in einer Datei mit einem Zeitstempel im Dateinamen. Jeden Tag wird eine neue Logdatei begonnen und es werden maximal 90 vorgehalten. Diese Logs protokollieren ziemlich alles und zwar sehr ausführlich. Auch Fehler werden darin protokolliert. Deswegen habe ich der anderen Softwarefirma einen lesenden WebDAV-Zugang zu diesen Protokollen ermöglicht, damit sie sich darin austoben können. Bis hierhin alles gut.
Nun gibt es aber einige Fehler, die bereits vor der Deserialisierung auftreten. Zum Beispiel schicken sie Daten, in denen u. a. eine GUID enthalten ist, die weder leer noch null
sein darf, und sie finden nichts besseres, als null
zu schicken. An dieser Stelle tritt ein Fehler auf, den ich aber bisher nicht abfangen konnte. Der Fehler wird kurz wie folgt protokolliert:
2025-01-29 07:20:58.650 +01:00 [DBG] JSON input formatter threw an exception: The JSON value could not be converted to System.Guid. Path: $.retailerId | LineNumber: 17 | BytePositionInLine: 22.
Es ist mir klar, was da passiert: retailerId kann nicht in eine GUID konvertiert werden, und man muss eben danach schauen, was da passiert ist.
Ich habe u. a. einen globalen Filter:
public class GlobalExceptionFilter : IExceptionFilter
{
private readonly ILogger<GlobalExceptionFilter> _logger;
public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
_logger.LogError(context.Exception, $"Eine Ausnahme ist aufgetreten: {context.Exception.Message}");
// ...
// Setze das Ergebnis auf einen generischen Fehler
context.Result = new ObjectResult(new { error = "Ein Fehler ist aufgetreten. Bitte überprüfen Sie die Protokolle für weitere Details." })
{
StatusCode = 500
};
context.ExceptionHandled = true;
}
}
Zusätzlich einen benutzerdefinierten Action-Filter, der verwendet wird, um Validierungsfehler im ModelState
zu überprüfen und zu protokollieren:
public class CustomModelStateInvalidFilter : IActionFilter
{
public int Order => -2100;
private readonly ILogger<CustomModelStateInvalidFilter> _logger;
public CustomModelStateInvalidFilter(ILogger<CustomModelStateInvalidFilter> logger)
{
_logger = logger;
}
public void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogInformation("CustomModelStateInvalidFilter wurde ausgeführt.");
if (!context.ModelState.IsValid)
{
// ...
context.Result = new BadRequestObjectResult(problemDetails);
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Keine Aktion erforderlich nach der Ausführung
}
}
Diese Filter werden im Program.cs
hinzugefügt:
builder.Services.AddControllers(options =>
{
options.Filters.Add<CustomModelStateInvalidFilter>();
options.Filters.Add<GlobalExceptionFilter>();
options.Filters.Add<ModelStateLoggerFilter>();
})
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
options.JsonSerializerOptions.WriteIndented = true;
});
Dann schließlich eine benutzerdefinierte Middleware, die Fehler bei der JSON-Deserialisierung sowie allgemeine Fehler abfangen und eine Fehlerantwort zurückgeben sollte:
namespace okpm.Middleware;
public class JsonExceptionHandlingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<JsonExceptionHandlingMiddleware> _logger;
public JsonExceptionHandlingMiddleware(RequestDelegate next, ILogger<JsonExceptionHandlingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (JsonException ex)
{
_logger.LogError(ex, $"Fehler beim JSON-Parsing: {ex.Message}");
await HandleErrorAsync(context, ex, "Ungültige JSON-Daten.");
}
catch (InvalidOperationException ex) when (ex.Message.Contains("JSON input formatter"))
{
_logger.LogError(ex, $"Fehler beim JSON-Parsing: {ex.Message}");
await HandleErrorAsync(context, ex, "Fehler beim Verarbeiten der Anfrage.");
}
catch (Exception ex)
{
_logger.LogError(ex, $"Unbehandelter Fehler: {ex.Message}");
await HandleErrorAsync(context, ex, "Unbekannter Fehler.");
}
}
private Task HandleErrorAsync(HttpContext context, Exception ex, string message)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
context.Response.ContentType = "application/json";
var response = new
{
message,
error = ex.Message
};
return context.Response.WriteAsync(JsonSerializer.Serialize(response));
}
}
Eingebunden wird sie im Program.cs:
app.UseMiddleware<Middleware.JsonExceptionHandlingMiddleware>();
Aber egal, was ich mache, ich kann so eine Ausnahme, die bei einem Problem beim Parsen von JSON-Daten auftritt (z. B. ungültiges JSON: retailerId = null
), nicht abfangen.
Schlimm ist es nicht, denn ASP.NET Core protokolliert mir den Fehler:
2025-01-29 07:20:58.650 +01:00 [DBG] JSON input formatter threw an exception: The JSON value could not be converted to System.Guid. Path: $.retailerId | LineNumber: 17 | BytePositionInLine: 22.
Allerdings dachte ich mir, ich kann hier eingreifen und selbst die Fehlermeldung etwas umfangreicher machen und sie aufhübschen. Bisher aber erfolglos.
Hat mir jemand einen Tipp?
Danke im Voraus und liebe Grüße
René
Ja, danke, ich kenne sie. Mir geht es dabei um diese Position:
Visual Studio Professional-Abonnements (ohne monatliche Azure-Gutschrift)
Darüber hinaus weiter unten zu lesen:
Diese Tabellen dienen nur allgemeinen Informationszwecken als allgemeine Übersicht über Microsoft-Partnervorteilepakete. Die hierin aufgeführten Programminformationen können sich ändern und sollten nicht als Angebot, Bestätigung, Garantie, Verpflichtung oder sonstige Art von Darstellung von Microsoft interpretiert werden. Vollständige Details und Anforderungen sind festgelegt und unterliegen den anwendbaren Programmberatern und Partnervereinbarungen.
Also es kann sich schon das eine oder andere ändern.
Vielen Dank!
Ich habe diesen Thread vor kurzem entdeckt und mich direkt hier eingeklinkt. Wie bereits erwähnt, finde ich leider keine Informationen über den genauen Leistungsumfang der enthaltenen "Visual Studio Professional Subscription". Daher warte ich nun auf den Rückruf vom Microsoft-Support und hoffe auf eine Klärung.
Sollte ich neue Informationen erhalten, werde ich diese hier posten.
Hallo zusammen!
Ich hoffe, hier kann mir jemand mit Informationen zum Action Pack und seinem möglichen Nachfolger weiterhelfen.
Seit vielen Jahren nutze ich die "Visual Studio Professional Subscription" als Teil des Action Packs. Leider wird das Action Pack ab Januar 2025 nicht mehr angeboten. Im Action Pack sind Lizenzen für verschiedene Microsoft-Produkte enthalten, darunter Server- und Client-Betriebssysteme sowie SQL-Server, die ich als Entwickler gerne für Testzwecke nutze.
Jetzt gibt es das Produkt "Partner Success Core", das ebenfalls eine "Visual Studio Professional Subscription" umfasst. Was ich jedoch noch nicht herausfinden konnte, ist, ob diese VS-Subscription auch die Lizenzen für Microsoft-Server- und Client-Betriebssysteme sowie für SQL-Server oder andere bisher enthaltene Software beinhaltet.
Falls dies nicht der Fall sein sollte, welche einigermaßen kostengünstigen Alternativen gibt es, um an diese Ressourcen zu gelangen?
Seit gestern versuche ich, einen verlässlichen Ansprechpartner bei Microsoft zu erreichen. Ich habe bereits eine Supportanfrage eingereicht, aber bisher noch keinen Rückruf erhalten. Daher wollte ich dieses Thema hier zur Diskussion stellen – möglicherweise betrifft es auch andere, die wie ich das Action Pack nutzen.
Vielen Dank im Voraus für eure Unterstützung!
Viele Grüße
René
Hallo T-Virus,
ich glaube, da prallen Galaxien aufeinander 😃
Es tut mir echt leid, dass du dich von den Regeln so stark eingeengt fühlst. Aber hey, in einer Zeit, in der viele Foren gegen KI kämpfen, ist es doch schön, wenn sich noch Leute finden, die sich austauschen möchten. Regeln sind nun mal dazu da, um befolgt zu werden, nicht wahr? Auch wenn es manchmal schwerfällt, sollten wir uns alle bemühen, den "guten deutschen" Weg zu gehen und Regeln nicht als optional anzusehen – wo kämen wir denn hin?! Wer braucht schon Flexibilität und Anpassungsfähigkeit in einer sich ständig wandelnden Welt, wenn wir stattdessen stur auf Regeln pochen können?
Und ja, du hast völlig recht. Die Herausforderungen moderner Technologien machen es vielen Foren nicht leicht. Man sagt ja, dass künstliche Intelligenz auf dem Vormarsch ist, und vielleicht führt das dazu, dass echte menschliche Interaktionen immer seltener werden. Da ist es wirklich erfrischend, wenn sich noch Menschen wie du und ich die Zeit nehmen, sich auszutauschen und Wissen zu teilen.
Also, bitte weiter so! Möge deine Einhaltung der Regeln stets ein leuchtendes Beispiel für uns alle sein. Denn wir wissen ja: Ein Forum ohne Regeln ist wie ein Tag ohne Regen - voller Möglichkeit und Potenzial, aber irgendwie auch viel zu chaotisch.
In diesem Sinne alles Gute,
René
Hallo zusammen,
wie ich sehe, gibt es hier eine kleine, von mir nicht gewollte Diskussion über Crossposting. Lass uns das mal ganz entspannt angehen – vielleicht hilft das in der Zukunft.
Erhöhte Sichtbarkeit und schnellere Lösungen:
Mehr Augen sehen mehr. Wenn ich dieselbe Frage in mehreren Foren stelle, erreiche ich eine breitere Expertise. Das erhöht die Chance auf eine schnelle und passende Antwort. Ist doch effizient, oder?
Wissenstransfer:
Wenn ich irgendwo eine Lösung finde, teile ich sie in anderen Foren. So profitieren alle. Das ist doch der Sinn der Sache, Wissen zu verbreiten (siehe dazu nächsten Punkt).
Transparenz:
Ja, mea culpa, ich hab das Crossposting nicht erwähnt. Normalerweise tue ich das. Vielleicht war es, wie bereits erwähnt, der Arbeitsdruck oder die schiere Lustlosigkeit, mich wie im Kindergarten über Crossposting zu rechtfertigen.
Effizienz:
Mehrere Experten können gleichzeitig an einer Lösung arbeiten. Das spart Zeit und führt oft zu besseren Ergebnissen. Außerdem, wer will schon alle Eier in einen Korb legen?
Respekt:
Natürlich respektiere ich die Hilfe aller Forenmitglieder – ich habe mich immer korrekt und anständig bei jedem Helfenden bedankt. Wenn ich eine Lösung finde, teile ich sie überall, damit alle davon profitieren können.
Übrigens, zum Thema Regeln: Manchmal sind Regeln dafür da, um hinterfragt zu werden, besonders wenn sie die Effizienz und den Wissensaustausch behindern. Aber keine Sorge, ich werde in Zukunft darauf achten, Crossposting explizit zu erwähnen, um Missverständnisse zu vermeiden.
Außerdem: Klar, ich hätte schreiben können, dass ich die Frage auch woanders gestellt habe. Aber ehrlich gesagt, hatte sich jemand früher schon mal darüber mokiert, und ich hatte echt keine Lust auf kindische Diskussionen. In der Regel gebe ich die Lösung bekannt, aber durch den Arbeitsstress ist das leider untergegangen – man ist nur ein Mensch. So führte diese Crossposting-Regel dazu, dass das Forum selbst nichts davon hat. Vielleicht sollte man mit der Zeit gehen und solche antiquierten Regeln überdenken.
Liebe Grüße
René
Zitat von dannoe
Zumindest erwähnen sollte man das Crossposting. Wenn jemand mit ähnlichem Problem dein Forenbeitrag findet, dann kann derjenige zumindest die anderen Crossposts nach weiteren Lösungen/Ideen durchsuchen.
Noch schöner wäre es natürlich, wenn die Lösung am Ende dann auch hier und in allen anderen Crossposts mitgeteilt wird.
Jo, da hast du Recht. Normalerweise tue ich das auch. Ich weiß auch heute nicht mehr, warum ich das nicht tat. Sicher der Arbeitsdruck, wenn ich mich an das Projekt damals erinnere oder keine Lust, nachdem hier mit diesem Thema wie im Kindergarten umgangen wird Cross Posting – ich weiß es einfach nicht mehr.
@wcseller
Du schreibst:
BTW: Ich würde für solche Dinge immer nur EWS verwenden. Man tut sich deutlich leichter, hat mehr Möglichkeiten und ist nicht auf ein installiertes Outlook angewiesen
Das ist klar, aber löst dieses Problem nicht. Sonst hätte ich das nicht geschrieben.
Zitat von pollito
(..) EWS oder PowerShell sollten nicht verwendet werden.
@dannoe
Ich hoffe, ich muss mich nicht schuldig bekennen, einen Cross-Posting begangen zu haben...
Das Problem habe ich anderwärtig gelöst, was zur Aufgabenstellung sogar besser passt.
Danke und buen dia!
René
Nein, die laufen nicht gleichzeitig parallel. Wenn "Securepoint Antivirus Pro" läuft, ist der Defender abgeschaltet. Schalte ich "Securepoint Antivirus Pro" aus, aktiviert sich automatisch der MS-Defender. Genau letzteres war mir passiert im dritten Punkt der Auflistung.