{"id":211,"date":"2021-01-24T19:04:23","date_gmt":"2021-01-24T19:04:23","guid":{"rendered":"https:\/\/www.naveedulhaq.com\/?p=211"},"modified":"2021-01-24T19:04:24","modified_gmt":"2021-01-24T19:04:24","slug":"working-with-ftp-in-net-core","status":"publish","type":"post","link":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/","title":{"rendered":"Working with FTP in .NET Core"},"content":{"rendered":"\n<p>In this blog post, we will explore how we can access FTP server and how we can download a file or complete folder based on access rights.<\/p>\n\n\n\n<p>Once files or folders are downloaded, we also delete files from FTP server to keep our FTP repository tidy. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Access FTP Server (Create a connection)<\/h2>\n\n\n\n<p>To access FTP server we need following;<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>A valid User name (user name that has access to explore FTP repository) <\/li><li>A valid password<\/li><li>FTP URL with the port. (Normally FTP uses port 25 but some service provider may change this port number)<\/li><\/ul>\n\n\n\n<p>Now we need to create an FTPRequest (System.Net) to talk with FTP server. This is a simple Web request, it contains NetworkCredential (System.Net) &amp; FTP server Url.<\/p>\n\n\n\n<p>So first step, create NetworkCredential <\/p>\n\n\n\n<pre><code>var credentials = new NetworkCredential(\"FTP-Username\", \"FTP-Password\");<\/code><\/pre>\n\n\n\n<p>After that we will create complete request object like below<\/p>\n\n\n\n<pre><code>FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(\"FTP-Url\");\n            listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;\n            listRequest.Credentials = credentials;<\/code><\/pre>\n\n\n\n<p>and get response from FTP server based on our Request<\/p>\n\n\n\n<pre><code>using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())<\/code><\/pre>\n\n\n\n<p>You might have noticed that in our request object, our request method is &#8220;ListDirectoryDetails&#8221;. This is because we want to get list of files and directories from our FTP repository and later we will decide if we want to delete or keep these files. Your request method or scenario might be different. There are following request methods you can use<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>ListDirectoryDetails<\/li><li>AppendFile<\/li><li>DeleteFile<\/li><li>DownloadFile<\/li><li>GetDateTimestamp<\/li><li>GetFileSize<\/li><li>ListDirectory<\/li><li>MakeDirectory<\/li><li>PrintWorkingDirectory<\/li><li>RemoveDirectory<\/li><li>Rename<\/li><li>UploadFile<\/li><li>UploadFileWithUniqueName<\/li><\/ul>\n\n\n\n<p>now we have response from FTP server we can read response and see list of files.<\/p>\n\n\n\n<pre><code>FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);\n            listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;\n            listRequest.Credentials = credentials;\n\n            List&lt;string> lines = new List&lt;string>();\n\n            using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())\n            using (Stream listStream = listResponse.GetResponseStream())\n            \n            using (StreamReader listReader = new StreamReader(listStream))\n            {\n                while (!listReader.EndOfStream)\n                {\n                    lines.Add(listReader.ReadLine());\n                }\n            }\n            foreach (string line in lines)\n            {\n                \/\/ ==== Do sometime ==== \n            }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Get Files \/ Directories from FTP<\/h2>\n\n\n\n<p>We can create a simple method that will download all files and directories from FTP using above code examples. Let&#8217;s call it &#8220;DownloadFtpFilesDirectory&#8221;. This method takes <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>User Name<\/li><li>Password<\/li><li>Url<\/li><li>Local directory path<\/li><\/ul>\n\n\n\n<p>to create FTP request and download files and complete directories in local drive.<\/p>\n\n\n\n<pre><code>        static void DownloadFtpFilesDirectory(string url, NetworkCredential credentials, string localPath)\n        {\n            FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);\n            listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;\n            listRequest.Credentials = credentials;\n\n            List&lt;string> lines = new List&lt;string>();\n\n            using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())\n            using (Stream listStream = listResponse.GetResponseStream())\n\n            using (StreamReader listReader = new StreamReader(listStream))\n            {\n                while (!listReader.EndOfStream)\n                {\n                    lines.Add(listReader.ReadLine());\n                }\n            }\n            \n            foreach (string line in lines)\n            {\n                string&#91;] tokens =\n                    line.Split(new&#91;] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries);\n                string name = tokens&#91;3];\n                string permissions = tokens&#91;2];\n\n\n                string fileUrl = url + name;\n\n\n                if (permissions&#91;1] == 'D')\n                {\n                    \/\/ line contains Directory\n                    string localFilePath = Path.Combine(localPath, name);\n\n                    \/\/recursive function\n                    DownloadFtpFilesDirectory(fileUrl + \"\/\", credentials, localFilePath);\n                }\n                else\n                {\n                    \/\/ line contains file\n\n                    FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(fileUrl);\n                    downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;\n                    downloadRequest.Credentials = credentials;\n\n                    using (FtpWebResponse downloadResponse =\n                              (FtpWebResponse)downloadRequest.GetResponse())\n                    using (Stream sourceStream = downloadResponse.GetResponseStream())\n                    using (Stream targetStream = File.Create(Path.Combine(localPath, name)))\n                    {\n                        byte&#91;] buffer = new byte&#91;10240];\n                        int read;\n                        while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0)\n                        {\n                            targetStream.Write(buffer, 0, read);\n                        }\n                    }\n                }\n            }\n        }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Delete Files or Directories from FTP<\/h2>\n\n\n\n<p><strong>Delete Files<\/strong><\/p>\n\n\n\n<pre><code>FtpWebRequest deleteRequest = (FtpWebRequest)WebRequest.Create(fileUrl);\n                    deleteRequest.Method = WebRequestMethods.Ftp.DeleteFile;\n                    deleteRequest.Credentials = credentials;\n\n                    FtpWebResponse response = (FtpWebResponse)deleteRequest.GetResponse();\n                    response.Close();<\/code><\/pre>\n\n\n\n<p><strong>Delete Directory<\/strong><\/p>\n\n\n\n<pre><code>FtpWebRequest deleteRequest = (FtpWebRequest)WebRequest.Create(fileUrl);\n                    deleteRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;\n                    deleteRequest.Credentials = credentials;\n\n                    FtpWebResponse response = (FtpWebResponse)deleteRequest.GetResponse();\n                    response.Close();<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post, we will explore how we can access FTP server and how we can download a file or complete folder based on&#8230;<\/p>\n","protected":false},"author":1,"featured_media":72,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[11,8,37,36],"class_list":["post-211","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dot-net-core","tag-dot-net-core","tag-dot-net-framework","tag-c","tag-ftp"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Working with FTP in .NET Core - Naveed Ul-Haq&#039;s blog<\/title>\n<meta name=\"description\" content=\"Working with FTP in .NET Core - how we can access the FTP server and how we can download a file or complete folder based on access rights.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Working with FTP in .NET Core - Naveed Ul-Haq&#039;s blog\" \/>\n<meta property=\"og:description\" content=\"Working with FTP in .NET Core - how we can access the FTP server and how we can download a file or complete folder based on access rights.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/\" \/>\n<meta property=\"og:site_name\" content=\"Naveed Ul-Haq&#039;s blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-24T19:04:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-01-24T19:04:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.naveedulhaq.com\/wp-content\/uploads\/2019\/04\/240px-.NET_Core_Logo.svg_.png\" \/>\n\t<meta property=\"og:image:width\" content=\"240\" \/>\n\t<meta property=\"og:image:height\" content=\"240\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Naveed Ul-Haq\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Naveed Ul-Haq\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/\"},\"author\":{\"name\":\"Naveed Ul-Haq\",\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/#\\\/schema\\\/person\\\/dd6db5980b965fcae41e096d357c65c9\"},\"headline\":\"Working with FTP in .NET Core\",\"datePublished\":\"2021-01-24T19:04:23+00:00\",\"dateModified\":\"2021-01-24T19:04:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/\"},\"wordCount\":304,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/#\\\/schema\\\/person\\\/dd6db5980b965fcae41e096d357c65c9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.naveedulhaq.com\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/240px-.NET_Core_Logo.svg_.png\",\"keywords\":[\".net core\",\".net framework\",\"c#\",\"ftp\"],\"articleSection\":[\".NET\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/\",\"url\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/\",\"name\":\"Working with FTP in .NET Core - Naveed Ul-Haq&#039;s blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.naveedulhaq.com\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/240px-.NET_Core_Logo.svg_.png\",\"datePublished\":\"2021-01-24T19:04:23+00:00\",\"dateModified\":\"2021-01-24T19:04:24+00:00\",\"description\":\"Working with FTP in .NET Core - how we can access the FTP server and how we can download a file or complete folder based on access rights.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.naveedulhaq.com\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/240px-.NET_Core_Logo.svg_.png\",\"contentUrl\":\"https:\\\/\\\/www.naveedulhaq.com\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/240px-.NET_Core_Logo.svg_.png\",\"width\":240,\"height\":240,\"caption\":\".net core\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/index.php\\\/dot-net-core\\\/working-with-ftp-in-net-core\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.naveedulhaq.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Working with FTP in .NET Core\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/#website\",\"url\":\"https:\\\/\\\/www.naveedulhaq.com\\\/\",\"name\":\"Naveed Ul-Haq's blog\",\"description\":\"AI, Optimizely, Azure &amp; more\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/#\\\/schema\\\/person\\\/dd6db5980b965fcae41e096d357c65c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.naveedulhaq.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.naveedulhaq.com\\\/#\\\/schema\\\/person\\\/dd6db5980b965fcae41e096d357c65c9\",\"name\":\"Naveed Ul-Haq\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g\",\"caption\":\"Naveed Ul-Haq\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g\"},\"description\":\"I lead engineering delivery teams for digital commerce and digital experience platforms, combining hands-on architecture experience with strong delivery governance. Over 20+ years, I\u2019ve built and led cross\u2011functional teams (engineering, BA, QA) delivering modern cloud solutions on Azure, microservices, APIs and eCommerce\\\/CMS platforms. My recent focus includes AI-enabled commerce automation: product ingestion and enrichment workflows, content optimisation for SEO and shopping feeds, and agentic tooling to improve marketing and accessibility workflows. I\u2019m passionate about building high-performing teams, establishing quality\\\/release standards, and delivering measurable outcomes across performance, reliability, and speed of change.\",\"sameAs\":[\"https:\\\/\\\/www.naveedulhaq.com\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/naveedulhaq\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Working with FTP in .NET Core - Naveed Ul-Haq&#039;s blog","description":"Working with FTP in .NET Core - how we can access the FTP server and how we can download a file or complete folder based on access rights.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/","og_locale":"en_GB","og_type":"article","og_title":"Working with FTP in .NET Core - Naveed Ul-Haq&#039;s blog","og_description":"Working with FTP in .NET Core - how we can access the FTP server and how we can download a file or complete folder based on access rights.","og_url":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/","og_site_name":"Naveed Ul-Haq&#039;s blog","article_published_time":"2021-01-24T19:04:23+00:00","article_modified_time":"2021-01-24T19:04:24+00:00","og_image":[{"width":240,"height":240,"url":"https:\/\/www.naveedulhaq.com\/wp-content\/uploads\/2019\/04\/240px-.NET_Core_Logo.svg_.png","type":"image\/png"}],"author":"Naveed Ul-Haq","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Naveed Ul-Haq","Estimated reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#article","isPartOf":{"@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/"},"author":{"name":"Naveed Ul-Haq","@id":"https:\/\/www.naveedulhaq.com\/#\/schema\/person\/dd6db5980b965fcae41e096d357c65c9"},"headline":"Working with FTP in .NET Core","datePublished":"2021-01-24T19:04:23+00:00","dateModified":"2021-01-24T19:04:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/"},"wordCount":304,"commentCount":1,"publisher":{"@id":"https:\/\/www.naveedulhaq.com\/#\/schema\/person\/dd6db5980b965fcae41e096d357c65c9"},"image":{"@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#primaryimage"},"thumbnailUrl":"https:\/\/www.naveedulhaq.com\/wp-content\/uploads\/2019\/04\/240px-.NET_Core_Logo.svg_.png","keywords":[".net core",".net framework","c#","ftp"],"articleSection":[".NET"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/","url":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/","name":"Working with FTP in .NET Core - Naveed Ul-Haq&#039;s blog","isPartOf":{"@id":"https:\/\/www.naveedulhaq.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#primaryimage"},"image":{"@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#primaryimage"},"thumbnailUrl":"https:\/\/www.naveedulhaq.com\/wp-content\/uploads\/2019\/04\/240px-.NET_Core_Logo.svg_.png","datePublished":"2021-01-24T19:04:23+00:00","dateModified":"2021-01-24T19:04:24+00:00","description":"Working with FTP in .NET Core - how we can access the FTP server and how we can download a file or complete folder based on access rights.","breadcrumb":{"@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#primaryimage","url":"https:\/\/www.naveedulhaq.com\/wp-content\/uploads\/2019\/04\/240px-.NET_Core_Logo.svg_.png","contentUrl":"https:\/\/www.naveedulhaq.com\/wp-content\/uploads\/2019\/04\/240px-.NET_Core_Logo.svg_.png","width":240,"height":240,"caption":".net core"},{"@type":"BreadcrumbList","@id":"https:\/\/www.naveedulhaq.com\/index.php\/dot-net-core\/working-with-ftp-in-net-core\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.naveedulhaq.com\/"},{"@type":"ListItem","position":2,"name":"Working with FTP in .NET Core"}]},{"@type":"WebSite","@id":"https:\/\/www.naveedulhaq.com\/#website","url":"https:\/\/www.naveedulhaq.com\/","name":"Naveed Ul-Haq's blog","description":"AI, Optimizely, Azure &amp; more","publisher":{"@id":"https:\/\/www.naveedulhaq.com\/#\/schema\/person\/dd6db5980b965fcae41e096d357c65c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.naveedulhaq.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/www.naveedulhaq.com\/#\/schema\/person\/dd6db5980b965fcae41e096d357c65c9","name":"Naveed Ul-Haq","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g","caption":"Naveed Ul-Haq"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/362536aba6cc66917d7558cacd015a81c7cdf1a69b9a28c994764847c487b692?s=96&d=mm&r=g"},"description":"I lead engineering delivery teams for digital commerce and digital experience platforms, combining hands-on architecture experience with strong delivery governance. Over 20+ years, I\u2019ve built and led cross\u2011functional teams (engineering, BA, QA) delivering modern cloud solutions on Azure, microservices, APIs and eCommerce\/CMS platforms. My recent focus includes AI-enabled commerce automation: product ingestion and enrichment workflows, content optimisation for SEO and shopping feeds, and agentic tooling to improve marketing and accessibility workflows. I\u2019m passionate about building high-performing teams, establishing quality\/release standards, and delivering measurable outcomes across performance, reliability, and speed of change.","sameAs":["https:\/\/www.naveedulhaq.com","https:\/\/www.linkedin.com\/in\/naveedulhaq\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/posts\/211","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/comments?post=211"}],"version-history":[{"count":0,"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/posts\/211\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/media\/72"}],"wp:attachment":[{"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/media?parent=211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/categories?post=211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.naveedulhaq.com\/index.php\/wp-json\/wp\/v2\/tags?post=211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}