diff --git a/Controllers/AutoChildController.cs b/Controllers/AutoChildController.cs index 7b28f96..bc36567 100644 --- a/Controllers/AutoChildController.cs +++ b/Controllers/AutoChildController.cs @@ -11,6 +11,7 @@ using Microsoft.EntityFrameworkCore; using NejCommon.Utils; using Swashbuckle.AspNetCore.Annotations; using NejCommon.Models; +using System.ComponentModel.DataAnnotations.Schema; namespace NejCommon.Controllers { @@ -46,10 +47,25 @@ namespace NejCommon.Controllers this.providers = providers; } - protected abstract TType GetQuery(TOwner comp); + [NonAction] + public abstract TType? GetQuery(TOwner comp); protected abstract void Assign(TOwner comp, TType query); public virtual bool Trackable => true; + public virtual TType GetQueryHelper(TOwner owner){ + var entity = GetQuery(owner); + if (entity == null) + { + if (Trackable) + entity = db.Create(); + else + entity = new TType(); + Assign(owner, entity); + } + + return entity; + } + /// /// Gets the /// @@ -76,15 +92,7 @@ namespace NejCommon.Controllers [Route("")] public virtual async Task, Ok>> Update([FromServices] TOwner owner, [FromBody] TUpdateRequest body) { - var entity = GetQuery(owner); - if (entity == null) - { - if (Trackable) - entity = db.Create(); - else - entity = new TType(); - Assign(owner, entity); - } + var entity = GetQueryHelper(owner); /* if(entity is InvoiceBase inv){ //Console.Writeline(inv.InvoiceItems.Count); diff --git a/Controllers/TypedResultsPolyfill.cs b/Controllers/TypedResultsPolyfill.cs index c1091a0..0154ced 100644 --- a/Controllers/TypedResultsPolyfill.cs +++ b/Controllers/TypedResultsPolyfill.cs @@ -39,7 +39,7 @@ namespace NejCommon.Controllers { var okArg = IsSubclassOfRawGeneric(typeof(Ok<>), arg).GetGenericArguments()[0]; - Console.WriteLine("Adding: " + okArg); + // Console.WriteLine("Adding: " + okArg); //get or generate the schema var schema = context.SchemaGenerator.GenerateSchema(okArg, context.SchemaRepository); @@ -56,7 +56,7 @@ namespace NejCommon.Controllers operation.Responses.Remove("201"); var okArg = IsSubclassOfRawGeneric(typeof(CreatedAtRoute<>), arg).GetGenericArguments()[0]; - Console.WriteLine("Adding: " + okArg); + // Console.WriteLine("Adding: " + okArg); //get or generate the schema var schema = context.SchemaGenerator.GenerateSchema(okArg, context.SchemaRepository); @@ -72,7 +72,7 @@ namespace NejCommon.Controllers operation.Responses.Remove("400"); var okArg = IsSubclassOfRawGeneric(typeof(BadRequest<>), arg).GetGenericArguments()[0]; - Console.WriteLine("Adding: " + okArg); + // Console.WriteLine("Adding: " + okArg); //get or generate the schema var schema = context.SchemaGenerator.GenerateSchema(okArg, context.SchemaRepository); diff --git a/Emails/wwwroot/output.css b/Emails/wwwroot/output.css index 6ce011d..ce6e911 100644 --- a/Emails/wwwroot/output.css +++ b/Emails/wwwroot/output.css @@ -1,5 +1,5 @@ /* -! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com +! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com */ /* @@ -415,7 +415,7 @@ video { /* Make elements with the HTML hidden attribute stay hidden by default */ -[hidden] { +[hidden]:where(:not([hidden="until-found"])) { display: none; } diff --git a/Utils/HttpDebuggingHandler.cs b/Utils/HttpDebuggingHandler.cs new file mode 100644 index 0000000..54c768a --- /dev/null +++ b/Utils/HttpDebuggingHandler.cs @@ -0,0 +1,103 @@ +using System.Net.Http.Headers; +using System.Text; + +namespace NejCommon.Utils; + +public class HttpDebuggingHandler : DelegatingHandler + { + protected readonly ILogger Logger; + public HttpDebuggingHandler(ILogger logger, HttpMessageHandler innerHandler = null) + : base(innerHandler ?? new HttpClientHandler()) + { + Logger = logger; + } + + async protected override Task SendAsync(HttpRequestMessage request, + CancellationToken cancellationToken) + { + var req = request; + var id = Guid.NewGuid().ToString(); + var msg = $"[{id} - Request]"; + + StringBuilder output = new StringBuilder(); + + output.AppendLine($"{msg}========Start=========="); + output.AppendLine($"{req.Method} {req.RequestUri.PathAndQuery} {req.RequestUri.Scheme}/{req.Version}"); + output.AppendLine($"Host: {req.RequestUri.Scheme}://{req.RequestUri.Host}"); + + foreach (var header in req.Headers) + output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); + + if (req.Content != null) + { + foreach (var header in req.Content.Headers) + output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); + + if (req.Content is StringContent || IsTextBasedContentType(req.Headers) || + this.IsTextBasedContentType(req.Content.Headers)) + { + var result = await req.Content.ReadAsStringAsync(); + + output.AppendLine($"Content:"); + output.AppendLine($"{result}"); + } + } + + var start = DateTime.Now; + + var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + + var end = DateTime.Now; + + output.AppendLine($"Duration: {end - start}"); + output.AppendLine($"{msg}==========End=========="); + Logger.LogInformation(output.ToString()); + + output.Clear(); + + msg = $"[{id} - Response]"; + output.AppendLine($"{msg}=========Start========="); + + var resp = response; + + output.AppendLine( + $"{req.RequestUri.Scheme.ToUpper()}/{resp.Version} {(int) resp.StatusCode} {resp.ReasonPhrase}"); + + foreach (var header in resp.Headers) + output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); + + if (resp.Content != null) + { + foreach (var header in resp.Content.Headers) + output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); + + if (resp.Content is StringContent || this.IsTextBasedContentType(resp.Headers) || + this.IsTextBasedContentType(resp.Content.Headers)) + { + start = DateTime.Now; + var result = await resp.Content.ReadAsStringAsync(); + end = DateTime.Now; + + output.AppendLine($"Content:"); + output.AppendLine($"{result}"); + output.AppendLine($"Duration: {end - start}"); + } + } + + output.AppendLine($"{msg}==========End=========="); + Logger.LogInformation(output.ToString()); + return response; + } + + readonly string[] types = new[] {"html", "text", "xml", "json", "txt", "x-www-form-urlencoded"}; + + bool IsTextBasedContentType(HttpHeaders headers) + { + IEnumerable values; + if (!headers.TryGetValues("Content-Type", out values)) + return false; + var header = string.Join(" ", values).ToLowerInvariant(); + + return types.Any(t => header.Contains(t)); + } + } \ No newline at end of file