diff --git a/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ControllerAction.cs b/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ControllerAction.cs index 7bd21af8aa..dbaeed1049 100644 --- a/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ControllerAction.cs +++ b/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ControllerAction.cs @@ -11,6 +11,8 @@ public class ControllerAction public bool DoesReturnSomething => ReturnType.ToDisplayString() is not "System.Threading.Tasks.Task" or "System.Threading.Tasks.ValueTask"; + public bool DoesReturnIAsyncEnumerable => DoesReturnSomething && ReturnType.ToDisplayString().Contains("IAsyncEnumerable"); + public string HttpMethod { get; set; } = default!; public string Url { get; set; } = default!; diff --git a/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/HttpClientProxySourceGenerator.cs b/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/HttpClientProxySourceGenerator.cs index 3399359ebe..0ab44e2964 100644 --- a/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/HttpClientProxySourceGenerator.cs +++ b/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/HttpClientProxySourceGenerator.cs @@ -46,8 +46,9 @@ public void Execute(GeneratorExecutionContext context) {{" : string.Empty)} using var request = new HttpRequestMessage(HttpMethod.{action.HttpMethod}, url); {(action.BodyParameter is not null ? $@"request.Content = JsonContent.Create({action.BodyParameter.Name}, options.GetTypeInfo<{action.BodyParameter.Type.ToDisplayString()}>());" : string.Empty)} - using var response = await httpClient.SendAsync(request{(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)}); - {(action.DoesReturnSomething ? ($"return await response.Content.ReadFromJsonAsync(options.GetTypeInfo<{action.ReturnType.GetUnderlyingType().ToDisplayString()}>(){(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)});}}))!;") : string.Empty)} + {(action.DoesReturnIAsyncEnumerable ? "" : "using ")}var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead {(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)}); + {(action.DoesReturnSomething ? ($"return {(action.DoesReturnIAsyncEnumerable ? "" : "await")} response.Content.{(action.DoesReturnIAsyncEnumerable ? "ReadFromJsonAsAsyncEnumerable" : "ReadFromJsonAsync")}(options.GetTypeInfo<{action.ReturnType.GetUnderlyingType().ToDisplayString()}>(){(action.HasCancellationToken ? $", {action.CancellationTokenParameterName}" : string.Empty)});" + + $"}}))!;") : string.Empty)} }} "); } @@ -114,7 +115,6 @@ public void AddQueryStrings(Dictionary queryString) }} "); - context.AddSource($"HttpClientProxy.cs", finalSource.ToString()); } } diff --git a/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ITypeSymboExtensions.cs b/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ITypeSymboExtensions.cs index 1e32f9bc32..36cd2205a0 100644 --- a/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ITypeSymboExtensions.cs +++ b/src/SourceGenerators/Bit.SourceGenerators/HttpClientProxy/ITypeSymboExtensions.cs @@ -24,10 +24,16 @@ public static string GetHttpMethod(this IMethodSymbol method) public static ITypeSymbol GetUnderlyingType(this ITypeSymbol typeSymbol) { - return typeSymbol switch + if (typeSymbol is INamedTypeSymbol namedTypeSymbol) { - INamedTypeSymbol namedTypeSymbol => namedTypeSymbol.TypeArguments.FirstOrDefault() ?? namedTypeSymbol, - _ => typeSymbol - }; + if (namedTypeSymbol.ToDisplayString().Contains("System.Collections.Generic.IAsyncEnumerable<")) + { + return namedTypeSymbol.TypeArguments.First().GetUnderlyingType(); + } + + return namedTypeSymbol.TypeArguments.FirstOrDefault() ?? namedTypeSymbol; + } + + return typeSymbol; } } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Categories/CategoryController.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Categories/CategoryController.cs index d8a538c5f1..9676f5348b 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Categories/CategoryController.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Categories/CategoryController.cs @@ -28,7 +28,7 @@ public async Task> GetCategories(ODataQueryOptions(query.AsAsyncEnumerable(), totalCount); + return new PagedResult(await query.ToArrayAsync(cancellationToken), totalCount); } [HttpGet("{id}")] diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Products/ProductController.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Products/ProductController.cs index d50fa46b42..20aefa316f 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Products/ProductController.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Products/ProductController.cs @@ -28,7 +28,7 @@ public async Task> GetProducts(ODataQueryOptions(query.AsAsyncEnumerable(), totalCount); + return new PagedResult(await query.ToArrayAsync(cancellationToken), totalCount); } [HttpGet("{id}")] diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Todo/TodoItemController.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Todo/TodoItemController.cs index 65173823c5..caee9d23a1 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Todo/TodoItemController.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Server/Controllers/Todo/TodoItemController.cs @@ -31,7 +31,7 @@ public async Task> GetTodoItems(ODataQueryOptions(query.AsAsyncEnumerable(), totalCount); + return new PagedResult(await query.ToArrayAsync(cancellationToken), totalCount); } [HttpGet("{id}")] diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/AppJsonContext.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/AppJsonContext.cs index d2faebbc76..2b54f651fc 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/AppJsonContext.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/AppJsonContext.cs @@ -15,20 +15,17 @@ namespace Boilerplate.Shared.Dtos; [JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] [JsonSerializable(typeof(Dictionary))] [JsonSerializable(typeof(UserDto))] -[JsonSerializable(typeof(List))] //#if (sample == "Todo") [JsonSerializable(typeof(TodoItemDto))] -[JsonSerializable(typeof(List))] +[JsonSerializable(typeof(PagedResult))] //#elif (sample == "Admin") +[JsonSerializable(typeof(ProductsCountPerCategoryResponseDto))] [JsonSerializable(typeof(OverallAnalyticsStatsDataResponseDto))] -[JsonSerializable(typeof(List))] -[JsonSerializable(typeof(List))] -[JsonSerializable(typeof(List))] +[JsonSerializable(typeof(ProductSaleStatResponseDto))] +[JsonSerializable(typeof(ProductPercentagePerCategoryResponseDto))] [JsonSerializable(typeof(ProductDto))] -[JsonSerializable(typeof(List))] [JsonSerializable(typeof(PagedResult))] [JsonSerializable(typeof(CategoryDto))] -[JsonSerializable(typeof(List))] [JsonSerializable(typeof(PagedResult))] //#endif [JsonSerializable(typeof(SignInRequestDto))] diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/PagedResultDto.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/PagedResultDto.cs index 0bdaae6a7d..c3ebdd935c 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/PagedResultDto.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Boilerplate.Shared/Dtos/PagedResultDto.cs @@ -2,18 +2,14 @@ public class PagedResult { - public IAsyncEnumerable? Items { get; set; } + public T[] Items { get; set; } = []; public long TotalCount { get; set; } - public PagedResult(IAsyncEnumerable items, long totalCount) + [JsonConstructor] + public PagedResult(T[] items, long totalCount) { Items = items; TotalCount = totalCount; } - - public PagedResult() - { - - } } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs index 38fb5fa79b..4a6c65a38d 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs @@ -1,4 +1,6 @@ -namespace Boilerplate.Client.Core.Components; +using System.Text.Json; + +namespace Boilerplate.Client.Core.Components; public partial class AppComponentBase : ComponentBase, IDisposable { @@ -8,6 +10,8 @@ public partial class AppComponentBase : ComponentBase, IDisposable [AutoInject] protected HttpClient HttpClient = default!; + [AutoInject] protected JsonSerializerOptions JsonSerializerOptions = default!; + /// /// /// diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/CategoriesPage.razor.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/CategoriesPage.razor.cs index ae8defafbf..a980477010 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/CategoriesPage.razor.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/CategoriesPage.razor.cs @@ -62,7 +62,7 @@ private void PrepareGridDataProvider() var data = await categoryController.GetCategories(CurrentCancellationToken); - return BitDataGridItemsProviderResult.From(await data.Items!.ToListAsync(CurrentCancellationToken)!, (int)data.TotalCount); + return BitDataGridItemsProviderResult.From(data.Items!, (int)data.TotalCount); } catch (Exception exp) { diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Products/ProductsPage.razor.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Products/ProductsPage.razor.cs index 10ae347b16..b8641c6d8c 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Products/ProductsPage.razor.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Products/ProductsPage.razor.cs @@ -62,7 +62,7 @@ private void PrepareGridDataProvider() var data = await productController.GetProducts(CurrentCancellationToken); - return BitDataGridItemsProviderResult.From(await data!.Items!.ToListAsync(), (int)data!.TotalCount); + return BitDataGridItemsProviderResult.From(data!.Items!, (int)data!.TotalCount); } catch (Exception exp) { diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppRenderMode.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppRenderMode.cs index affc20667c..b84080a0e4 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppRenderMode.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppRenderMode.cs @@ -1,3 +1,4 @@ +//-:cnd:noEmit using Microsoft.AspNetCore.Components.Web; namespace Boilerplate.Client.Core.Services;