-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added csv export
- Loading branch information
Showing
6 changed files
with
112 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/BUTR.Site.NexusMods.Server/Utils/Csv/Extensions/MvcOptionsExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using BUTR.Site.NexusMods.Server.Utils.Csv.Utils; | ||
|
||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Formatters; | ||
|
||
using System; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
|
||
namespace BUTR.Site.NexusMods.Server.Utils.Csv.Extensions; | ||
|
||
[ExcludeFromCodeCoverage] | ||
public static class MvcOptionsExtensions | ||
{ | ||
public static void AddCsvOutputFormatters(this MvcOptions options) | ||
{ | ||
var types = typeof(Program).Assembly.GetTypes().Where(t => t.IsAssignableTo(typeof(ICsvFile)) && !t.IsAbstract); | ||
foreach (var type in types) | ||
options.OutputFormatters.Insert(0, (IOutputFormatter) Activator.CreateInstance(typeof(ExportOutputFormatter<>).MakeGenericType(type))!); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace BUTR.Site.NexusMods.Server.Utils.Csv; | ||
|
||
public interface ICsvFile | ||
{ | ||
static abstract string GenerateFilename(); | ||
} |
65 changes: 65 additions & 0 deletions
65
src/BUTR.Site.NexusMods.Server/Utils/Csv/Utils/ExportOutputFormatter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using CsvHelper; | ||
|
||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Mvc.Formatters; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace BUTR.Site.NexusMods.Server.Utils.Csv.Utils; | ||
|
||
public class ExportOutputFormatter<TCsvFile> : TextOutputFormatter where TCsvFile: ICsvFile | ||
{ | ||
private static string ContentType => "text/csv"; | ||
|
||
public ExportOutputFormatter() | ||
{ | ||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(ContentType)); | ||
|
||
SupportedEncodings.Add(Encoding.UTF8); | ||
SupportedEncodings.Add(Encoding.Unicode); | ||
} | ||
|
||
protected override bool CanWriteType(Type? type) | ||
{ | ||
if (typeof(TCsvFile).IsAssignableFrom(type) || typeof(IEnumerable<TCsvFile>).IsAssignableFrom(type)) | ||
return base.CanWriteType(type); | ||
return false; | ||
} | ||
|
||
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) | ||
{ | ||
var (data, type) = context.Object switch | ||
{ | ||
IEnumerable<TCsvFile> enumerable => (enumerable, enumerable.GetType().GetGenericArguments()[0]), | ||
TCsvFile entry => (new List<TCsvFile> { entry }, entry.GetType()), | ||
_ => default | ||
}; | ||
if (data is null || type is null) | ||
throw new InvalidOperationException("Invalid csv data type!"); | ||
|
||
await WriteCsvCollection(context.HttpContext, data, selectedEncoding); | ||
} | ||
|
||
private static async Task WriteCsvCollection(HttpContext context, IEnumerable<TCsvFile> entries, Encoding selectedEncoding) | ||
{ | ||
var response = context.Response; | ||
|
||
response.Headers.ContentDisposition = new System.Net.Mime.ContentDisposition | ||
{ | ||
FileName = TCsvFile.GenerateFilename(), | ||
Inline = false, | ||
}.ToString(); | ||
|
||
await using var csv = new CsvWriter(new StreamWriter(response.Body, selectedEncoding), CultureInfo.InvariantCulture); | ||
|
||
csv.WriteHeader<TCsvFile>(); | ||
await csv.NextRecordAsync(); | ||
await csv.WriteRecordsAsync(entries); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters