Git Product home page Git Product logo

extensions's People

Contributors

chuanboz avatar eumikhailov avatar gathogojr avatar groovyfeng avatar marabooy avatar microsoftopensource avatar msftgits avatar xuzhg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

extensions's Issues

High latency issues when use HttpClient in OData Client with TaskExtensionMethods.ToApm

Currently in ODataClient extensions, there is default implementation to use HttpClient in ODataClient based on similar code as documented in Use HttpClient in OData Client, this is working well under normal load, but during perf load testing, I found that under high request rate with thread usage, the end to end latency could jump dramatically from less than seconds to a few minutes and even approaching hours. After a long time of experiment and debugging, I eventually trace it to the following line of code:

public static class TaskExtensionMethods
    {
        public static Task<TResult> ToApm<TResult>(this Task<TResult> task, AsyncCallback callback, object state)
        {
            var tcs = new TaskCompletionSource<TResult>(state);

            task.ContinueWith(
                delegate
                {
...
                    if (callback != null)
                    {
                        callback(tcs.Task);
                    }
                },
                CancellationToken.None,
                TaskContinuationOptions.None,  // <-- issue is here, due to context switch under high load.
                TaskScheduler.Default);

            return tcs.Task;
        }
    }

I tried to change TaskContinuationOptions.None to TaskContinuationOptions.ExecuteSynchronously, then the latency issue is gone even under high load, and could now finish in less than second during perf test.

Could not install the extension on .Net 5 project

Error NU1107 Version conflict detected for Microsoft.Extensions.DependencyInjection. Install/reference Microsoft.Extensions.DependencyInjection 5.0.0-preview.7.20364.11 directly to project Test.WebClient to resolve this issue.
Test.WebClient -> Test.DataService -> Test.Entity -> Microsoft.AspNetCore.Identity.EntityFrameworkCore 5.0.0-preview.7.20365.19 -> Microsoft.EntityFrameworkCore.Relational 5.0.0-preview.7.20365.15 -> Microsoft.EntityFrameworkCore 5.0.0-preview.7.20365.15 -> Microsoft.Extensions.DependencyInjection (>= 5.0.0-preview.7.20364.11)
Test.WebClient -> Microsoft.OData.Extensions.Client 1.0.2 -> Microsoft.Extensions.DependencyInjection (>= 2.1.0 && < 4.0.0). Test.WebClient D:\Projects\Test.WebClient.csproj 1

Use extensions from a Non Asp.net Core context

How should we use this package from a Non ASP.net Core context where the Ninject DI system is being used? Hence i can not use the provided AddODataClient() / AddHttpClient() functionality since it is build on IServiceprovider which is not available.

Binding the DefaultODataClientFactory manually is not possible neither since the class is marked as internal (and deriviates as well). I am also wondering how i could get it working.

Update for Microsoft.OData.Core > 7.6.1

Hello,

If a project references Microsoft.AspnetCore.OData v7.4.1, you cannot reference the latest version of Microsoft.OData.Extensions.Client v1.0.1, because of a version conflict :

Microsoft.AspNetCore.OData 7.4.1 -> Microsoft.OData.Core (>= 7.6.1 && < 8.0.0)
Microsoft.OData.Client 7.6.0 -> Microsoft.OData.Core (= 7.6.0)

There are new abstract properties in DataServiceClientRequestMessage that are not implemented in Microsoft.OData.Extensions.ClientHttpClientRequestMessage

Do you know when will it be updated ? Thank you

Allow access to service provider on ConfigureODataClient

Hi,

I have a tenant app that has various services that provide information about the current tenant, user, and the URLs to be used to access server resources, per tenant/user.
It's called IUriProvider.

I can see the method in DefaultODataClientFactory based on serviceRoot.
But I rather them all to be based on the underlying IHttpClientFactory's provided HttpClient.BaseAddress.

In addition, the IOdataClientFactory.CreateClient<T>, also requires a serviceRoot argument. This is unnecessary if it has already been configured, or if there is an underlying HttpClient whose BaseAddress should be used for this matter instead.
Asking for Uris all over the place which would rely on constants, is a bad habit and somewhat defies the power of DI.

Could not add the nuget package reference to .NET5 Blazor Web Assembly project

