OData / Extensions

ExtensionsLib: - Extensions for OData libraries and framework
MIT License
11 stars 19 forks source link

Using OData Client and Extensions with .Net Blazor 8 WebAssembly #61

Open rgsilva20 opened 9 months ago

rgsilva20 commented 9 months ago

When I run the example code below, using .Net Blazor 8 WebAssembly, the Container does not bring any results.

Program.cs

internal class Program
{
    static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        string host = builder.HostEnvironment.BaseAddress;
        builder.Services.AddSingleton<HttpAuthorizedHandler>();
        builder.Services.AddSingleton(sp => new HttpClient(sp.GetRequiredService<HttpAuthorizedHandler>()) { BaseAddress = new Uri(host), Timeout = TimeSpan.FromMinutes(2) });
        builder.Services.AddHttpClient("default", httpClient =>
        {
            httpClient.BaseAddress = new Uri(host);
            httpClient.Timeout = TimeSpan.FromMinutes(2);
        }).AddHttpMessageHandler<HttpAuthorizedHandler>();

        builder.Services.AddODataClient("default")
            .AddHttpClient();

        builder.Services.AddFluentUIComponents();
        await builder.Build().RunAsync();
    }
}

Home.razor

@page "/people"

@inject IODataClientFactory ODataClientFactory
@inject IWebAssemblyHostEnvironment HostEnvironment

<div class="row">
    <div class="col-12">
        <div class="page-title-box d-sm-flex align-items-center justify-content-between">
            <h4 class="mb-sm-0 font-size-18">Pessoas</h4>
        </div>
    </div>
</div>

<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-body">
                @foreach (var item in collection)
                {
                    <div>@item.Id - @item.Name</div>
                }
            </div>
        </div>
    </div>
</div>

@code {
    private Container? dataContainer;
    private List<Person> collection = new();

    protected override async Task OnInitializedAsync()
    {
        try
        {
            if (dataContainer == null)
            {
                dataContainer = ODataClientFactory.CreateClient<Container>(new Uri(HostEnvironment.BaseAddress + "odata"), "default");
            }

            collection.Clear();
            var data = dataContainer.People
                .Where(e => e.Id > 10)
                .OrderBy(e => e.Name);
            collection.AddRange(data.ToList());
            StateHasChanged();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }
}

However, when I run the code below, the Container returns the result.

    protected override async Task OnInitializedAsync()
    {
        try
        {
            if (dataContainer == null)
            {
                dataContainer = ODataClientFactory.CreateClient<Container>(new Uri(HostEnvironment.BaseAddress + "odata"), "default");
            }

            collection.Clear();
            var data = await dataContainer.People.ExecuteAsync();
            collection.AddRange(data.ToList());
            StateHasChanged();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }

I understand that it is necessary to execute the ExecuteAsync() method to return the result, but this method is not available for the IQueryable<T> interface returned in the Where() or OrderBy() methods. Please add the code below to the ODataClientQueryExtensions.cs file to resolve this problem.

        /// <summary>
        /// convert the queryable to DataServiceQuery and execute it.
        /// </summary>
        /// <typeparam name="TElement">the entity type.</typeparam>
        /// <param name="queryable">the OData querable.</param>
        /// <returns>the OData query result.</returns>
        public static async Task<IEnumerable<TElement>> ExecuteAsync<TElement>(this IQueryable<TElement> queryable)
        {
            var collection = (DataServiceQuery<TElement>)queryable;
            return await collection.ExecuteAsync().ConfigureAwait(false);
        }