Compare commits

...

15 Commits

Author SHA1 Message Date
Developer 02
137579bbcc chore: WindreamHub.Legacy.Client Paketversion auf 1.1.0 erhöht
- Paketversion von 1.0.0 auf 1.1.0 aktualisiert, um die neuen Änderungen widerzuspiegeln.
2024-09-13 15:39:56 +02:00
Developer 02
4aa696410c refactor: Generische Methoden für Rückgabetypen in DocumentsRouteService hinzugefügt
- Refaktorierte CreateAsync-, UploadAsync-, UpdateAsync-, DownloadAsync- und DeleteAsync-Methoden, um generische TData- und TError-Typen zu unterstützen.
- Dynamische Overloads für Create-, Upload-, Update-, Download- und Delete-Methoden hinzugefügt für flexible Anwendungsfälle.
- Methoden-Signaturen aktualisiert, um bessere Typinferenz und Handhabung verschiedener Rückgabetypen zu ermöglichen.
2024-09-13 14:38:09 +02:00
Developer 02
3be920c06a feat: Deserialize- und DeserializeList-Methoden zu ModelExtensions hinzufügen
- Hinzugefügt: Deserialize<T>- und Deserialize-Methoden für JSON-Deserialisierung.
- Hinzugefügt: DeserializeList-Methode zum Deserialisieren von JSON in eine IEnumerable<dynamic>.
2024-09-13 13:48:35 +02:00
Developer 02
4aa4a0add5 feat: DeleteAsync-Methode hinzufügen und Methodennamen mit 'Async'-Suffix refaktorisieren
- Hinzugefügt: DeleteAsync-Methode zur Handhabung der Dokumentenlöschung.
- Bestehende Methoden umbenannt, um 'Async'-Suffix für Konsistenz zu enthalten.
2024-09-13 13:46:17 +02:00
Developer 02
650f2c58d3 refactor: HTTP-Methoden umbenennen, um das Suffix 'Async' für asynchrone Operationen hinzuzufügen 2024-09-13 13:23:14 +02:00
Developer 02
8e367e89c4 feat: Fehler-Modelle für den Dokumentenlöschvorgang hinzugefügt 2024-09-13 13:15:58 +02:00
Developer 02
193c2c41cd chore: Projektdatei aktualisiert, um DeleteItem- und DocDeleteBody-Modelle einzuschließen 2024-09-13 12:08:31 +02:00
Developer 02
6ee87f8b02 feat: DeleteItem- und DocDeleteBody-Modelle für Dokumentenlöschanforderung erstellt 2024-09-13 12:06:57 +02:00
Developer 02
8249c99132 feat: Neue Update- und Download-Methoden zu DocumentsRouteService hinzugefügt 2024-09-13 12:04:35 +02:00
Developer 02
b1834c3417 refactor: DocCreateBody in DocBody umbenannt
- `DocCreateBody` in `DocBody` umbenannt, um den Code einfacher und klarer zu gestalten.
2024-09-13 11:27:27 +02:00
Developer 02
dc0cfd6010 refactor: Dokumenterstellungs-Modelle in den Request-Ordner verschoben
- Modelle von `Models/Documents/Create/Request` nach `Models/Documents/Request` verschoben, um eine bessere Organisation und Konsistenz zu gewährleisten.
2024-09-13 11:25:29 +02:00
Developer 02
18b3a7dfff feat: Flag-Enum für Dokumentoperationen eingeführt
- Ein `Flag`-Enum erstellt, um dokumentbezogene Operationen zu repräsentieren (z.B. `CreateObject`, `CheckIn` usw.).
- Die Verwendung von Integer-Flags in `DocumentsRouteService` durch das neue Enum ersetzt, um die Lesbarkeit und Wartbarkeit des Codes zu verbessern.
- Die `Upload`-Methode aktualisiert, um Flags als Array von `Flag`-Enum-Werten zu verarbeiten.
2024-09-13 11:18:24 +02:00
Developer 02
d9784115ce refactor: Bool-Typen in den Modellen auf bool? geändert 2024-09-13 09:44:20 +02:00
Developer 02
d0ae6c4541 feat: Methode "Upload" zur Dateiübertragung mit Abfrageparametern hinzugefügt
- Methode "Upload" für das Hochladen von Dateien hinzugefügt.
- Unterstützung für Abfrageparameter wie item_id, item_location, item_name, flags und stream_identity hinzugefügt.
- Methode auf MultipartFormDataContent für die Dateiverarbeitung aktualisiert.
2024-09-13 01:28:16 +02:00
Developer 02
e8cffa5fa0 refactor: Dokumenterstellungs-Modelle in den Create-Ordner verschoben 2024-09-13 00:55:06 +02:00
21 changed files with 190 additions and 31 deletions

