From 1ad0ea4d292f0baf58d7c7ef73770fb762dd09f8 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 21 Feb 2025 11:56:28 +0100 Subject: [PATCH] Json Error Handling + Echo --- Host/Host.csproj.user | 2 +- Host/Web.config | 6 +- Service/Service.csproj | 3 + .../JsonError/JsonErrorBehavior.cs | 32 +++++++ .../JsonError/JsonErrorBehaviorExtension.cs | 19 ++++ .../JsonError/JsonErrorHandler.cs | 89 +++++++++++++++++++ Service/ServiceContracts/IAdminService.cs | 6 +- .../ServiceImplementations/AdminServiceImp.cs | 5 ++ 8 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 Service/ServiceBehavior/JsonError/JsonErrorBehavior.cs create mode 100644 Service/ServiceBehavior/JsonError/JsonErrorBehaviorExtension.cs create mode 100644 Service/ServiceBehavior/JsonError/JsonErrorHandler.cs diff --git a/Host/Host.csproj.user b/Host/Host.csproj.user index f8b116048..361b57e4b 100644 --- a/Host/Host.csproj.user +++ b/Host/Host.csproj.user @@ -1,4 +1,4 @@ - + BeWo2.0 diff --git a/Host/Web.config b/Host/Web.config index a45800f20..f513048a7 100644 --- a/Host/Web.config +++ b/Host/Web.config @@ -210,13 +210,14 @@ - + - + + @@ -240,6 +241,7 @@ + diff --git a/Service/Service.csproj b/Service/Service.csproj index f96bb9fc7..d80c4bcf7 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -488,6 +488,9 @@ + + + diff --git a/Service/ServiceBehavior/JsonError/JsonErrorBehavior.cs b/Service/ServiceBehavior/JsonError/JsonErrorBehavior.cs new file mode 100644 index 000000000..dd95f21c3 --- /dev/null +++ b/Service/ServiceBehavior/JsonError/JsonErrorBehavior.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.ServiceBehavior.JsonError +{ + internal class JsonErrorBehavior : IEndpointBehavior + { + public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) + { + } + + public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) + { + } + + public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) + { + endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new JsonErrorHandler()); + } + + public void Validate(ServiceEndpoint endpoint) + { + } + } +} diff --git a/Service/ServiceBehavior/JsonError/JsonErrorBehaviorExtension.cs b/Service/ServiceBehavior/JsonError/JsonErrorBehaviorExtension.cs new file mode 100644 index 000000000..274368d1e --- /dev/null +++ b/Service/ServiceBehavior/JsonError/JsonErrorBehaviorExtension.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel.Configuration; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.ServiceBehavior.JsonError +{ + public class JsonErrorBehaviorExtension : BehaviorExtensionElement + { + public override Type BehaviorType => typeof(JsonErrorBehavior); + + protected override object CreateBehavior() + { + return new JsonErrorBehavior(); + } + } +} diff --git a/Service/ServiceBehavior/JsonError/JsonErrorHandler.cs b/Service/ServiceBehavior/JsonError/JsonErrorHandler.cs new file mode 100644 index 000000000..f8f7d7f0f --- /dev/null +++ b/Service/ServiceBehavior/JsonError/JsonErrorHandler.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.ServiceModel.Channels; +using System.ServiceModel.Dispatcher; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace BeWo.Service.ServiceBehavior.JsonError +{ + [DataContract] + public class JsonError + { + [DataMember] + public string Message { get; set; } + + [DataMember] + public string ExceptionType { get; set; } + } + + public class JsonErrorHandler : IErrorHandler + { + public void ProvideFault(Exception error, MessageVersion version, ref Message fault) + { + // Erstelle eine JSON-Fehlermeldung + var jsonError = new JsonError + { + Message = error.Message, + ExceptionType = error.GetType().Name + }; + + // Serialisiere das JSON-Objekt + var serializer = new DataContractJsonSerializer(typeof(JsonError)); + using (var stream = new MemoryStream()) + { + serializer.WriteObject(stream, jsonError); + stream.Position = 0; + using (var reader = new StreamReader(stream)) + { + string jsonString = reader.ReadToEnd(); + fault = Message.CreateMessage(version, null, new JsonBodyWriter(jsonString)); + } + } + + // Setze den Content-Type auf application/json + var webBodyFormat = WebBodyFormatMessageProperty.Name; + if (!fault.Properties.ContainsKey(webBodyFormat)) + { + fault.Properties.Add(webBodyFormat, new WebBodyFormatMessageProperty(WebContentFormat.Raw)); + } + + var httpResponse = new HttpResponseMessageProperty + { + StatusCode = System.Net.HttpStatusCode.InternalServerError, + StatusDescription = "Internal Server Error", + }; + httpResponse.Headers["Content-Type"] = "application/json"; + fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponse); + } + + public bool HandleError(Exception error) + { + // Gib an, ob der Fehler behandelt wurde + return true; + } + } + + public class JsonBodyWriter : BodyWriter + { + private readonly string _json; + + public JsonBodyWriter(string json) : base(true) + { + _json = json; + } + + protected override void OnWriteBodyContents(System.Xml.XmlDictionaryWriter writer) + { + writer.WriteStartElement("Binary"); + byte[] jsonBytes = Encoding.UTF8.GetBytes(_json); + writer.WriteBase64(jsonBytes, 0, jsonBytes.Length); + writer.WriteEndElement(); + } + } +} diff --git a/Service/ServiceContracts/IAdminService.cs b/Service/ServiceContracts/IAdminService.cs index ea7a62acd..68351d725 100644 --- a/Service/ServiceContracts/IAdminService.cs +++ b/Service/ServiceContracts/IAdminService.cs @@ -12,7 +12,11 @@ namespace BeWo.Service.ServiceContracts public interface IAdminService { [OperationContract] - [WebGet(UriTemplate = "/Test")] + [WebGet(UriTemplate = "/Test", ResponseFormat = WebMessageFormat.Json)] string Test(); + + [OperationContract] + [WebInvoke(UriTemplate = "/Echo/{echo}", Method ="POST", ResponseFormat = WebMessageFormat.Json)] + string Echo(string echo); } } diff --git a/Service/ServiceImplementations/AdminServiceImp.cs b/Service/ServiceImplementations/AdminServiceImp.cs index 9a6566323..cfb828905 100644 --- a/Service/ServiceImplementations/AdminServiceImp.cs +++ b/Service/ServiceImplementations/AdminServiceImp.cs @@ -15,5 +15,10 @@ namespace BeWo.Service.ServiceImplementations { return "Test erfolgreich!"; } + + public string Echo(string echo) + { + return echo; + } } }