{"id":37482760,"url":"https://github.com/relativitydev/server-import-sdk-samples","last_synced_at":"2026-01-16T07:28:36.650Z","repository":{"id":226303249,"uuid":"698633495","full_name":"relativitydev/server-import-sdk-samples","owner":"relativitydev","description":null,"archived":false,"fork":false,"pushed_at":"2025-12-30T13:27:10.000Z","size":875,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-03T00:56:16.957Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/relativitydev.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":"2023-09-30T13:55:46.000Z","updated_at":"2025-12-30T13:17:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"d769df80-643c-4fbb-90f1-4d067a7df61d","html_url":"https://github.com/relativitydev/server-import-sdk-samples","commit_stats":null,"previous_names":["relativitydev/server-import-sdk-samples"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/relativitydev/server-import-sdk-samples","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relativitydev%2Fserver-import-sdk-samples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relativitydev%2Fserver-import-sdk-samples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relativitydev%2Fserver-import-sdk-samples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relativitydev%2Fserver-import-sdk-samples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/relativitydev","download_url":"https://codeload.github.com/relativitydev/server-import-sdk-samples/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relativitydev%2Fserver-import-sdk-samples/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: 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":[],"created_at":"2026-01-16T07:28:36.555Z","updated_at":"2026-01-16T07:28:36.629Z","avatar_url":"https://github.com/relativitydev.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Relativity Server Import Samples\n\nThis repository demonstrates how the Relativity Server Import SDK can be used to import the following:\n\n* Native documents\n* Images\n* Objects\n* Productions\n\nAll of the samples are based on [NUnit](https://nunit.org/), the [AAA](https://learn.microsoft.com/en-us/visualstudio/test/unit-test-basics?view=vs-2022#write-your-test) test structure pattern is followed, and app.config settings define test parameters including Relativity Urls and login credentials. Once these settings have been made, the tests are 100% responsible for all required setup and tear down procedures.\n\n**Note:** the test project relies on [Relativity NuGet packages](https://www.nuget.org/packages?q=Relativity) to ensure Import API and all dependencies are deployed to the proper target directory.\n\nThis page contains the following information:\n\n* [Prerequisites](#prerequisites)\n* [Setup](#setup)\n* [Import API class](#importapi-class)\n  * [Authentication](#authentication)\n  * [Jobs](#jobs)\n  * [Data Source](#data-source)\n  * [Events](#events)\n  * [Execute](#execute)\n* [Import Samples](#import-samples)\n  * [Import documents](#import-documents)\n  * [Import objects](#import-objects)\n  * [Import images](#import-images)\n  * [Import productions](#import-productions)\n\n## Prerequisites\n\n* Visual Studio 2022 and above\n* A Server 2023 or above developer Dev VM\n* Visual C++ 2015 x64 Runtime (Outside In and FreeImage)\n\n**Note:** Visual Studio 2022 and above is required due to NuGet 6 and C# language feature usage. Relativity strongly recommends [using a developer Dev VM](https://platform.relativity.com/Server2022/Content/Get_started/Lesson_1_-_Set_up_your_developer_environment.htm) for the test environment.\n\n## Setup\nThe steps below should only be required when the repository is being cloned for the first time.\n\n\u003cdetails\u003e\u003csummary\u003eView instructions\u003c/summary\u003e\n\n## Step 1 - Identify the branch\nWith each new Relativity Server annual release, a new branch is created to not only test and verify the Import SDK package but to ensure all package references are updated properly. As of this writing, the following three releases are available for consideration:\n\n![Sample Branches](docs/Branches.png \"Sample Branches\")\n\n## Step 2 - Clone the repository\nUse the command-line or Visual Studio to clone the repository and target a branch from the previous step.\n\n```bash\ngit clone -b server-release-2023 https://github.com/relativitydev/server-import-sdk-samples.git\n```\n\n## Step 3 - Open the solution\nLaunch Visual Studio 2022 and open the Relativity.DataExchange.Samples.NUnit.sln solution file.\n\n## Step 4 - Create the FunctionalTest.runsettings file\nOpen a PowerShell terminal and run the following script to autogenerate the .\\src\\FunctionalTest.runsettings file.\n\n```powershell\n.\\New-TestSettings.ps1 -TestVMName \u003cSPECIFY-DEVVM-NAME\u003e\n```\n\nOnce the file is created, click Test \u0026rarr; Configure Run Settings \u0026rarr; Select Solution Wide runsettings File, and select the .\\src\\FunctionalTest.runsettings file.\n\n## Step 5 - Build Solution\nUse Visual Studio to build the solution.\n\n## Step 6 - Execute tests\nAt this point, the setup is complete and should now be able to run all of the tests. If the test explorer isn't visible, go to `Test-\u003eWindows-\u003eTest Explorer` and click the `Run All` hyper-link at the top. Regardless of which method is used to execute tests, the following actions occur:\n\n* A new test workspace is created (normally 15-30 seconds) to ensure tests are isolated\n* The tests are executed\n* The test workspace is deleted\n* The Test Explorer displays the results\n\nIf everything is working properly, the Test Explorer should look something like this:\n\n![Test Explorer](docs/TestExplorer.png \"Test Explorer\")\n\n**Note:** If the Test Explorer lists the tests but none of the tests run, **ensure the value is set to X64**. Although this setting is cached, Visual Studio is known to reset the value to X86.\n\n\u003c/details\u003e\n\n## ImportAPI class\nThe `ImportAPI` class is a top-level class that includes functionality for importing documents, images, production sets, and Relativity Dynamic Objects (RDOs). It includes methods for performing these import jobs, as well as other methods for retrieving workspace, field, and other objects.\n\n### Relativity Kepler REST Services\nThe Import SDK design uses the Relativity Kepler REST Services and proper URLs must be supplied when constructing the object.\n\n* https://hostname.mycompany.corp (Relativity instance)\n* https://hostname.mycompany.corp/relativitywebapi (Relativity web services)\n\n### Authentication\nWhen constructing the `ImportAPI` object, the API caller must first decide which authentication model is used in order to determine how the object is constructed.\n\n**Note:** Authentication is immediately performed within the `ImportAPI` constructor and *will throw an exception* if a failure occurs. API callers should wrap this call with a try/catch block.\n\n#### Relativity username and password authentication\nThe user must be a member of the System Administrators group in Relativity. These permissions are similar to those required to import a load file through the Relativity Desktop Client.\n\n```csharp\nImportAPI importApi = new ImportAPI(relativityUserName, relativityPassword, relativityWebServiceUrl);\n```\n\n#### Bearer token authentication\nUses the current claims principal token to authenticate and should only be used by Relativity Service Account hosted processes.\n\n```csharp\nImportAPI importApi = ImportAPI.CreateByRsaBearerToken(relativityWebServiceUrl);\n```\n\n**Note:** This is the preferred method for using Import API within an agent or custom page.\n\n#### Windows authentication\nThe user is validated against the Relativity instance located at WebServiceURL.\n\n```csharp\nImportAPI importApi = new ImportAPI(relativityWebServiceUrl);\n```\n\n### Jobs\nGiven the `ImportAPI` object, the API caller calls a method to create the appropriate job object. This is later used to configure and execute the import job.\n\n```csharp\nconst int SomeObjectArtifactTypeId = 1111111;\nconst int ProductionSetArtifactId = 2222222;\nkCura.Relativity.DataReaderClient.ImportBulkArtifactJob job = importApi.NewNativeDocumentImportJob();\nkCura.Relativity.DataReaderClient.ImportBulkArtifactJob job = importApi.NewObjectImportJob(SomeObjectArtifactTypeId);\nkCura.Relativity.DataReaderClient.ImageImportBulkArtifactJob job = importApi.NewImageImportJob();\nkCura.Relativity.DataReaderClient.ImageImportBulkArtifactJob job = importApi.NewProductionImportJob(ProductionSetArtifactId);\n```\n\n#### ImportBulkArtifactJob Settings\nWhen configuring either native document or object import jobs, the `Settings` property exposes a number of options to control import behavior.\n\n\u003cdetails\u003e\u003csummary\u003eView settings\u003c/summary\u003e\n\n| Setting                                     | Description                                                                                                                  |\n|---------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|\n| ArtifactTypeId                              | The target object artifact type identifier.                                                                                  |\n| Billable                                    | Indicates whether imported files are billable.                                                                               |\n| BulkLoadFileFieldDelimiter                  | The field delimiter used when writing out the bulk load file.                                                                |\n| CaseArtifactId                              | The target workspace artifact identifier.                                                                                    |\n| CopyFilesToDocumentRepository               | Indicates whether to enable or disable copying files to the document repository.\u003cul\u003e\u003cli\u003eIf True, the files are copied.\u003c/li\u003e\u003cli\u003eIf False, files will be linked instead.\u003c/li\u003e\u003c/ul\u003e |\n| DisableControlNumberCompatibilityMode       | Indicates whether to enable or disable the use of `Control Number` to override `SelectedIdentifierField`.\u003cul\u003e\u003cli\u003eIf True, tries to use `Control Number` for the `SelectedIdentifierField` and ignores `SelectedIdentifierField`.\u003c/li\u003e\u003cli\u003eIf False and `SelectedIdentifierField` is not set, uses the default identifier field.\u003c/li\u003e\u003c/ul\u003e |\n| DisableExtractedTextEncodingCheck           | Indicates whether to enable or disable encoding checks for each file.\u003cul\u003e\u003cli\u003eIf True, encoding checks are disabled.\u003c/li\u003e\u003cli\u003eIf False, encoding checks are disabled.\u003c/li\u003e\u003c/ul\u003e |\n| DisableExtractedTextFileLocationValidation  | Indicates whether to enable or disable validation of the extracted text file location.\u003cul\u003e\u003cli\u003eIf True, validation is disabled. If an extracted text file doesn't exist, the job fails.\u003c/li\u003e\u003cli\u003eIf False, validation is enabled.\u003c/li\u003e\u003c/ul\u003e |\n| DisableNativeLocationValidation             | Indicates whether to enable or disable validation of the native file path.\u003cul\u003e\u003cli\u003eIf True, validation is disabled.\u003c/li\u003e\u003cli\u003eIf False, validation is enabled.\u003c/li\u003e\u003c/ul\u003e |\n| DisableNativeValidation                     | Indicates whether to enable or disable validation of the native file type for the current job.\u003cul\u003e\u003cli\u003eIf True, validation is disabled.\u003c/li\u003e\u003cli\u003eIf False, validation is enabled.\u003c/li\u003e\u003c/ul\u003e |\n| DisableUserSecurityCheck                    | Indicates whether to enable or disable user permission checks per document or object.\u003cul\u003e\u003cli\u003eIf True, user permission checks are disabled.\u003c/li\u003e\u003cli\u003eIf False, validation checks are enabled.\u003c/li\u003e\u003c/ul\u003e |\n| ExtractedTextEncoding                       | The extracted text file encoding.                                                                                            |\n| ExtractedTextFieldContainsFilePath          | Indicates whether the extracted text field contains a path to the extracted text file or contains the actual extracted text.\u003cul\u003e\u003cli\u003eIf True, the extracted text field contains a path to the extracted text file.\u003c/li\u003e\u003cli\u003eIf False, the extracted text field contains the actual extracted text.\u003c/li\u003e\u003c/ul\u003e |\n| FileSizeColumn                              | The column that contains the `FileSize` on the `SourceData` property.                                                          |\n| FileSizeMapped                              | Indicates whether to enable or disable skipping file size checks.\u003cul\u003e\u003cli\u003eIf True, the file size is mapped and `OIFileIdColumnName` and `FileSizeColumn` must be mapped.\u003c/li\u003e\u003cli\u003eIf False, the file size isn't mapped.\u003c/li\u003e\u003c/ul\u003e |\n| FolderPathSourceFieldName                   | The metadata field used to build the folder structure.\u003cbr/\u003e\u003cbr/\u003e**Note:**  All folders are built under the Import Destination folder, indicated by the `DestinationFolderArtifactID` value. If a folder matching the entered string already exists, the documents will be added to it; otherwise, the folder(s) (including nested folders) will be created and the documents will be imported into the new folder(s). |\n| IdentityFieldId                             | The key field that's set only on Overwrite mode.                                                                             |\n| LoadImportedFullTextFromServer              | Indicates whether to enable or disable loading extracted text directly from its file path.\u003cul\u003e\u003cli\u003eIf True, the extracted text field data is loaded directly from its file path. extracted text files must exactly match the encoding of the extracted text field. If extracted text is unicode enabled, the files need to be UTF-16 encoded, otherwise they need to be ANSI. This setting will only be used when `ExtractedTextFieldContainsFilePath` is also set to True.\u003c/li\u003e\u003cli\u003eIf False, the extracted text field data is loaded from the bulk-load file.\u003c/li\u003e\u003c/ul\u003e |\n| MaximumErrorCount                           | The maximum number of errors displayed. This property is optional.                                                           |\n| MoveDocumentsInAppendOverlayMode            | Indicates whether to enable or disable moving documents to a new folder for Append/Overlay mode.\u003cul\u003e\u003cli\u003eIf True, the documents are moved to a new folder for Append/Overlay mode.\u003c/li\u003e\u003cli\u003eIf False, the documents are not moved.\u003c/li\u003e\u003c/ul\u003e |\n| NativeFileCopyMode                          | The native file copy behavior.\u003cul\u003e\u003cli\u003e**DoNotImportNativeFiles:** documents are imported without their native files.\u003c/li\u003e\u003cli\u003e**CopyFiles:** native files are copied into the workspace.\u003c/li\u003e\u003cli\u003e**SetFileLinks:** Link to the native files but don't copy them.\u003c/li\u003e\u003c/ul\u003e |\n| NativeFilePathSourceFieldName               | The name of the field that contains the full path and filename for the native files.                                         |\n| OIFileIdColumnName                          | The name of the field that contains the `OutsideInFileId` on the data source object.\u003cbr/\u003e\u003cbr/\u003e**Note:** If `OIFileIdMapped` or `FileSizeMapped` is True, set this property to the value that indicates the field that. contains the `OutsideInFileId` value. |\n| OIFileIdMapped                              | Indicates whether to enable or disable file identification.\u003cul\u003e\u003cli\u003eIf True, the file identifier is mapped. Both `OIFileIdColumnName` and `OIFileTypeColumnName` must be set.\u003c/li\u003e\u003cli\u003eIf False, the file identifier isn't mapped.\u003c/li\u003e\u003c/ul\u003e |\n| OIFileTypeColumnName                        | The name of the field that contains the Outside In file type on the data source.\u003cbr/\u003e\u003cbr/\u003e**Note:**  If `OIFileIdMapped` is True, this field must be set. |                                                               |\n| OverwriteMode                               | The import overwrite behavior.\u003cul\u003e\u003cli\u003e**Append:** Import all files even if that causes duplication. This is faster than Append/Overlay mode.\u003c/li\u003e\u003cli\u003e**Overlay:** Update all files if new versions are made available by the import.\u003c/li\u003e\u003cli\u003e**AppendOverlay:** Import all files. Those that are duplicates will be updated to the new version of the file.\u003c/li\u003e\u003c/ul\u003e |\n| SelectedIdentifierFieldName                 | The name of the field used as an identifier.\u003cbr/\u003e\u003cbr/\u003e**Note:**  If this identifier cannot be resolved, the control number will be used in its place. |\n| StartRecordNumber                           | The record number from which to start the import.                                                                           |\n\n\u003c/details\u003e\n\n#### ImageImportBulkArtifactJob Settings\nWhen configuring either image or production import jobs, the `Settings` property exposes a number of options to control import behavior.\n\n\u003cdetails\u003e\u003csummary\u003eView settings\u003c/summary\u003e\n\n| Setting                                     | Description                                                                                                                  |\n|---------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|\n| ArtifactTypeId                              | The target object artifact type identifier.                                                                                  |\n| AutoNumberImages                            | Indicates whether to enable or disable appending a page number to a page-level identifier.\u003cul\u003e\u003cli\u003eIf True, a new incremental number (such as 01, 02) is added to the page-level identifier to create a unique page number.\u003c/li\u003e\u003cli\u003eIf False, the page number isn't appended.\u003c/li\u003e\u003c/ul\u003e |\n| BatesNumberField                            | The name of the field that defines the unique identifier.\u003cbr/\u003e\u003cbr/\u003e**Note:** This unique identifier may be called `Bates Number` or `Control Number` in a database. |\n| Billable                                    | Indicates whether imported files are billable.                                                                               |\n| CaseArtifactId                              | The target workspace artifact identifier.                                                                                    |\n| CopyFilesToDocumentRepository               | Indicates whether to enable or disable copying files to the document repository.\u003cul\u003e\u003cli\u003eIf True, the files are copied.\u003c/li\u003e\u003cli\u003eIf False, files will be linked instead.\u003c/li\u003e\u003c/ul\u003e |\n| DisableExtractedTextEncodingCheck           | Indicates whether to enable or disable encoding checks for each file.\u003cul\u003e\u003cli\u003eIf True, encoding checks are disabled.\u003c/li\u003e\u003cli\u003eIf False, encoding checks are disabled.\u003c/li\u003e\u003c/ul\u003e |\n| DisableImageLocationValidation              | Indicates whether to enable or disable image location validation.\u003cul\u003e\u003cli\u003eIf True, validation checks are disabled.\u003c/li\u003e\u003cli\u003eIf False, validation checks are enabled.\u003c/li\u003e\u003c/ul\u003e |\n| DisableImageTypeValidation                  | Indicates whether to enable or disable image type validation.\u003cul\u003e\u003cli\u003eIf True, validation checks are disabled.\u003c/li\u003e\u003cli\u003eIf False, validation checks are enabled.\u003c/li\u003e\u003c/ul\u003e |\n| DisableUserSecurityCheck                    | Indicates whether to enable or disable user permission checks per document or object.\u003cul\u003e\u003cli\u003eIf True, user permission checks are disabled.\u003c/li\u003e\u003cli\u003eIf False, validation checks are enabled.\u003c/li\u003e\u003c/ul\u003e |\n| DocumentIdentifierField                     | The name of the field that corresponds to the `DocumentIdentifier` field.                                                     |\n| ExtractedTextEncoding                       | The extracted text file encoding.                                                                                            |\n| ExtractedTextFieldContainsFilePath          | Indicates whether the extracted text field contains a path to the extracted text file or contains the actual extracted text.\u003cul\u003e\u003cli\u003eIf True, the extracted text field contains a path to the extracted text file.\u003c/li\u003e\u003cli\u003eIf False, the extracted text field contains the actual extracted text.\u003c/li\u003e\u003c/ul\u003e |\n| FileLocationField                           | The name of the field that corresponds with the `FileLocation` field.                                                        |\n| FolderPathSourceFieldName                   | The metadata field used to build the folder structure.\u003cbr/\u003e\u003cbr/\u003e**Note:**  All folders are built under the Import Destination folder, indicated by the `DestinationFolderArtifactID` value. If a folder matching the entered string already exists, the documents will be added to it; otherwise, the folder(s) (including nested folders) will be created and the documents will be imported into the new folder(s). |\n| IdentityFieldId                             | The key field that's set only on `Overwrite` mode.                                                                             |\n| ImageFilePathSourceFieldName                | The name of the field that contains the full path to the image file.                                                         |\n| LoadImportedFullTextFromServer              | Indicates whether to enable or disable loading extracted text directly from its file path.\u003cul\u003e\u003cli\u003eIf True, the extracted text field data is loaded directly from its file path. extracted text files must exactly match the encoding of the extracted text field. If extracted text is unicode enabled, the files need to be UTF-16 encoded, otherwise they need to be ANSI. This setting will only be used when `ExtractedTextFieldContainsFilePath` is also set to True.\u003c/li\u003e\u003cli\u003eIf False, the extracted text field data is loaded from the bulk-load file.\u003c/li\u003e\u003c/ul\u003e |\n| MaximumErrorCount                           | The maximum number of errors displayed. This property is optional.                                                           |\n| MoveDocumentsInAppendOverlayMode            | Indicates whether to enable or disable moving documents to a new folder for Append/Overlay mode.\u003cul\u003e\u003cli\u003eIf True, the documents are moved to a new folder for Append/Overlay mode.\u003c/li\u003e\u003cli\u003eIf False, the documents are not moved.\u003c/li\u003e\u003c/ul\u003e |\n| NativeFileCopyMode                          | The native file copy behavior.\u003cul\u003e\u003cli\u003e**DoNotImportNativeFiles:** documents are imported without their native files.\u003c/li\u003e\u003cli\u003e**CopyFiles:** native files are copied into the workspace.\u003c/li\u003e\u003cli\u003e**SetFileLinks:** Link to the native files but don't copy them.\u003c/li\u003e\u003c/ul\u003e |\n| OverlayBehavior                             | The method for overlay imports with multiple choice and multi-object fields.\u003cul\u003e\u003cli\u003e**UseRelativityDefaults:** each field will be imported based on its overlay behavior settings in Relativity.\u003c/li\u003e\u003cli\u003e**MergeAll:** new imported values will be added to all imported fields.\u003c/li\u003e\u003cli\u003e**ReplaceAll:** all the imported fields previous values will all be overwritten with the imported values.\u003c/li\u003e\u003c/ul\u003e |\n| OverwriteMode                               | The import overwrite behavior.\u003cul\u003e\u003cli\u003e**Append:** Import all files even if that causes duplication. This is faster than Append/Overlay mode.\u003c/li\u003e\u003cli\u003e**Overlay:** Update all files if new versions are made available by the import.\u003c/li\u003e\u003cli\u003e**AppendOverlay:** Import all files. Those that are duplicates will be updated to the new version of the file.\u003c/li\u003e\u003c/ul\u003e |\n| SelectedIdentifierFieldName                 | The name of the field used as an identifier.\u003cbr/\u003e\u003cbr/\u003e**Note:**  If this identifier cannot be resolved, the control number will be used in its place. |\n| StartRecordNumber                           | The record number from which to start the import.                                                                           |\n\n\u003c/details\u003e\n\n### Data Source\nRegardless of which job is created, the API caller uses standard [ADO.NET](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ado-net-overview) constructs like  `System.Data.DataTable` to define or `System.Data.IDataReader` to read data sources.\n\n```csharp\n// Once the data source is defined, the DataColumn names are mapped via the job Settings object.\nSystem.Data.DataTable dataSource = new System.Data.DataTable();\ndataSource.Columns.AddRange(new[]\n{\n    new DataColumn(\"control number\", typeof(string)),\n    new DataColumn(\"file path\", typeof(string))\n});\n\ndataSource.Rows.Add(\"REL-4444444\", @\"C:\\temp\\sample.pdf\");\njob.Settings.SelectedIdentifierFieldName = \"control number\";\njob.SourceData.SourceData = dataSource.CreateDataReader();\n```\n\n### Events\nThe `ImportBulkArtifactJob` and `ImageImportBulkArtifactJob` objects expose a number of useful events to obtain document-level errors, completion, fatal exception, and progress details.\n\n#### JobReport\nThis object is exposed by several events and provides useful job summary details.\n\n| Property                      | Description                                                                                                          |\n| ------------------------------| ---------------------------------------------------------------------------------------------------------------------|\n| EndTime                       | The import end time.                                                                                                 |\n| ErrorRowCount                 | The total number of non-fatal document-level errors that occurred.                                                   |\n| ErrorRows                     | The collection of non-fatal document-level error objects that occurred.                                                     |\n| FatalException                | The exception that resulted in a fatal job error.                                                                    |\n| FieldMap                      | The collection of field map entries that map source fields to destination fields in the workspace.                   |\n| FileBytes                     | The total number of transferred native file bytes.                                                                   |\n| MetadataBytes                 | The total number of transferred metadata bytes.                                                                      |\n| StartTime                     | The import start time.                                                                                               |\n| TotalRows                     | The total number of processed rows. This value doesn't indicate the number of successful rows.                       |\n\n#### OnComplete\nThis event is raised when an import job is finished. A `JobReport` object is passed with detailed information about the job. A completed job may have errors if the data wasn't imported properly.\n\n```csharp\n// This event provides the JobReport object.\njob.OnComplete += report =\u003e\n{\n   Console.WriteLine(\"The job has completed.\");\n};\n```\n\n#### OnError\nThis event is raised when an error occurs while importing a row of data.\n\n```csharp\n// This event provides an IDictionary object with well-known parameters.\njob.OnError += row =\u003e\n{\n    Console.WriteLine(row[\"Line Number\"]);\n    Console.WriteLine(row[\"Identifier\"]);\n    Console.WriteLine(row[\"Message\"]);\n};\n```\n\n**Note:** The MaximumErrorCount is a configurable setting available on all import jobs that determines the number of errors to return.\n\n#### OnFatalException\nThis event is raised when an import job encounters a fatal exception caused by invalid import settings or other issues. The fatal exception can be retrieved by the passed `JobReport` object.\n\n```csharp\n// This event provides the JobReport object.\njob.OnFatalException += report =\u003e\n{\n    Console.WriteLine(\"The job experienced a fatal exception: \" + report.FatalException);\n};\n```\n\n#### OnMessage\nThis event is raised throughout the import job life cycle and is similar to the messages displayed in the Relativity Desktop Client.\n\n```csharp\n// This event provides the Status object.\njob.OnMessage += status =\u003e\n{\n    Console.WriteLine(\"Job message: \" + status.Message);\n};\n```\n\n#### OnProcessProgress\nThis event is raised at the same rate as the `OnMessage` event and provides detailed progress information about the import job.\n\n```csharp\n// This event provides the FullStatus object.\njob.OnProcessProgress += status =\u003e\n{\n    Console.WriteLine(\"Job start time: \" + status.StartTime);\n    Console.WriteLine(\"Job end time: \" + status.EndTime);\n    Console.WriteLine(\"Job process ID: \" + status.ProcessID);\n    Console.WriteLine(\"Job total records: \" + status.TotalRecords);\n    Console.WriteLine(\"Job total records processed: \" + status.TotalRecordsProcessed);\n    Console.WriteLine(\"Job total records processed with warnings: \" + status.TotalRecordsProcessedWithWarnings);\n    Console.WriteLine(\"Job total records processed with errors: \" + status.TotalRecordsProcessedWithErrors);\n    Console.WriteLine(\"Job total records: \" + status.TotalRecordsDisplay);\n    Console.WriteLine(\"Job total records processed: \" + status.TotalRecordsProcessedDisplay);\n    Console.WriteLine(\"Job status suffix: \" + status.StatusSuffixEntries);\n};\n```\n\n#### OnProgress\nThis event is raised for each row found in the data set.\n\n```csharp\n// This event provides the row number.\njob.OnProgress += row =\u003e\n{\n    Console.WriteLine(\"Job progress line number: \" + row);\n};\n```\n\n### Execute\nOnce the job has been fully configured, the API caller invokes the `Execute` method. Soon thereafter, events are raised and the method returns once the job either completes or a fatal exception occurs.\n\n```csharp\n// Wait for the job to complete.\njob.Execute();\n```\n\n**Note:** Although fatal exceptions are normally caught and raised by the `OnFatalException` event, API callers should wrap this method call with a try/catch block.\n\n## Import Samples\nThe section below outlines each of the import job test samples.\n\n### Import documents\n* The [DocImportTests](src/Relativity.Server.Import.SDK.Samples/Tests/DocImportTests.cs \"DocImportTests\")  imports sample documents.\n* The [DocImportFolderTests](src/Relativity.Server.Import.SDK.Samples/Tests/DocImportFolderTests.cs \"DocImportFolderTests\") imports sample documents and also specifies folder paths. \n* The [DocNegativeImportTests](src/Relativity.Server.Import.SDK.Samples/Tests/DocNegativeImportTests.cs \"DocNegativeImportTests\") imports documents that expect job-level import failures.\n\n### Import objects\n* The [ObjectSimpleImportTests](src/Relativity.Server.Import.SDK.Samples/Tests/ObjectSimpleImportTests.cs \"ObjectSimpleImportTests\") imports a custom object with a single-object field.\n* The [ObjectAdvancedImportTests](src/Relativity.Server.Import.SDK.Samples/Tests/ObjectAdvancedImportTests.cs \"ObjectAdvancedImportTests\") imports a custom object with a multi-object field.\n* The [ObjectNegativeImportTests](src/Relativity.Server.Import.SDK.Samples/Tests/ObjectNegativeImportTests.cs \"ObjectNegativeImportTests\") imports single-object and multi-object fields that expect document-level and job-level import failures.\n\n**Note:** The tests create custom RDO types during the test setup.\n\n### Import images\n* The [ImageImportTests](src/Relativity.Server.Import.SDK.Samples/Tests/ImageImportTests.cs \"ImageImportTests\") imports sample images.\n\n### Import productions\n* The [ProductionImportTests](src/Relativity.Server.Import.SDK.Samples/Tests/ProductionImportTests.cs \"ProductionImportTests\") imports sample documents, creates a production, and then validates the bates numbers.\n\n**Note:** This test relies upon the [Productions NuGet package](https://www.nuget.org/packages/Relativity.Productions.Client/) to perform all required functionality.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelativitydev%2Fserver-import-sdk-samples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frelativitydev%2Fserver-import-sdk-samples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelativitydev%2Fserver-import-sdk-samples/lists"}