View File

@ -7,9 +7,9 @@ namespace WindreamHub.Legacy.Client.Models.Authentication
public int? UserID { get; set; } public int? UserID { get; set; }
public string UserName { get; set; } public string UserName { get; set; }
public string FullUserName { get; set; } public string FullUserName { get; set; }
public bool IsValidUser { get; set; } public bool? IsValidUser { get; set; }
public ErrorDetails Error { get; set; } public ErrorDetails Error { get; set; }
public List<ErrorDetails> Errors { get; set; } public List<ErrorDetails> Errors { get; set; }
public bool HasErrors { get; set; } public bool? HasErrors { get; set; }
} }
} }

View File

@ -0,0 +1,13 @@
namespace WindreamHub.Legacy.Client.Models.Documents
{
public enum Flag
{
CreateObject = 1,
CheckIn = 2,
CreateNewVersion = 4,
UseDefaultLocation = 8,
ReturnIndexingDetails = 16,
ForceOverwrite = 32,
CreateTree = 64
}
}

View File

@ -0,0 +1,9 @@
namespace WindreamHub.Legacy.Client.Models.Documents.Request.Delete
{
public class DeleteItem
{
public int Id { get; set; }
public string Location { get; set; }
public string Name { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace WindreamHub.Legacy.Client.Models.Documents.Request.Delete
{
public class DocDeleteBody
{
public DeleteItem Item { get; set; }
public int Flags { get; set; }
public int ResponseDetails { get; set; }
}
}

View File

@ -1,9 +1,9 @@
namespace WindreamHub.Legacy.Client.Models.Documents.Request namespace WindreamHub.Legacy.Client.Models.Documents.Request
{ {
public class DocCreateBody public class DocBody
{ {
public Item Item { get; set; } public Item Item { get; set; }
public bool CreateFolder { get; set; } public bool? CreateFolder { get; set; }
public int? ResponseDetails { get; set; } public int? ResponseDetails { get; set; }
} }
} }

View File

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
namespace WindreamHub.Legacy.Client.Models.Documents.Request namespace WindreamHub.Legacy.Client.Models.Documents.Request
{ {

View File

@ -8,14 +8,14 @@
public int? Type { get; set; } public int? Type { get; set; }
public int? UnderlyingType { get; set; } public int? UnderlyingType { get; set; }
public string Column { get; set; } public string Column { get; set; }
public bool IsSystem { get; set; } public bool? IsSystem { get; set; }
public bool IsSortable { get; set; } public bool? IsSortable { get; set; }
public VectorDetails VectorDetails { get; set; } public VectorDetails VectorDetails { get; set; }
public TypeSpecificDetails TypeSpecificDetails { get; set; } public TypeSpecificDetails TypeSpecificDetails { get; set; }
public int? MaxSize { get; set; } public int? MaxSize { get; set; }
public bool AlwaysModifiable { get; set; } public bool? AlwaysModifiable { get; set; }
public int? PreDigits { get; set; } public int? PreDigits { get; set; }
public int? PostDigits { get; set; } public int? PostDigits { get; set; }
public bool IsFulltext { get; set; } public bool? IsFulltext { get; set; }
} }
} }

View File

@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace WindreamHub.Legacy.Client.Models.Documents.Response.Delete
{
public class DocDelErrorResponse
{
public ErrorDetail Error { get; set; }
public List<Error> Errors { get; set; }
public bool HasErrors { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace WindreamHub.Legacy.Client.Models.Documents.Response.Delete
{
public class ErrorDetail
{
public string Message { get; set; }
public int? ErrorCode { get; set; }
public int? Type { get; set; }
}
}

View File

@ -2,12 +2,12 @@
namespace WindreamHub.Legacy.Client.Models.Documents.Response namespace WindreamHub.Legacy.Client.Models.Documents.Response
{ {
public class DocCreatResponse public class DocResponse
{ {
public Item Item { get; set; } public Item Item { get; set; }
public IndexingDetails IndexingDetails { get; set; } public IndexingDetails IndexingDetails { get; set; }
public Error Error { get; set; } public Error Error { get; set; }
public List<Error> Errors { get; set; } public List<Error> Errors { get; set; }
public bool HasErrors { get; set; } public bool? HasErrors { get; set; }
} }
} }

View File

@ -2,6 +2,6 @@
{ {
public class IndexingDetails public class IndexingDetails
{ {
public bool IndexEventRequired { get; set; } public bool? IndexEventRequired { get; set; }
} }
} }

View File

@ -2,6 +2,6 @@
{ {
public class TypeSpecificDetails public class TypeSpecificDetails
{ {
public bool OnceEditable { get; set; } public bool? OnceEditable { get; set; }
} }
} }

View File

@ -5,6 +5,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Text; using System.Text;
using System.Collections.Generic;
namespace WindreamHub.Legacy.Client.Models namespace WindreamHub.Legacy.Client.Models
{ {
@ -94,7 +95,13 @@ namespace WindreamHub.Legacy.Client.Models
public static string Serialize(this object model) => JsonConvert.SerializeObject(model); public static string Serialize(this object model) => JsonConvert.SerializeObject(model);
public static HttpContent ToContent(this string json, Encoding encoding = null, string mediaType = "application/json") public static T Deserialize<T>(this string json) => JsonConvert.DeserializeObject<T>(json);
public static dynamic Deserialize(this string json) => JsonConvert.DeserializeObject<dynamic>(json);
public static IEnumerable<dynamic> DeserializeList(this string json) => JsonConvert.DeserializeObject<IEnumerable<dynamic>>(json);
public static HttpContent ToContent(this string json, Encoding encoding = null, string mediaType = "application/json")
=> new StringContent(json, encoding ?? Encoding.UTF8, mediaType); => new StringContent(json, encoding ?? Encoding.UTF8, mediaType);
public static HttpContent Stringify(this object model, Encoding encoding = null, string mediaType = "application/json") public static HttpContent Stringify(this object model, Encoding encoding = null, string mediaType = "application/json")

View File

@ -8,6 +8,6 @@
public object Errors { get; set; } public object Errors { get; set; }
public bool HasErrors { get; set; } public bool? HasErrors { get; set; }
} }
} }

View File

@ -14,7 +14,7 @@ namespace WindreamHub.Legacy.Client.Routes
{ {
} }
public async Task<SimplifiedResponse<ValidationResponse, object>> IsValidUser() public async Task<SimplifiedResponse<ValidationResponse, object>> IsValidUserAsync()
{ {
return await FetchAsync(route: "/IsValidUser", HttpMethod.Get).ThenAsync(res => res.Simplify<ValidationResponse, object>()); return await FetchAsync(route: "/IsValidUser", HttpMethod.Get).ThenAsync(res => res.Simplify<ValidationResponse, object>());
} }

View File

@ -6,6 +6,12 @@ using System.Threading.Tasks;
using WindreamHub.Legacy.Client.Models; using WindreamHub.Legacy.Client.Models;
using WindreamHub.Legacy.Client.Models.Documents.Response; using WindreamHub.Legacy.Client.Models.Documents.Response;
using WindreamHub.Legacy.Client.Models.Documents.Request; using WindreamHub.Legacy.Client.Models.Documents.Request;
using System.IO;
using System.Web;
using WindreamHub.Legacy.Client.Models.Documents;
using System.Linq;
using WindreamHub.Legacy.Client.Models.Documents.Response.Delete;
using WindreamHub.Legacy.Client.Models.Documents.Request.Delete;
namespace WindreamHub.Legacy.Client.Routes namespace WindreamHub.Legacy.Client.Routes
{ {
@ -15,12 +21,102 @@ namespace WindreamHub.Legacy.Client.Routes
{ {
} }
public async Task<SimplifiedResponse<DocCreatResponse, object>> Create(HttpContent docCreateBody) //Create
=> await FetchAsync(route: "/Create", method: HttpMethod.Post, body: docCreateBody) public async Task<SimplifiedResponse<TData, TError>> CreateAsync<TData, TError>(DocBody docCreateBody)
.ThenAsync(res => res.Simplify<DocCreatResponse, object>());
public async Task<SimplifiedResponse<DocCreatResponse, object>> Create(DocCreateBody docCreateBody)
=> await FetchAsync(route: "/Create", method: HttpMethod.Post, body: docCreateBody.Stringify()) => await FetchAsync(route: "/Create", method: HttpMethod.Post, body: docCreateBody.Stringify())
.ThenAsync(res => res.Simplify<DocCreatResponse, object>()); .ThenAsync(res => res.Simplify<TData, TError>());
public Task<SimplifiedResponse<dynamic, dynamic>> CreateDynamicAsync(DocBody docCreateBody) => CreateAsync<dynamic, dynamic>(docCreateBody);
public Task<SimplifiedResponse<DocResponse, DocResponse>> CreateAsync(DocBody docCreateBody) => CreateAsync<DocResponse, DocResponse>(docCreateBody);
//Upload
public async Task<SimplifiedResponse<TData, TError>> UploadAsync<TData, TError>(string path, long? item_id = null, string item_location = null, string item_name = null, object stream_identity = null, params Flag[] flags)
{
using (var fileStream = File.OpenRead(path))
{
var fileContent = new StreamContent(fileStream);
var formData = new MultipartFormDataContent
{
{ fileContent, "file" },
};
var query = HttpUtility.ParseQueryString(string.Empty);
if (item_id != null)
query["parameter.item.id"] = item_id.ToString();
if (item_location != null)
query["parameter.item.location"] = item_location;
if (item_name != null)
query["parameter.item.name"] = item_name;
if (flags != null && flags.Length > 0)
query["parameter.flags"] = string.Join(",", flags.Select(flag => (int)flag));
if (stream_identity != null)
query["parameter.stream.__identity"] = stream_identity.ToString();
return await FetchAsync(route: $"/Upload?{query}", method: HttpMethod.Post, body: fileContent).ThenAsync(res => res.Simplify<TData, TError>());
}
}
public Task<SimplifiedResponse<dynamic, dynamic>> UploadDynamicAsync(string path, long? item_id = null, string item_location = null, string item_name = null, object stream_identity = null, params Flag[] flags)
=> UploadAsync<dynamic, dynamic>(path: path, item_id: item_id, item_location: item_location, item_name: item_name, stream_identity: stream_identity, flags: flags);
public Task<SimplifiedResponse<DocResponse, DocResponse>> UploadAsync(string path, long? item_id = null, string item_location = null, string item_name = null, object stream_identity = null, params Flag[] flags)
=> UploadAsync<DocResponse, DocResponse>(path: path, item_id: item_id, item_location: item_location, item_name: item_name, stream_identity: stream_identity, flags: flags);
//Update
public async Task<SimplifiedResponse<TData, TError>> UpdateAsync<TData, TError>(DocBody docUpdateBody)
=> await FetchAsync(route: "/Update", method: HttpMethod.Post, body: docUpdateBody.Stringify())
.ThenAsync(res => res.Simplify<TData, TError>());
public Task<SimplifiedResponse<dynamic, dynamic>> UpdateDynamicAsync(DocBody docUpdateBody)
=> UpdateAsync<dynamic, dynamic>(docUpdateBody);
public Task<SimplifiedResponse<DocResponse, DocResponse>> UpdateAsync(DocBody docUpdateBody)
=> UpdateAsync<DocResponse, DocResponse>(docUpdateBody);
//Download
public async Task<SimplifiedResponse<TData, TError>> DownloadAsync<TData, TError>(long? item_id = null, string item_location = null, string item_name = null, object stream_identity = null, params Flag[] flags)
{
var query = HttpUtility.ParseQueryString(string.Empty);
if (item_id != null)
query["parameter.item.id"] = item_id.ToString();
if (item_location != null)
query["parameter.item.location"] = item_location;
if (item_name != null)
query["parameter.item.name"] = item_name;
if (flags != null && flags.Length > 0)
query["parameter.flags"] = string.Join(",", flags.Select(flag => (int)flag));
if (stream_identity != null)
query["parameter.stream.__identity"] = stream_identity.ToString();
return await FetchAsync(route: $"/Download?{query}", method: HttpMethod.Get).ThenAsync(res => res.Simplify<TData, TError>());
}
public Task<SimplifiedResponse<dynamic, dynamic>> DownloadDynamicAsync(long? item_id = null, string item_location = null, string item_name = null, object stream_identity = null, params Flag[] flags)
=> DownloadAsync<dynamic, dynamic>(item_id: item_id, item_location: item_location, item_name: item_name, stream_identity: stream_identity, flags: flags);
public Task<SimplifiedResponse<DocResponse, DocResponse>> DownloadAsync(long? item_id = null, string item_location = null, string item_name = null, object stream_identity = null, params Flag[] flags)
=> DownloadAsync<DocResponse, DocResponse>(item_id: item_id, item_location: item_location, item_name: item_name, stream_identity: stream_identity, flags: flags);
//Delete
public async Task<SimplifiedResponse<TData, TError>> DeleteAsync<TData, TError>(DocDeleteBody docDeleteBody)
=> await FetchAsync(route: "/Delete", HttpMethod.Post, body: docDeleteBody.Stringify())
.ThenAsync(res => res.Simplify<TData, TError>());
public async Task<SimplifiedResponse<dynamic, dynamic>> DeleteDynamicAsync(DocDeleteBody docDeleteBody)
=> await DeleteAsync<dynamic, dynamic>(docDeleteBody: docDeleteBody);
public async Task<SimplifiedResponse<DocResponse, DocDelErrorResponse>> DeleteAsync(DocDeleteBody docDeleteBody)
=> await DeleteAsync<DocResponse, DocDelErrorResponse>(docDeleteBody: docDeleteBody);
} }
} }

