{"id":26103307,"url":"https://github.com/constructor-io/constructorio-netcore","last_synced_at":"2026-02-10T20:16:58.933Z","repository":{"id":62226987,"uuid":"319750082","full_name":"Constructor-io/constructorio-netcore","owner":"Constructor-io","description":"A .NET Core REST client for the Constructor.io API","archived":false,"fork":false,"pushed_at":"2025-03-04T17:35:06.000Z","size":1923,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":24,"default_branch":"main","last_synced_at":"2025-04-12T17:22:42.548Z","etag":null,"topics":["constructorio","constructorio-integrations","dotnet","netcore"],"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/Constructor-io.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}},"created_at":"2020-12-08T20:14:10.000Z","updated_at":"2025-03-04T17:35:09.000Z","dependencies_parsed_at":"2024-02-02T12:32:15.573Z","dependency_job_id":"db92254a-8d0e-4e61-95c8-5b35157ba038","html_url":"https://github.com/Constructor-io/constructorio-netcore","commit_stats":null,"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constructor-io%2Fconstructorio-netcore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constructor-io%2Fconstructorio-netcore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constructor-io%2Fconstructorio-netcore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constructor-io%2Fconstructorio-netcore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Constructor-io","download_url":"https://codeload.github.com/Constructor-io/constructorio-netcore/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248602736,"owners_count":21131684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["constructorio","constructorio-integrations","dotnet","netcore"],"created_at":"2025-03-09T20:06:12.101Z","updated_at":"2026-02-10T20:16:58.925Z","avatar_url":"https://github.com/Constructor-io.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Constructor.io Netcore Client\n\n[Constructor.io](http://constructor.io/) provides search as a service that optimizes results using artificial intelligence (including natural language processing, re-ranking to optimize for conversions, and user personalization).\n\n# Documentation\n\nFull API documentation is available on [Github Pages](https://constructor-io.github.io/constructorio-netcore/)\n\n# Requirements\n\nRequesting results from your .NET based back-end can be useful in order to control result rendering logic on your server, or augment/hydrate results with data from another system. However, a back-end integration has additional requirements compared to a front-end integration. Please review the [Additional Information For Backend Integrations](https://github.com/Constructor-io/constructorio-netcore/wiki/Additional-Information-for-Backend-Integrations) article within the wiki for more detail.\n\n# Installation\n\n1. Follow the directions at [Nuget](https://www.nuget.org/packages/constructor.io/) to add the package to your project.\n2. Retrieve your API token and key.  You can find this at your [Constructor.io dashboard](https://constructor.io/dashboard).\n3. Create a new instance of the client.\n\n## Basic Usage\n\n```csharp\nConstructorioConfig config = new ConstructorioConfig(\"apiKey\", \"apiToken\");\nConstructorIO constructorio = new ConstructorIO(config);\n```\n\n## Using with IHttpClientFactory\n\n```csharp\nservices.AddHttpClient();\n\n// Register your ConstructorioConfig\nservices.AddSingleton(new ConstructorioConfig(\"apiKey\", \"apiToken\"));\n\n// Register ConstructorIO with custom HttpClient\nservices.AddScoped\u003cConstructorIO\u003e(serviceProvider =\u003e\n{\n    var config = serviceProvider.GetRequiredService\u003cConstructorioConfig\u003e();\n    var httpClient = serviceProvider.GetRequiredService\u003cIHttpClientFactory\u003e().CreateClient();\n    config.HttpClient = httpClient;\n\n    return new ConstructorIO(config);\n});\n```\n\n# Uploading a Catalog\n\nTo upload your product catalog, you will need to create a `CatalogRequest`.  In this request, you can specify the files you want to upload (items, variations, and item groups) and the section you want to send the upload.  You can also set a notification e-mail to be alerted when a file ingestion fails.\n\n```csharp\n// Create a files dictionary and add the relevant files\nStreamContent itemsStream = new StreamContent(File.OpenRead(\"./catalog/items.csv\"));\nitemsStream.Headers.ContentType = new MediaTypeHeaderValue(\"text/csv\");\nStreamContent variationsStream = new StreamContent(File.OpenRead(\"./catalog/variations.csv\"));\nvariationsStream.Headers.ContentType = new MediaTypeHeaderValue(\"text/csv\");\nStreamContent itemGroupsStream = new StreamContent(File.OpenRead(\"./catalog/item_groups.csv\"));\nitemGroupsStream.Headers.ContentType = new MediaTypeHeaderValue(\"text/csv\");\n\nDictionary\u003cstring, StreamContent\u003e files = new Dictionary\u003cstring, StreamContent\u003e()\n{\n    { \"items\", itemsStream },\n    { \"variations\", variationsStream },\n    { \"item_groups\", itemGroupsStream },\n};\n\n// Create a CatalogRequest with files to upload and the section to upload to\nCatalogRequest request = new CatalogRequest(files);\nrequest.Section = \"Products\";\n\n// Set a notification e-mail\nrequest.NotificationEmail = \"integration@company.com\";\n\n// Set the force flag if the catalog should be processed even if it will invalidate a large number of existing items\nrequest.Force = true;\n\n// Send a request to replace the catalog (sync)\nCatalogResponse response = await constructorio.Catalog.ReplaceCatalog(request);\n```\n\n# Retrieving Autocomplete Results\n\nTo retrieve autocomplete results, you will need to create an `AutocompleteRequest`. In this request you can specify the number of results you want per autocomplete section.  If the results are for a specific user, you can also create a `UserInfo` object, which will allow you to retrieve personalized results.\n\n```csharp\n// Create an AutocompleteRequest with the term to request results for\nAutocompleteRequest request = new AutocompleteRequest(\"rain coat\");\n\n// Define the number of results to show per section\nrequest.ResultsPerSection = new Dictionary\u003cstring, int\u003e\n{\n    { \"Products\", 6 },\n    { \"Search Suggestions\", 8 },\n};\n\n// Create a UserInfo object with the unique device identifier and session\nUserInfo userInfo = new UserInfo(\"device-id-1123123\", 5);\nrequest.UserInfo = userInfo;\n\n// Add a variations map to request specific variation attributes as an array or object (optional)\nVariationsMap variationsMap = new VariationsMap();\nvariationsMap.AddGroupByRule(\"url\", \"data.url\");\nvariationsMap.AddValueRule(\"variation_id\", AggregationTypes.First, \"data.variation_id\");\nvariationsMap.AddValueRule(\"deactivated\", AggregationTypes.First, \"data.deactivated\");\nrequest.VariationsMap = variationsMap;\n\n// Request results as an object\nAutocompleteResponse response = await constructorio.Autocomplete.GetAutocompleteResults(request);\n```\n\n# Retrieving Search Results\n\nTo retrieve search results, you will need to create a `SearchRequest`. In this request you can specify the number of results you want per page, the page you want, sorting instructions, and also filter the results by category or facets. If the results are for a specific user, you can also create a `UserInfo` object, which will allow you to retrieve personalized results.\n\n```csharp\n// Create a SearchRequest with the term to request results for\nSearchRequest request = new SearchRequest(\"peanut butter\");\n\n// Add in additional parameters\nrequest.ResultsPerPage = 5;\nrequest.Page = 1;\nrequest.SortBy = \"Price\";\nrequest.Filters = new Dictionary\u003cstring, List\u003cstring\u003e\u003e()\n{\n    { \"Brand\", new List\u003cstring\u003e() { \"Jif\" } }\n};\n\n// Add the following paramaters to request for hidden fields\nrequest.HiddenFields = new List\u003cstring\u003e\n{\n    \"hidden_price_field\",\n    \"hidden_brand_field\",\n};\n\n// Add the following paramaters to request for hidden facets\nrequest.HiddenFacets = new List\u003cstring\u003e\n{\n    \"hidden_price_facet\",\n    \"hidden_brand_facet\",\n};\n\n// Create a UserInfo object with the unique device identifier and session\nUserInfo userInfo = new UserInfo(\"device-id-1123123\", 5);\nrequest.UserInfo = userInfo;\n\n// Add a variations map to request specific variation attributes as an array or object (optional)\nVariationsMap variationsMap = new VariationsMap();\nvariationsMap.AddGroupByRule(\"url\", \"data.url\");\nvariationsMap.AddValueRule(\"variation_id\", AggregationTypes.First, \"data.variation_id\");\nvariationsMap.AddValueRule(\"deactivated\", AggregationTypes.First, \"data.deactivated\");\nrequest.VariationsMap = variationsMap;\n\n// Faceting expression to scope results, it is applied before other filters and doesn't affect facet counts\nstring preFilterExpressionJObject = @\"{\n    or: [\n        {\n        and:\n            [\n            { name: 'group_id', value: 'BrandXY' },\n            { name: 'Color', value: 'red' },\n        ],\n        },\n        {\n        and:\n            [\n            { name: 'Color', value: 'blue' },\n            { name: 'Brand', value: 'XYZ' },\n        ],\n        },\n    ],\n}\";\nJsonPrefilterExpression preFilterExpression = new JsonPrefilterExpression(preFilterExpressionJObject);\nrequest.PreFilterExpression = preFilterExpression;\n\n// Request results as an object\nSearchResponse response = await constructorio.Search.GetSearchResults(request);\n```\n\n# Retrieving Browse Results\n\nTo retrieve browse results, you will need to create a `BrowseRequest`. When creating the `BrowseRequest` the filter name can be one of `collection_id`, `group_id`, or a facet name (i.e. Brand). In this request, you can also specify the number of results you want per page, the page you want, sorting instructions, and also filter the results by category or facets. If the results are for a specific user, you can also create a `UserInfo` object, which will allow you to retrieve personalized results.\n\n```csharp\n// Create a BrowseRequest with the filter name and filter value to request results for\nBrowseRequest request = new BrowseRequest(\"group_id\", \"8193\");\n\n// Add in additional parameters\nrequest.ResultsPerPage = 5;\nrequest.Page = 1;\nrequest.SortBy = \"Price\";\nrequest.Filters = new Dictionary\u003cstring, List\u003cstring\u003e\u003e()\n{\n    { \"Brand\", new List\u003cstring\u003e() { \"Jif\" } }\n};\n\n// Add the following paramaters to request for hidden fields\nrequest.HiddenFields = new List\u003cstring\u003e\n{\n    \"hidden_price_field\",\n    \"hidden_brand_field\",\n};\n\n// Add the following paramaters to request for hidden facets\nrequest.HiddenFacets = new List\u003cstring\u003e\n{\n    \"hidden_price_facet\",\n    \"hidden_brand_facet\",\n};\n\n// Create a UserInfo object with the unique device identifier and session\nUserInfo userInfo = new UserInfo(\"device-id-1123123\", 5);\nrequest.UserInfo = userInfo;\n\n// Add a variations map to request specific variation attributes as an array or object (optional)\nVariationsMap variationsMap = new VariationsMap();\nvariationsMap.AddGroupByRule(\"url\", \"data.url\");\nvariationsMap.AddValueRule(\"variation_id\", AggregationTypes.First, \"data.variation_id\");\nvariationsMap.AddValueRule(\"deactivated\", AggregationTypes.First, \"data.deactivated\");\nrequest.VariationsMap = variationsMap;\n\n// Faceting expression to scope results, it is applied before other filters and doesn't affect facet counts\nstring preFilterExpressionJObject = @\"{\n    or: [\n        {\n        and:\n            [\n            { name: 'group_id', value: 'BrandXY' },\n            { name: 'Color', value: 'red' },\n        ],\n        },\n        {\n        and:\n            [\n            { name: 'Color', value: 'blue' },\n            { name: 'Brand', value: 'XYZ' },\n        ],\n        },\n    ],\n}\";\nJsonPrefilterExpression preFilterExpression = new JsonPrefilterExpression(preFilterExpressionJObject);\nrequest.PreFilterExpression = preFilterExpression;\n\n// Request results as an object\nBrowseResponse response = await constructorio.Browse.GetBrowseResults(request);\n```\n\n# Retrieving Browse Results for Item ID's\n\nTo retrieve browse results for a supplied list of item ID's, you will need to create a `BrowseItemsRequest`. When creating the `BrowseItemsRequest` the `itemIds` parameter will be a list of item ID's. In this request, you can also specify the number of results you want per page, the page you want, sorting instructions, and also filter the results by category or facets. If the results are for a specific user, you can also create a `UserInfo` object, which will allow you to retrieve personalized results.\n\n```csharp\n// Create a BrowseItemsRequest with the filter name and filter value to request results for\nBrowseItemsRequest request = new BrowseItemsRequest(Arrays.asList(\"t-shirt-xxl\"));\n\n// Add in additional parameters\nrequest.ResultsPerPage = 5;\nrequest.Page = 1;\nrequest.SortBy = \"Price\";\nrequest.Filters = new Dictionary\u003cstring, List\u003cstring\u003e\u003e()\n{\n    { \"Brand\", new List\u003cstring\u003e() { \"Jif\" } }\n};\n\n// Add the following paramaters to request for hidden fields\nrequest.HiddenFields = new List\u003cstring\u003e\n{\n    \"hidden_price_field\",\n    \"hidden_brand_field\",\n};\n\n// Add the following paramaters to request for hidden facets\nrequest.HiddenFacets = new List\u003cstring\u003e\n{\n    \"hidden_price_facet\",\n    \"hidden_brand_facet\",\n};\n\n// Create a UserInfo object with the unique device identifier and session\nUserInfo userInfo = new UserInfo(\"device-id-1123123\", 5);\nrequest.UserInfo = userInfo;\n\n// Request results as an object\nBrowseResponse response = await constructorio.Browse.GetBrowseItemsResults(request);\n```\n\n# Retrieving Recommendation Results\n\nTo retrieve recommendation results, you will need to create a `RecommendationsRequest`. In this request, you can also specify the number of results you want and the items (given the ids) that you want to retrieve recommendations for. If the results are for a specific user, you can also create a `UserInfo` object, which will allow you to retrieve personalized results.\n\n```csharp\n// Create a RecommendationsRequest with the pod id to request results for\nRecommendationsRequest request = new RecommendationsRequest(\"pdp_complementary_items\");\n\n// Add in additional parameters\nrequest.NumResults = 5;\nrequest.ItemIds = new List\u003cstring\u003e { \"9838172\" };\n\n// Optionally, set variation IDs to use as seeds for recommendations (requires item IDs)\nrequest.VariationIds = new List\u003cstring\u003e { \"variation_123\", \"variation_456\" };\n\n// Create a UserInfo object with the unique device identifier and session\nUserInfo userInfo = new UserInfo(\"device-id-1123123\", 5);\nrequest.UserInfo = userInfo;\n\n// Add a variations map to request specific variation attributes as an array or object (optional)\nVariationsMap variationsMap = new VariationsMap();\nvariationsMap.AddGroupByRule(\"url\", \"data.url\");\nvariationsMap.AddValueRule(\"variation_id\", AggregationTypes.First, \"data.variation_id\");\nvariationsMap.AddValueRule(\"deactivated\", AggregationTypes.First, \"data.deactivated\");\nrequest.VariationsMap = variationsMap;\n\n// Request results as an object\nRecommendationsResponse response = await constructorio.Recommendations.GetRecommendationsResults(request);\n```\n\n# Retrieving All Tasks\n\nTo retrieve all tasks, you will need to create a `AllTasksRequest`. In this request you can also specify the page and number of results per page. The page and number of results per page will default to 1 and 20 respectively.\n\n```csharp\n// Create a AllTasksRequest to request results for\nAllTasksRequest request = new AllTasksRequest();\n\n// Add in additional parameters\nrequest.Page = 2;\nrequest.ResultsPerPage = 10;\n\n//Request all tasks as an object\nAllTasksResponse response = await constructorio.Tasks.GetAllTasks(request);\n```\n\n# Retrieving Task with Task ID\n\nTo retrieve a specific task with a task_id, you will need to create a `TaskRequest`.\n\n```csharp\n// Create a TaskRequest with the task_id to retrieve\nTaskRequest request = new TaskRequest(\"12345\");\n\n//Request task as an object\nTask response = await constructorio.Tasks.GetTask(request);\n```\n\n# Development\n## Using VS Code\n- Download \".NET Core Test Explorer\" Extension\n- In settings =\u003e .NET Core Test Explorer =\u003e Test Project Path: Constructorio_NET/Constructorio_NET.Tests\n\n## Building\nThe project includes a build script that handles restore, build, and packaging:\n\n```bash\n# Build in Release mode (default)\n./build.sh\n\n# Build in Debug mode\n./build.sh Debug\n\n# Build with tests\n./build.sh --test\n\n# Build with clean\n./build.sh --clean\n\n# Combine options\n./build.sh Release --test --clean\n```\n\nThe build script will create a NuGet package in the `./artifacts` directory.\n\n## Testing\n- Make sure you have .NET SDK V8 installed\n- Open your terminal and navigate to the test directory:\n  ```bash\n  cd src/Constructorio_NET.Tests/\n  ```\n- Run the following command to execute tests:\n  ```bash\n  dotnet test\n  ```\n\n## For code coverage:\n- if initial setup:\n  - dotnet husky install\n- dotnet husky run -g coverage\n\n## Publishing\nThe project includes a publish script to push packages to NuGet:\n\n```bash\n# Set your NuGet API key\nexport NUGET_API_KEY=\"your-api-key\"\n\n# Dry run to verify package details\n./publish.sh --dry-run\n\n# Publish to NuGet (requires confirmation)\n./publish.sh\n```\n\nThe publish script will:\n1. Find the package in `./artifacts`\n2. Show package details and prompt for confirmation\n3. Push to NuGet.org\n4. Clean up the artifacts folder on success\n\n## Documentation\n- Documentation generated by [Doxygen](https://doxygen.nl/download.html) for Mac OS X 10.14 and later\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconstructor-io%2Fconstructorio-netcore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconstructor-io%2Fconstructorio-netcore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconstructor-io%2Fconstructorio-netcore/lists"}