gehnster / evestandard Goto Github PK
View Code? Open in Web Editor NEWA C# library for accessing the EVE Online ESI API. This library is .NET Standard compatible.
License: MIT License
A C# library for accessing the EVE Online ESI API. This library is .NET Standard compatible.
License: MIT License
Hi,
I am trying to build an Winforms app, but when I run it, it throws an exception:
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
at EVEStandard.API.Alliance..ctor(String dataSource)
at EVEStandard.EVEStandardAPI.initializeAPI()
at EVEStandard.EVEStandardAPI..ctor(String userAgent, DataSource dataSource, TimeSpan timeOut)
at EVEStandard.EVEStandardAPI..ctor(String userAgent, DataSource dataSource, TimeSpan timeOut, String callbackUri, String clientId, String secretKey)
at xxxESI.SSO.TestEVEStandard() in xxxx
at xxx.Form1.Button1_Click(Object sender, EventArgs e) in xxx
LOG: This bind starts in default load context.
LOG: Using application configuration file: xxxx.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
LOG: Attempting download of new URL file:///xxx/Microsoft.Extensions.Logging.Abstractions.DLL.
LOG: Attempting download of new URL file:///xxxx/Microsoft.Extensions.Logging.Abstractions/Microsoft.Extensions.Logging.Abstractions.DLL.
LOG: Attempting download of new URL file:///xxxxx/Microsoft.Extensions.Logging.Abstractions.EXE.
LOG: Attempting download of new URL file:///xxxx/Microsoft.Extensions.Logging.Abstractions/Microsoft.Extensions.Logging.Abstractions.EXE.
I am missing the 'Microsoft.Extensions.Logging.Abstractions' library. When I try to add it to the project from NuGet I got various problems, like wrong .NET Framework and etc.
Can you remove this dependency? I have my own logging system and tons of references in the EVEStandard library does not help at all.
Off topic: can you make a sample Winforms app which covers the SSO?
thanks
Since Eve Application Secret Key's are not used when using the PKCE protocol for authentication, it seems like the SSOv2 class should not throw an ArgumentNullException if a Secret Key is not provided.
Repro steps
var sso = new SSOv2(DataSource.Tranquility, "http://localhost/callback", "MyEVEAppClientId", null);
Figure out a decent design for how to handle the lastest/legacy/dev labels for ESI. Individual endpoints will ALWAYS reference versioned endpoints but users should still be able to use either the labels when initializing the EVEStandardAPI class or different versioned endpoints based on their current needs.
GetHashCode() throws a null ref exception if any Property on a ModelBase object has a Null value.
Given that subclasses of ModelBase can be initialized with null values for their properties, GetHashCode() should not include null properties in it's calculation.
var marketOrder = new EVEStandard.Models.MarketOrder();
marketOrder.GetHashCode(); // Throws exception
Add comments to both classes that should explain the process required to use the basics of the API. If examples in the XML comments would be too long, then reference the readme file in GitHub where you can show examples on how to use the library within an ASP.NET Core app and a Windows Desktop app.
Change to HttpClientFactory
Change decompression for http client to be automatic. Change it for all http clients.
Better handle query parameters. Currently just handling datasource but need to also account for things like pages and x-page.
Need to put additional thought into how we handle logging and exceptions. Do we want to do any logging? How should we handle it? Do we just want to allow the app to throw everything up without logging and have the user handle it? A combination of both? What should be considered an exception and what should we just log? Do we need more types of exceptions?
The image server has changed a bit and should be updated.
https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
Looks like contract id is int in some places and long in others. Make them consistent.
Contracts.GetCorporationContractItemsV1Async
and
UserInterface.OpenContractWindowV1Async
are two examples
CharacterInfo call takes characterId as long but returns characterInfo.characterId as int.
Same for alliance and corporations. Queries require long but the characterinfo returns ints.
Great library by the way.
var responseModel = await GetAsync($"/v3/corporations/{corpId}/wallet/{division}/journal/", auth, ifNoneMatch, queryParameters);
should be
var responseModel = await GetAsync($"/v3/corporations/{corpId}/wallets/{division}/journal/", auth, ifNoneMatch, queryParameters);
(Missing an s in wallets)
Same for GetCorporationWalletTransactionsV1Async() and this should probably be renamed to V3 :)
Add the image server to the library. http://eveonline-third-party-documentation.readthedocs.io/en/latest/imageserver/index.html
This happens on the callback when I call esiClient.SSO.GetCharacterDetailsAsync(accessToken.AccessToken);
I don't know if it's a good idea to post the access token here, it seems that whatever comes back from /oauth/verify can't be decoded, maybe it's an error?
I got the library from nuget
EDIT: Doesn't happen with the source, well I guess that's already fixed then
I'll be trying out some more debugging with the source, in the meantime here's the stacktrace:
JsonReaderException: Unexpected character encountered while parsing value: �. Path '', line 0, position 0.
Newtonsoft.Json.JsonTextReader.ParseValue()
EVEStandardException: An error occured with some part of the http request/response
EVEStandard.SSO.GetCharacterDetailsAsync(string accessToken)
Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: �. Path '', line 0, position 0.
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonTextReader.Read()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at EVEStandard.SSO.GetCharacterDetailsAsync(String accessToken)
EVEStandard.EVEStandardException: An error occured with some part of the http request/response ---> Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: �. Path '', line 0, position 0.
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonTextReader.Read()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at EVEStandard.SSO.GetCharacterDetailsAsync(String accessToken)
--- End of inner exception stack trace ---
at EVEStandard.SSO.GetCharacterDetailsAsync(String accessToken)
at EVEStandard.ASPNETCoreSample.Controllers.AuthController.Callback(String code, String state) in C:\Users\Maddo\Source\Repos\EVEStandard-Examples\EVEStandard.ASPNETCoreSample\Controllers\AuthController.cs:line 69
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at System.Threading.Tasks.ValueTask`1.get_Result()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)```
Calling this method results in an exception similar to the following: "Error converting value "bounty-missions" to type 'EVEStandard.Enumerations.ServicesEnum'."
It doesn't seem like the services returned from ESI are mapping to the enumeration, this might be complicated by the hyphens included in the response.
Logging doesn't seem to be working for the library. Need to find a good strategy to get it working.
Hi,
I noticed that according to the ESI https://esi.evetech.net/ui/#/Industry/get_characters_character_id_industry_jobs, OutputlocationId is an int64, but you have it as a long https://github.com/gehnster/EVEStandard/blob/master/EVEStandard/Models/IndustryJob.cs
I am a noob, so there's a good chance I am missing something. Would you please let me know what? :D
Thanks!
I had problems the helper not starting or not able to register the callback protocol due to permissions.
i think that you can use async task, which invokes an async httplistener just before starting the browser and await it to finish after the user submits the callback.
an await.whenany with task.delay could be used to continue operation after some timeout in order not to block the app if something goes wrong with user submitting data
I will be able to post my code tomorrow if you want to check it out.
Update the package and dependencies to .NET Standard 2.1
Figure out what it is and how to use it.
This property doesn't make sense to be nullable. If there is no unallocated SP the value should be zero. In addition, all the skillpoint properties should probably be int
since it's not possible to have more SP than an int
can represent.
Could you give an simple example of an MVC app with SSO login&
I have noticed a bug sometimes when the expected state has plus symbols (+) they are stripped out by ESI and when the state is returned it doesn't match the expected state. At which point fails the state check.
Says it. Want a branch that auto builds and pushes to NuGet for people to use. Also want some more git branches for development so we can have some clean branches for builds and a dev branch.
I'm struggling to work out how to handle the callback when performing SSO.
I'm having a hard time figuring out the best way to handle state, at least in an ASP.NET application. Is it something that the library itself should support and check in the callback or is it something that should be handled by the application using the library. If its a desktop application it seems easy enough to know how to handle State, and if the user doesn't check it properly then so be it. But how to handle it in an ASP.NET application is another matter.
The deserialiser is incorrectly interpreting the ID values in the wallet journal as 32 bit integers, this means journals cannot be read if the id would exceed the max safe Int32 value. Which it often does.
JSON integer 5017602413 is too large or small for an Int32. Path '[1].context_id', line 1, position 282.
Instead, it should use the long type.
Add http status codes that ESI looks to return but are currently missing because .NET doesn't suppor them in the HttpStatusCodes enum.
Change the code to better support the expires and last modified headers. Currently it just tries to parse the data without any concern for the actual data coming in or if there are multiple header values for it.
Hello,
I get an exception when trying to fetch contracts for a corporation.
System.ArgumentException: Requested value 'public' was not found.
at Newtonsoft.Json.Utilities.EnumUtils.ParseEnum(Type enumType, String value, Boolean disallowNumber)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
Newtonsoft.Json.JsonSerializationException: Error converting value "public" to type 'EVEStandard.Models.Contract+AvailabilityEnum'. Path '[0].availability', line 1, position 64. ---> System.ArgumentException: Requested value 'public' was not found.
at Newtonsoft.Json.Utilities.EnumUtils.ParseEnum(Type enumType, String value, Boolean disallowNumber)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
--- End of inner exception stack trace ---
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
at EVEStandard.API.APIBase.ReturnModelDTO[T](APIResponse response)
at EVEStandard.API.Contracts.GetCorporationContractsV1Async(AuthDTO auth, Int32 corporationId, Int32 page, String ifNoneMatch)
[...]
System.Text.Json.JsonException: The JSON value could not be converted to EVEStandard.Models.Contract+TypeEnum. Path: $[0].type | LineNumber: 0 | BytePositionInLine: 317.
at System.Text.Json.ThrowHelper.ThrowJsonException(String message)
at System.Text.Json.Serialization.Converters.EnumConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at EVEStandard.API.APIBase.ReturnModelDTO[T](APIResponse response) in D:\Development Work\PodLabs.Contract.Searcher\EVEStandard\EVEStandard\API\APIBase.cs:line 276
at EVEStandard.API.Contracts.GetPublicContractsV1Async(Int32 regionId, Int32 page, String ifNoneMatch) in D:\Development Work\PodLabs.Contract.Searcher\EVEStandard\EVEStandard\API\Contracts.cs:line 104
at Program.<>c__DisplayClass0_0.<<<Main>$>g__GetContractPage|2>d.MoveNext() in D:\Development Work\PodLabs.Contract.Searcher\PodLabs.Contract.Searcher\Program.cs:line 47
--- End of stack trace from previous location ---
at Program.<>c__DisplayClass0_0.<<<Main>$>g__GetContracts|1>d.MoveNext() in D:\Development Work\PodLabs.Contract.Searcher\PodLabs.Contract.Searcher\Program.cs:line 35
--- End of stack trace from previous location ---
at Program.<Main>$(String[] args) in D:\Development Work\PodLabs.Contract.Searcher\PodLabs.Contract.Searcher\Program.cs:line 15
at Program.<Main>(String[] args)
Looks like I am only dealing with some of the error headers being returned by ESI, I need to handle all of them. ref: https://developers.eveonline.com/blog/article/error-limiting-imminent
Take a look at Polly. https://github.com/App-vNext/Polly
Might help with retrying and caching strategies for ESI, if it can do it per-route.
Make sure you write JSON Properties for each model property.
Probably an low priority improvement, but the AuthDTO model is too complex and difficult to compose between requests. It's easy to use in the same request as the callback but composing it in other requests from saved token is awkward, especially that most calls just a couple of properties contained in the DTO.
Accessing the ESI API itself and using SSO are independent items. One app might just need SSO for authentication while another might just need the public ESI endpoints. Because of this I've decided to have the SSO class be able to be used independently from the EVEStandardAPI class, which is where all API calls will be accessed from. My goal is to have any function within the EVEStandardAPI that needs the SSO data to actually required the SSO class be a function argument, perhaps bundled with a POCO containing class data.
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.