View File

@ -16,7 +16,7 @@ namespace WindreamHub.Legacy.Client.Route
{ {
} }
public async Task<SimplifiedResponse<SystemDetailsResponse, object>> GetSystemDetails() public async Task<SimplifiedResponse<SystemDetailsResponse, object>> GetSystemDetailsAsync()
=> await FetchAsync(route: "/GetSystemDetails") => await FetchAsync(route: "/GetSystemDetails")
.ThenAsync(res => res.Simplify<SystemDetailsResponse, object>()); .ThenAsync(res => res.Simplify<SystemDetailsResponse, object>());
} }

View File

@ -33,8 +33,8 @@ namespace WindreamHub.Legacy.Client
public async Task<bool> AuthenticateAsync(ICredential credential) public async Task<bool> AuthenticateAsync(ICredential credential)
{ {
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credential.AuthorizationHeader); _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credential.AuthorizationHeader);
var res = await Authentication.IsValidUser(); var res = await Authentication.IsValidUserAsync();
return res.Ok && res.Data.IsValidUser; return res.Ok && (res.Data.IsValidUser ?? false);
} }
public async Task<bool> AuthenticateAsync(string domain, string name, string password) public async Task<bool> AuthenticateAsync(string domain, string name, string password)

View File

@ -74,6 +74,7 @@
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath> <HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@ -84,6 +85,11 @@
<ItemGroup> <ItemGroup>
<Compile Include="DIExtensions.cs" /> <Compile Include="DIExtensions.cs" />
<Compile Include="Models\Authentication\ErrorDetails.cs" /> <Compile Include="Models\Authentication\ErrorDetails.cs" />
<Compile Include="Models\Documents\Flag.cs" />
<Compile Include="Models\Documents\Request\Delete\DeleteItem.cs" />
<Compile Include="Models\Documents\Request\Delete\DocDeleteBody.cs" />
<Compile Include="Models\Documents\Response\Delete\DocDelErrorResponse.cs" />
<Compile Include="Models\Documents\Response\Delete\ErrorDetail.cs" />
<Compile Include="Models\Documents\Response\Error.cs" /> <Compile Include="Models\Documents\Response\Error.cs" />
<Compile Include="Models\Shared\ErrorItem.cs" /> <Compile Include="Models\Shared\ErrorItem.cs" />
<Compile Include="Models\Authentication\ICredential.cs" /> <Compile Include="Models\Authentication\ICredential.cs" />
@ -92,9 +98,9 @@
<Compile Include="Models\Documents\Request\Attribute.cs" /> <Compile Include="Models\Documents\Request\Attribute.cs" />
<Compile Include="Models\Documents\Request\Item.cs" /> <Compile Include="Models\Documents\Request\Item.cs" />
<Compile Include="Models\Documents\Request\ObjectType.cs" /> <Compile Include="Models\Documents\Request\ObjectType.cs" />
<Compile Include="Models\Documents\Request\DocCreateBody.cs" /> <Compile Include="Models\Documents\Request\DocBody.cs" />
<Compile Include="Models\Documents\Response\Attribute.cs" /> <Compile Include="Models\Documents\Response\Attribute.cs" />
<Compile Include="Models\Documents\Response\DocCreatResponse.cs" /> <Compile Include="Models\Documents\Response\DocResponse.cs" />
<Compile Include="Models\Documents\Response\IndexingDetails.cs" /> <Compile Include="Models\Documents\Response\IndexingDetails.cs" />
<Compile Include="Models\Documents\Response\Item.cs" /> <Compile Include="Models\Documents\Response\Item.cs" />
<Compile Include="Models\Documents\Response\ObjectType.cs" /> <Compile Include="Models\Documents\Response\ObjectType.cs" />

