{"id":23380673,"url":"https://github.com/agility/agility-contentimportapp","last_synced_at":"2025-04-08T07:43:24.308Z","repository":{"id":40915859,"uuid":"159851206","full_name":"agility/Agility-ContentImportApp","owner":"agility","description":"A .NET console application showcasing how to import content into Agility","archived":false,"fork":false,"pushed_at":"2022-12-07T20:02:18.000Z","size":21,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-14T04:51:15.429Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agility.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-30T16:38:50.000Z","updated_at":"2020-06-09T19:52:10.000Z","dependencies_parsed_at":"2023-01-24T22:00:27.845Z","dependency_job_id":null,"html_url":"https://github.com/agility/Agility-ContentImportApp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agility%2FAgility-ContentImportApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agility%2FAgility-ContentImportApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agility%2FAgility-ContentImportApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agility%2FAgility-ContentImportApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agility","download_url":"https://codeload.github.com/agility/Agility-ContentImportApp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247801198,"owners_count":20998331,"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":[],"created_at":"2024-12-21T20:17:32.068Z","updated_at":"2025-04-08T07:43:24.286Z","avatar_url":"https://github.com/agility.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Agility Content Import API \u0026 SDK\nA .NET console application showcasing how to import content into Agility.\n\n## About the API\nWhen you need to save web content into Agility for an import, you can use the Content Import API to do so.  It is a JSON API specifically created to allow you to save items into the Shared Content section of Agility.  This can be useful for doing complex content imports at the start of a project, or for keeping Agility content in sync with an outside system.  It is not meant to be used on a regular basis to replace the functions of the content manager. \n\nEach of these calls works by sending and receiving JSON strings to the server. \n\nBefore you start, make sure you are using the latest version of the Agility.Web dll, available from the Developer Downloads section of the Agility Content Manager Settings screen or nuget.\n\nEach method returns a JSON string in the following formats --\n\n**A single object result:**\n```csharp\n{\n  IsError: [true/false],\n  Message: [if an error occurred, not null],\n  ResponseData: [the object returned by the server]\n}\n```\n**A list result:**\n```csharp\n{\n  IsError: [true/false],\n  Message: [if an error occurred, not null],\n  ResponseData: {\n    TotalCount: [int],\n    Items: [list of objects returned by the server]\n}\n```\nIt's up to your code to check for IsError, in addition to any other exceptions that may occur within the method.\n\n```csharp\nstring jsonStr = JsonConvert.SerializeObject(obj);\n \nstring retStr = ServerAPI.SaveContentItem(-1, \"MyContent\", \"en-us\", jsonStr, null);\n \nAPIResult\u003cint\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cint\u003e\u003e(retStr);\nint contentID = retObj.ResponseData;\n\nif (retObj.IsError)\n{\n   throw new ApplicationException(string.Format(\"Error: {0}\", retObj.Message));\n}\n```\n\nWe recommend the JSON.Net library for serialization. \n\nIn order to convert your ResponseData to a strongly typed object, you must define that in the Deserialization settings when converting the string to a C# object.\n\n \n\n**Deserialize ResponseData to strongly-typed object:**\n\n```csharp\nAPIResult\u003cYourType\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cYourType\u003e\u003e(retStr);\n```\n\nOr, you can convert to a dynamic object for simplicity:\n```csharp\nAPIResult\u003cdynamic\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cdynamic\u003e\u003e(retStr);\n```\n\n## Client Setup\nYou can use the Content Import API from any .NET project. Typically, these are used in console applications or secured methods in a custom website project.\n\nIn order to use the Content Import API, you need to have the Agility.Web SDK installed in your .NET project. Agility.Web has dependencies on MVC, but it will still work in a Console application.\n\nIn addition to the Agility.Web SDK being installed, you'll also need to have an Agility.Web section added to your web.config or app.config (depending on the nature of your .NET project). This is used for authentication.\n\n**In app/web.config:**\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cconfiguration\u003e\n  \u003cconfigSections\u003e\n    \u003c!-- Agility.Web Config Group --\u003e\n    \u003csectionGroup name=\"agility.web\"\u003e\n      \u003csection name=\"settings\" type=\"Agility.Web.Configuration.Settings, Agility.Web\" allowLocation=\"true\" allowDefinition=\"Everywhere\" restartOnExternalChanges=\"false\" requirePermission=\"false\" /\u003e\n    \u003c/sectionGroup\u003e\n  \u003c/configSections\u003e\n  \u003cagility.web\u003e\n    \u003csettings applicationName=\"Content Import\" developmentMode=\"true\" contentCacheFilePath=\"c:\\AgilityContent\\\"\u003e\n      \u003cwebsites\u003e\n        \u003cadd websiteName=\"{{Your Website Name}}\" securityKey=\"{{Your Security Key}}\" /\u003e\n      \u003c/websites\u003e\n      \u003ctrace traceLevel=\"Verbose\" logFilePath=\"c:\\AgilityLogs\\Import.log\" emailErrors=\"false\"\u003e\n      \u003c/trace\u003e\n    \u003c/settings\u003e\n  \u003c/agility.web\u003e\n...\n\u003c/configuration\u003e\n```\n \n\n## Methods\n**GetContentItems(Agility.Web.Objects.ServerAPI.GetContentItemArgs arg)**\nGets a listing of content items based on the GetContentItemArgs parameter. You must include ALL the columns you want to be returned, otherwise, they will be not be returned. Returns an array on the ResponseData.\n```csharp\nstring retStr = ServerAPI.GetContentItems(\n        new Agility.Web.Objects.ServerAPI.GetContentItemArgs()\n        {\n            referenceName = \"ServerAPITest\",\n            columns = \"Title;Date;NumberTest\",\n            languageCode = \"en-us\",\n            pageSize = 20,\n            rowOffset = 0,\n            searchFilter = \"\",\n            sortField = \"Date\",\n            sortDirection = \"DESC\"\n        }\n    );\n\n/*\n Search Filter syntax:\n You must include the column name you want to retrieve/filter by in your 'columns'\n To search for a non-reserved property value (a custom field):\n    WHERE x.xmlData.value('(CI/I/IntTest)[1]', 'int') \u003e 1 //IntTest field, cast to an int\n    WHERE x.xmlData.value('(CI/I/MyString)[1]', 'nvarchar(max)') = 'My Test' //MyString, cast to a string\n To search for Title (reserved property name):\n    WHERE x.Title = 'this is a title'\n To search for TextBlob (reserved property name):\n    WHERE x.TextBlob = 'this is a textblob'\n To search for state (Staging,Published,Deleted,Approved,AwaitingApproval,Declined,Unpublished):\n    WHERE s.state = 'Staging'\n */\n    \n\nAPIResult\u003cdynamic\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cdynamic\u003e\u003e(retStr);\n \nif (retObj.IsError)\n{\n    //todo: handle error\n}\nelse\n{\n \n    foreach (var item in retObj.ResponseData.Items)\n    {\n        //access the columns from the items using their field names\n        string title = item.Title;\n        DateTime date = item.Date;\n        int numberTest = item.NumberTest;                   \n    }\n                 \n}\n```\n\n**GetContentItem(int contentID, string languageCode)**\nGet a content item given a contentID and languageCode.  Returns an object in the ResponseData.\n\n```csharp\nstring retStr = ServerAPI.GetContentItem(contentID, \"en-us\");\nAPIResult\u003cdynamic\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cdynamic\u003e\u003e(retStr);\nif (retObj.IsError)\n{\n    //handle error\n}\nelse\n{\n    dynamic item = retObj.ResponseData;\n    string aFieldValue = item.AFieldName;\n}\n```\n\n**DeleteContent(int contentID, string languageCode)**\nDeletes a content item given a contentID and languageCode. Does not return a value in the ReponseData.\n\n```csharp\nstring retStr = ServerAPI.DeleteContent(123, \"en-us\");\nAPIResult retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003e(retStr);\nif (retObj.IsError) { //handle error }\n ```\n\nRequestApproval(int contentID, string languageCode)\nRequests approval for a content item given a contentID and languageCode. Returns an integer in the ReponseData.\n\n```csharp\nstring retStr = ServerAPI.RequestApproval(123, \"en-us\");\nAPIResult\u003cint\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cint\u003e\u003e(retStr);\nif (retObj.IsError) { //handle error }\n```\n\n**SaveContentItem(int contentID, string languageCode, string referenceName, string contentItemEncoded, string attachmentsEncoded)**\nSaves a content item based on contentID, languageCode, referenceName. Returns an integer representing the content item in the ResponseData.\n\n```csharp\nvar contentItem =  new {\n    Title = \"Test item 1\",        \n    Date = new DateTime(2012, 10, 26),\n    Number = 1\n};\n \n \nvar attachments = new[] {\n    new {\n        originalName = \"[uploaded url]\",\n        mimeType = \"[contentType]\",\n        fileSize = fileSize, //file size \n        managerID = \"[FieldName]\",\n        AssetMediaID = mediaID //media id of uploaded file \n    }\n};\n \nstring contentItemStr = JsonConvert.SerializeObject(contentItem);\nstring attachmentsStr = JsonConvert.SerializeObject(attachments);\n \nstring retStr = ServerAPI.SaveContentItem(\n                -1, //if updating an item, pass content item here, otherwise set to -1 for NEW\n                \"ServerAPITest\", \n                \"en-us\", \n                contentItemStr, attachmentsStr);\n \nAPIResult\u003cint\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cint\u003e\u003e(retStr);\nif (retObj.IsError)\n{\n    //handle error\n}\nelse\n{\n    int contentID = retObj.ResponseData;\n}\n```\n\n**PublishContent(int contentID, string languageCode)**\nPublish a content item given a specific contentID and languageCode. The same contentID should be returned on success in the ReponseData.\n\n```csharp\nstring retStr = ServerAPI.PublishContent(123, \"en-us\");\nAPIResult\u003cint\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cint\u003e\u003e(retStr);\nif (retObj.IsError)\n{\n    //handle error\n}\nelse\n{\n    int contentID = retObj.ResponseData;\n}\n```\n\n**UnpublishContent(int contentID, string languageCode)**\nUnpublish a content item given a specific contentID and languageCode. The same contentID should be returned on success in the ReponseData.\n\n```csharp\nstring retStr = ServerAPI.UnpublishContent(123, \"en-us\");\nAPIResult\u003cint\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cint\u003e\u003e(retStr);\nif (retObj.IsError)\n{\n    //handle error\n}\nelse\n{\n    int contentID = retObj.ResponseData;\n}\n```\n\n**UploadMedia(string mediaFolder, string fileName, string contentType, Stream fileData)**\nUpload a file to the Media \u0026 Documents section of Agility to the specified folder. Returns an object representing the media uploaded.\n\n```csharp\nStream s = Request.Files[0].InputStream;\nstring filename = Path.GetFileName(Request.Files[0].FileName);\nstring contentType = Request.Files[0].ContentType;\n \nstring retStr = ServerAPI.UploadMedia(\"Upload\", filename, contentType, s);\n \nAPIResult\u003cdynamic\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cdynamic\u003e\u003e(retStr);\nif (retObj.IsError)\n{\n    //handle error\n}\nelse\n{\n    int mediaID = retObj.ResponseData.MediaID;\n    string mediaUrl = retObj.ResponseData.Url;\n    string thumbnailUrl = retObj.ResponseData.ThumbnailUrl;\n    int size = retObj.ResponseData.Size;\n}\n```\n**GetSitemap(string languageCode)**\nRetrieves a list of page items from the page tree in Agility.\n\n```csharp\nstring retStr = ServerAPI.GetSitemap(\"en-us\");\nConsole.WriteLine(retStr);\nAPIResult\u003cdynamic\u003e retObj = JsonConvert.DeserializeObject\u003cAPIResult\u003cdynamic\u003e\u003e(retStr);\n\nif (retObj.IsError)\n{\n    //handle error\n} else {\n  var channelsList = retObj.ResponseData;\n  var channelPages = retObj.ResponseData[0].Pages;\n  var pageUrl = retObj.ResponseData[0].Pages.URL;\n}\n```\nView Docs in [Help Center](https://help.agilitycms.com/hc/en-us/articles/360020079532)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagility%2Fagility-contentimportapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagility%2Fagility-contentimportapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagility%2Fagility-contentimportapp/lists"}