Error	NU1107	Version conflict detected for Microsoft.Extensions.DependencyInjection. Install/reference Microsoft.Extensions.DependencyInjection 5.0.0 directly to project BlazorClientApp5 to resolve this issue. 
 BlazorClientApp5 -> Microsoft.AspNetCore.Components.WebAssembly 5.0.0 -> Microsoft.Extensions.Logging 5.0.0 -> Microsoft.Extensions.DependencyInjection (>= 5.0.0) 
 BlazorClientApp5 -> Microsoft.OData.Extensions.Client 1.0.2 -> Microsoft.Extensions.DependencyInjection (>= 2.1.0 && < 4.0.0).	

Error after upgrading to .NET 3.1

Connection id "0HM1US5IK9AH0", Request id "0HM1US5IK9AH0:00000002": An unhandled exception was thrown by the application.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.AggregateException: One or more errors occurred. (Method 'get_Timeout' in type 'Microsoft.OData.Extensions.Client.HttpClientRequestMessage' from assembly 'Microsoft.OData.Extensions.Client, Version=1.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.)
---> System.TypeLoadException: Method 'get_Timeout' in type 'Microsoft.OData.Extensions.Client.HttpClientRequestMessage' from assembly 'Microsoft.OData.Extensions.Client, Version=1.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
at Microsoft.OData.Extensions.Client.HttpClientODataClientHandler.<>c__DisplayClass4_0.b__0(DataServiceClientRequestMessageArgs args)
at Microsoft.OData.Client.RequestInfo.CreateRequestMessage(BuildingRequestEventArgs requestMessageArgs)
at Microsoft.OData.Client.ODataRequestMessageWrapper.CreateRequestMessageWrapper(BuildingRequestEventArgs requestMessageArgs, RequestInfo requestInfo)
at Microsoft.OData.Client.ODataMessageWritingHelper.CreateRequestMessage(BuildingRequestEventArgs requestMessageArgs)
at Microsoft.OData.Client.DataServiceRequest.CreateExecuteResult(Object source, DataServiceContext context, AsyncCallback callback, Object state, String method)
at Microsoft.OData.Client.DataServiceRequest.BeginExecute(Object source, DataServiceContext context, AsyncCallback callback, Object state, String method)
at Microsoft.OData.Client.DataServiceQuery1.BeginExecute(AsyncCallback callback, Object state) at Microsoft.OData.Client.DataServiceQuery1.BeginExecuteInternal(AsyncCallback callback, Object state)
at Microsoft.OData.Client.DataServiceQuery.BeginExecute(AsyncCallback callback, Object state)
at System.Threading.Tasks.TaskFactory1.FromAsyncImpl(Func3 beginMethod, Func2 endFunction, Action1 endAction, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory1.FromAsync(Func3 beginMethod, Func2 endMethod, Object state) at Microsoft.OData.Client.DataServiceQuery.ExecuteAsync() at SutureHealth.Shared.OData.ODataExtensions.ToListAsync[T](IQueryable1 queryable)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)

Migration does not handle datetimeoffset

The current code unfortunately does not translate filter expressions with datetimeoffset eg. $filter=Date ge datetimeoffset'2020-09-09T00:00:00Z'. If sending this it is passed forward as a literal string and fails in the v4 endpoint as datetimeoffset is unknown.

The problem can be fixed by extending QueryNodeTranslator.Visit(Data.OData.Query.SemanticAst.ConstantNode nodeIn) for example like this:
{ v => v is DateTimeOffset, v => ((DateTimeOffset)nodeIn.Value).UtcDateTime.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ssK", CultureInfo.InvariantCulture)

Since a number of classes for the tranlsations are internal it is not straightforward to use the package but override some methods.

Using OData Client and Extensions with .Net Blazor 8 WebAssembly

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);
        }

Support select clause with navigation properties translation to OData v4

Currently migration does not properly handle $select clause translation with navigation properties.

Eg.
host/Person?$expand=Address&$select=Name,Address/Street

is not translated to :

host/Person?$expand=Address($select=Street)&$select=Name

If Address and Person are EntityTypes than following error is returned by OData v4 API:

