{"id":37061318,"url":"https://github.com/dutchgrit/afasclient","last_synced_at":"2026-01-14T06:56:21.060Z","repository":{"id":88312625,"uuid":"241480328","full_name":"dutchgrit/afasclient","owner":"dutchgrit","description":"Source code, samples and documentation for the open-source DutchGrit.AfasClient library, a .NET Standard 2.0 library for the Afas REST API.","archived":false,"fork":false,"pushed_at":"2026-01-13T18:58:12.000Z","size":372,"stargazers_count":11,"open_issues_count":5,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-13T21:00:51.782Z","etag":null,"topics":["afas","dotnet","library"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dutchgrit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-02-18T22:22:33.000Z","updated_at":"2025-11-24T12:09:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"59c17c01-fd82-4837-a558-8fc582c6a48a","html_url":"https://github.com/dutchgrit/afasclient","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dutchgrit/afasclient","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dutchgrit%2Fafasclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dutchgrit%2Fafasclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dutchgrit%2Fafasclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dutchgrit%2Fafasclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dutchgrit","download_url":"https://codeload.github.com/dutchgrit/afasclient/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dutchgrit%2Fafasclient/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28412470,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["afas","dotnet","library"],"created_at":"2026-01-14T06:56:20.481Z","updated_at":"2026-01-14T06:56:21.041Z","avatar_url":"https://github.com/dutchgrit.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![nuget badge](https://img.shields.io/nuget/v/DutchGrit.AfasClient.svg)](https://www.nuget.org/packages/DutchGrit.AfasClient/)\n\n# Afas Client\nThe GitHub repository for the open-source DutchGrit.AfasClient library, a .NET Standard 2.0 library for the Afas REST API.\n\nThis repository contains the source code, documentation and some code samples on how to use the AfasClient library NuGet package listed as `DutchGrit.AfasClient`. \n\n\n## Getting started\n\n1. Make sure you have an AppConnector in Afas. Read the [Setup a AppConnector](Documentation/SetupAppConnector.MD).  \n2. Include the [DutchGrit.AfasClient](https://www.nuget.org/packages/DutchGrit.AfasClient/) NuGet package to your project.\n3. Generate your AppConnector specific GetConnector and UpdateConnector code with the [afas-cli](https://github.com/dutchgrit/afascli) tool.\n4. Happy coding!  \n\n## Code snippets\n\n### Setup the client object\n\n```cs\nvar client = new AfasClient(00000, \"YOUR FULL TOKEN KEY\");\n```\n\nBy default, the client will use the Production environment of Afas. You can also specify to use the Test (`Environments.Test`) or Acceptation (`Environments.Acceptation`) environments by initializing the AfasClient object with a different value.\n\n```cs\nvar client = new AfasClient(00000, \"YOUR FULL TOKEN KEY\", Environments.Test);\n```\n\n### Session information\n\n```cs\nvar session = await client.GetSessionInfoAsync();\nConsole.WriteLine($\"ConnectorName: {session.Info.ApplicationName}\");\nConsole.WriteLine($\"EnvironmentID: {session.Info.EnvironmentID}\");\nConsole.WriteLine($\"Group        : {session.Info.Group}\");\n``` \n\nThe session also holds the availabe Get- and UpdateConnectors as specified in the AppConnector.\n\n```cs\n            foreach (var conn in session.GetConnectors)\n            {\n                Console.WriteLine($\"{conn.Id} - {conn.Description}\");\n            }\n\n```\n\n### Quering data from Afas  \n\nThe AfasClient library's make it easier to use the Afas GetConnectors by providing typed results from a LINQ-like Query's. \n\n```cs\nvar invoices = await client.Query\u003cProfitDebtorInvoices\u003e()\n        .WhereEquals(x =\u003e x.UnitId, \"1\")\n        .WhereContains(x =\u003e x.Description, \"ABC\", \"BCD\", \"CDE\")\n        .Skip(50)\n        .Take(10)\n        .OrderBy(x =\u003e x.DebtorID)\n        .GetAsync();\n```\n\nIn the above code snippet, the `ProfitDebtorInvoices` is a generated class by the `afas-cli`. The class only exists if the corresponding GetConnector was included in your AppConnector definition.\n\nIt is possible to include one or more `Where*` clausules which will act as a AND filter. In this example, the `WhereContains` has multiple values specified which acts as an OR. Both the `Skip` and `Take` are included. You can retrieve all available records by specifying `Take(-1)`.  Sorting the result is done by `OrderBy` and `OrderByDesc` statements.  \n\nThe `WhereEquals` and `WhereContains` are only some samples of the complete filter options. Please see [Filter overview](Documentation/QueryFilters.md) for more filters. \n\n\n### Update data in Afas\n\nTo update data in Afas, you will need one of the UpdateConnectors and include it in your AppConnector. The `afas-cli` tool will generate the classes you need to update your data. \n\nThe page [UpdateConnectors](https://help.afas.nl/help/NL/SE/App_Conect_UpdDsc.htm) on the [help.afas.nl](https://help.afas.nl) website, shows an overview of all available updateconnectors.\n\nThe `session.UpdateConnectors` gives an overview of all the installed updateconnectors.\n\nAn example how to add a new organisation in Afas with the AfasClient library, assuming you have included the `KnOrganisation` UpdateConnector in your AppConnector.\n\n\n\n```cs\nvar org = new KnOrganisation()\n    {\n        AutoNum = false,\n        BcCo = \"1001\",\n        Nm = \"Test Organisation\",   //Name\n        SeNm = \"TEST\"              //Search name\n        ,...\n    };\n\nvar ba = new KnBankAccount()\n    { \n        //etc..etc..\n    };\n            \norg.AddKnBankAccount(ba);\n\n//save this object to afas\nvar res = await client.SaveAsync(org);\n\n//check result\nif (res.IsSuccess) {\n    //get the result object, could be a typed \n    //class or simply object\n    var x = res.Result;\n}\n```\n\nThe `client.SaveAsync(someobject)` will result in a http `POST` call and `client.UpdateAsync(someobject)` will result in a `PUT` call, which roughly corresponds to ADD and UPDATE operations. \n\nTo add/update a sub-parts of an object, please read the [Advanced save](Documentation/AdvancedSave.md) documentation.\n\n\n### Other functions\n\nThe AppConnectors can also be configured with special connectors, like: version, subject and report connectors.\n\n#### VersionConnector\n\nYou need the AppConnectorVersion 'connector' in your AppConnector defintion to use these methods. Please see the [setup](Documentation/SetupAppConnector.md) instructions.\n\n```cs\nvar version = await client.GetVersionAsync();\n```\n\u003e TIP: Most of the provided methods come in both sync and async version. For example: `GetVersionAsync()` and `GetVersion()`.\n\n#### FileConnector\n\n``` cs \nvar fileInfo = await client.GetFileAsync(\"..FileId..\",\"invoice001.pdf\");\n\n//GetFile returns null if not found. \nif (file!=null) \n {\n     //convert Base46 to bytes\n     var rawbytes = Convert.FromBase64String(fileInfo.FileDataBase64);\n     //save to disk\n     System.IO.File.WriteAllBytes(fileInfo.FileName, rawbytes);\n }\n```\n\n#### ImageConnector\n\nSample usage of the imageConnector. \n\n``` cs\n\n//request image with id 10001\nvar imageInfo = await client.GetImageAsync(10001, ImageSizes.Medium);\n\n//info object holds \nif (imageInfo.IsNotFound) { ... }\n\nif (imageInfo.MimeType == 'image/jpg') { ... }\n\nvar rawbytes = Convert.FromBase64String(imageInfo.FileDataBase64);\n\n```\n\n#### Other connectors\n\nThe other connectors are not implemented (yet). \nPlease leave a request if you need the `Report` connector.  \n\n### OTP Client\n\nWhen developing afas application, you can choose to work with ONE token for the whole application, or per-user token. \nThe per-user token scenario requires a way to request tokens with the OTP client. \n\nTo request a token you need:\n- API key and Environment key of the AppConnector.\n- The users emailadress or \n\nThe process requires two steps\n#### OTP request and validate process\n\n``` cs\nvar otpclient  = new AfasOtpClient( 12345, \"api-key\", \"environment-key\" );\n\n//Request the otp valdiation code, which is send by mail by Afas.\nawait otpclient.GetOtpTokenRequest(\"john@somecompany.ext\"); \n\n//Assume you received validation code 123456 by mail, you can request a token. \nvar token = await otpclient.GetOtpTokenValidation(\"john@somecompany.ext\", \"123456\";)\n\n``` \n\n### Debugging\nSee the [tracing](Documentation/Tracing.MD) option for monitoring and debugging the actual requests performed.\nFeel free to report any bugs or missing features.\n\n### Got feedback or ideas?\n[File an issue](https://github.com/dutchgrit/afasclient/issues) and tell us what you want to change, add, or what doesn't work for you if that's the case. All issues are welcome, from improvements to bugs!\n\n### Want to contribute?\nIf you want to contribute to the AfasClient project, a great place to start would be the project's 'Issues' tab! You can also contribute by creating bug reports, try playing around with the client and see if you find any problems. If so, make an issue!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdutchgrit%2Fafasclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdutchgrit%2Fafasclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdutchgrit%2Fafasclient/lists"}