();
+
+ foreach (var redirect in records)
+ {
+ if (_redirectRepository.FetchRedirectByOldUrl(redirect.OldUrl) is not { } existingRedirect)
+ {
+ try
+ {
+ _redirectRepository.AddRedirect(redirect.IsRegex, redirect.OldUrl, redirect.NewUrl, redirect.RedirectCode, redirect.Notes);
+ addedRedirects++;
+ }
+ catch (ArgumentException e)
+ {
+ redirect.Notes = e.Message;
+ errorList.Add(redirect);
+ }
+ }
+ else if(overwriteMatches && !existingRedirect.Equals(redirect))
+ {
+ redirect.Id = existingRedirect.Id;
+ try
+ {
+ _redirectRepository.UpdateRedirect(redirect);
+ updatedRedirects++;
+ }
+ catch (ArgumentException e)
+ {
+ redirect.Notes = e.Message;
+ errorList.Add(redirect);
+ }
+ }
+ else
+ existingRedirects++;
+ }
+
+ return ImportRedirectsResponse.FromImport(addedRedirects, updatedRedirects, existingRedirects, errorList.ToArray());
+ }
+}
\ No newline at end of file
diff --git a/source/SimpleRedirects.Core/Services/IImportExportService.cs b/source/SimpleRedirects.Core/Services/IImportExportService.cs
new file mode 100644
index 0000000..2c2dfb9
--- /dev/null
+++ b/source/SimpleRedirects.Core/Services/IImportExportService.cs
@@ -0,0 +1,10 @@
+using Microsoft.AspNetCore.Http;
+using SimpleRedirects.Core.Models;
+
+namespace SimpleRedirects.Core.Services;
+
+public interface IImportExportService
+{
+ DataRecordCollectionFile ExportDataRecordCollection();
+ ImportRedirectsResponse ImportRedirectsFromCollection(IFormFile file, bool overwriteMatches);
+}
\ No newline at end of file
diff --git a/source/SimpleRedirects.Core/Services/ImportExportFactory.cs b/source/SimpleRedirects.Core/Services/ImportExportFactory.cs
new file mode 100644
index 0000000..0702fb9
--- /dev/null
+++ b/source/SimpleRedirects.Core/Services/ImportExportFactory.cs
@@ -0,0 +1,19 @@
+using System;
+using SimpleRedirects.Core.Enums;
+
+namespace SimpleRedirects.Core.Services;
+
+public class ImportExportFactory
+{
+ private readonly IServiceProvider _serviceProvider;
+
+ public ImportExportFactory(IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ }
+
+ public IImportExportService GetDataRecordProvider(DataRecordProvider dataRecordProvider)
+ => dataRecordProvider == DataRecordProvider.Csv
+ ? (IImportExportService)_serviceProvider.GetService(typeof(CsvImportExportService))
+ : (IImportExportService)_serviceProvider.GetService(typeof(ExcelImportExportService));
+}
\ No newline at end of file
diff --git a/source/SimpleRedirects.Core/SimpleRedirects.Core.csproj b/source/SimpleRedirects.Core/SimpleRedirects.Core.csproj
index bbbf74c..27573ff 100644
--- a/source/SimpleRedirects.Core/SimpleRedirects.Core.csproj
+++ b/source/SimpleRedirects.Core/SimpleRedirects.Core.csproj
@@ -13,6 +13,8 @@
https://raw.githubusercontent.com/patrickdemooij9/SimpleRedirects/v9/main/package/simpleRedirectsLogo.png
+
+
diff --git a/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/Lang/en.xml b/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/Lang/en.xml
index b930345..33460f8 100644
--- a/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/Lang/en.xml
+++ b/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/Lang/en.xml
@@ -3,4 +3,8 @@
Redirects
+
+ Export to CSV
+ Export to Excel (.xlsx)
+
diff --git a/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/app.html b/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/app.html
index de7efbe..320a58f 100644
--- a/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/app.html
+++ b/source/SimpleRedirects.Site/App_Plugins/SimpleRedirects/app.html
@@ -9,13 +9,28 @@
Simple Redirects Manager
-
-
+
+
+
+
+
+
+
Cache Cleared!
-
+
+
+
+
+
+
+
+
+
+
+
Add, Update, and Delete redirects in the table below.
@@ -93,6 +108,8 @@ {{redirects.length}} rows
+
+