odata / extensions Goto Github PK
View Code? Open in Web Editor NEWExtensionsLib: - Extensions for OData libraries and framework
License: MIT License
ExtensionsLib: - Extensions for OData libraries and framework
License: MIT License
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.
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
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.
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
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 Uri
s all over the place which would rely on constants, is a bad habit and somewhat defies the power of DI.
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).
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.DataServiceQuery
1.BeginExecuteInternal(AsyncCallback callback, Object state)
at Microsoft.OData.Client.DataServiceQuery.BeginExecute(AsyncCallback callback, Object state)
at System.Threading.Tasks.TaskFactory1.FromAsyncImpl(Func
3 beginMethod, Func2 endFunction, Action
1 endAction, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory1.FromAsync(Func
3 beginMethod, Func2 endMethod, Object state) at Microsoft.OData.Client.DataServiceQuery.ExecuteAsync() at SutureHealth.Shared.OData.ODataExtensions.ToListAsync[T](IQueryable
1 queryable)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
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.
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);
}
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, Func
2 modelFunction, IWebApiRequestMessage request, Func2 createQueryOptionFunction)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.OnActionExecuted(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, IWebApiRequestMessage request, Func
2 modelFunction, Func2 createQueryOptionFunction, Action
1 createResponseAction, Action3 createErrorAction)" } } }
No error.
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.
Enabled Odata HTTPClient in Program.cs
builder.Services.AddODataClient().AddHttpClient(httpClient);
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
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;
}
I have some trouble migrating my .net program to mono platform . Anything is ok when i run my program on mono,except for substringof keyword ,it does't work. Is Odata not compatible with mono platform? How can i fix the trouble, is there any compatible package?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.