View File

@ -2,7 +2,7 @@
<package> <package>
<metadata> <metadata>
<id>WindreamHub.Legacy.Client</id> <id>WindreamHub.Legacy.Client</id>
<version>1.0.0</version> <version>1.1.0</version>
<title>WindreamHub.Legacy.Client</title> <title>WindreamHub.Legacy.Client</title>
<authors>Digital Data GmbH</authors> <authors>Digital Data GmbH</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>

View File

@ -7,7 +7,7 @@
<package id="Microsoft.Extensions.Options" version="8.0.2" targetFramework="net462" /> <package id="Microsoft.Extensions.Options" version="8.0.2" targetFramework="net462" />
<package id="Microsoft.Extensions.Primitives" version="8.0.0" targetFramework="net462" /> <package id="Microsoft.Extensions.Primitives" version="8.0.0" targetFramework="net462" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net462" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net462" />
<package id="NuGet.CommandLine" version="6.10.1" targetFramework="net462" developmentDependency="true" /> <package id="NuGet.CommandLine" version="6.11.0" targetFramework="net462" developmentDependency="true" />
<package id="System.Buffers" version="4.5.1" targetFramework="net462" /> <package id="System.Buffers" version="4.5.1" targetFramework="net462" />
<package id="System.Memory" version="4.5.5" targetFramework="net462" /> <package id="System.Memory" version="4.5.5" targetFramework="net462" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net462" /> <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net462" />