{ "error": { "code": "", "message": "The query specified in the URI is not valid. Found a path with multiple navigation properties or a bad complex property path in a select clause. Please reword your query such that each level of select or expand only contains either TypeSegments or Properties.", "innererror": { "message": "Found a path with multiple navigation properties or a bad complex property path in a select clause. Please reword your query such that each level of select or expand only contains either TypeSegments or Properties.", "type": "Microsoft.OData.ODataException", "stacktrace": " at Microsoft.OData.UriParser.SelectExpandBinder.ProcessSelectTokenPath(PathSegmentToken tokenIn)\r\n at Microsoft.OData.UriParser.SelectExpandBinder.GenerateSelectItem(SelectTermToken tokenIn)\r\n at Microsoft.OData.UriParser.SelectExpandBinder.Bind(ExpandToken expandToken, SelectToken selectToken)\r\n at Microsoft.OData.UriParser.SelectExpandSemanticBinder.Bind(ODataPathInfo odataPathInfo, ExpandToken expandToken, SelectToken selectToken, ODataUriParserConfiguration configuration, BindingState state)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseSelectAndExpandImplementation(String select, String expand, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseSelectAndExpand()\r\n at Microsoft.AspNet.OData.Query.Validators.SelectExpandQueryValidator.Validate(SelectExpandQueryOption selectExpandQueryOption, ODataValidationSettings validationSettings)\r\n at Microsoft.AspNet.OData.Query.SelectExpandQueryOption.Validate(ODataValidationSettings validationSettings)\r\n at Microsoft.AspNet.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n at Microsoft.AspNet.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.<>c__DisplayClass0_0.<OnActionExecuted>b__1(ODataQueryContext queryContext)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.ExecuteQuery(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, Func2 modelFunction, IWebApiRequestMessage request, Func2 createQueryOptionFunction)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.OnActionExecuted(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, IWebApiRequestMessage request, Func2 modelFunction, Func2 createQueryOptionFunction, Action1 createResponseAction, Action3 createErrorAction)" } } }

.NET Framework 4.8 : Could not load file or assembly 'Microsoft.OData.Extensions.Client.Abstractions' or one of its dependencies.

Reproduction steps

  • Create a new project ASP.NET Web Application (.NET Framework), using version 4.8
  • Select MVC template
  • Reference nuget package Microsoft.OData.Extensions.Client.Abstractions 1.0.6
  • Run the project with IIS Express

Excepected result

No error.

Result

Fatal error with this message :

Could not load file or assembly 'Microsoft.OData.Extensions.Client.Abstractions' or one of its dependencies. Strong name signature could not be verified.

Thanks for your help.

Unhandled exception in Blazor WebAssembly Project - .Net5 Preview 8

  1. Enabled Odata HTTPClient in Program.cs
    builder.Services.AddODataClient().AddHttpClient(httpClient);

  2. Calling Odata service In the Razor Component OnInitializedAsync Methos: (Odata Connected Service)

            var container= ClientFactory.CreateClient<DefaultContainer>(serviceRoot);
            var records = await container.Incidents.ExecuteAsync();

Below exception is thrown when navigating to the page:

blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Type Microsoft.OData.Extensions.Client.HttpClientRequestMessage has invalid vtable method slot 12 with method none
System.TypeLoadException: Type Microsoft.OData.Extensions.Client.HttpClientRequestMessage has invalid vtable method slot 12 with method none
   at Microsoft.OData.Extensions.Client.ODataClientBuilderExtensions.<>c__DisplayClass4_0.<AddHttpClient>b__0(DataServiceContext context)
   at Microsoft.OData.Extensions.Client.DelegatingODataClientHandler.OnClientCreated(ClientCreatedArgs args)
   at Microsoft.OData.Extensions.Client.DefaultODataClientFactory.OnClientCreated(ClientCreatedArgs args)
   at Microsoft.OData.Extensions.Client.DefaultODataClientFactory.CreateClient[DefaultContainer](Uri serviceRoot, String name)
   at Microsoft.OData.Extensions.Client.ODataClientFactoryExtensions.CreateClient[DefaultContainer](IODataClientFactory factory, Uri serviceRoot)
``
Odata Client Version 7.7.1
Orata Extension Version 1.0.2

Named client configuration is bugged

Hello,

My issue is based on this : https://docs.microsoft.com/en-us/odata/client/using-extensions#named-clients

We can create a custom client in Startup.cs

services.AddODataClient("TripPin")
    .ConfigureODataClient(dsc =>
    {
        dsc.BaseUri = new Uri("https://services.odata.org/v4/(S(lqbvtwide0ngdev54adgc0lu))/TripPinServiceRW/");

        // Github API versioning
        dsc.Configurations.Properties.Add("User-Agent", "ODataClientFactory-Sample"));
    });

But there are no way to create a client with only a Name property.
Constructors available are taking as parameters :
Uri serviceRoot, string name
Uri serviceRoot

We are missing an empty constructor and a constructor that takes only a Name to find related configuration.
ServiceRoot should not be mandatory in this constructor.

    [EnableQuery]
    public IEnumerable<Person> Get()
    {
        var client = _clientFactory.CreateClient<DefaultContainer>("TripPin"); << This doesn't exists
        var people = client.People.Execute();
        return people;
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.