This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -48,7 +48,7 @@
|
|||||||
"AYANOVA_DATA_PATH": "c:\\temp\\ravendata",
|
"AYANOVA_DATA_PATH": "c:\\temp\\ravendata",
|
||||||
"AYANOVA_USE_URLS": "http://*:7575;",
|
"AYANOVA_USE_URLS": "http://*:7575;",
|
||||||
//"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true",
|
//"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true",
|
||||||
"AYANOVA_SERVER_TEST_MODE": "true",
|
"AYANOVA_SERVER_TEST_MODE": "false",
|
||||||
"AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-8",
|
"AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-8",
|
||||||
//"AYANOVA_REPORT_RENDERING_TIMEOUT":"1",
|
//"AYANOVA_REPORT_RENDERING_TIMEOUT":"1",
|
||||||
"AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small",
|
"AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small",
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Bogus" Version="34.0.1" />
|
<PackageReference Include="Bogus" Version="34.0.1" />
|
||||||
<PackageReference Include="BouncyCastle.NetCore" Version="1.8.10" />
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.8.10" />
|
||||||
<PackageReference Include="ChoETL.JSON.NETStandard" Version="1.2.1.42" />
|
|
||||||
<PackageReference Include="Enums.NET" Version="4.0.0" />
|
<PackageReference Include="Enums.NET" Version="4.0.0" />
|
||||||
<PackageReference Include="jose-jwt" Version="3.2.0" />
|
<PackageReference Include="jose-jwt" Version="3.2.0" />
|
||||||
<PackageReference Include="MailKit" Version="3.1.1" />
|
<PackageReference Include="MailKit" Version="3.1.1" />
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ using AyaNova.Util;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
|
||||||
using ChoETL;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace AyaNova.Api.Controllers
|
namespace AyaNova.Api.Controllers
|
||||||
@@ -46,11 +44,10 @@ namespace AyaNova.Api.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Export to file
|
/// Export to file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">Valid values are: "csv","json"</param>
|
|
||||||
/// <param name="selectedRequest"></param>
|
/// <param name="selectedRequest"></param>
|
||||||
/// <returns>downloadable export file name</returns>
|
/// <returns>downloadable export file name</returns>
|
||||||
[HttpPost("render/{format}")]
|
[HttpPost("render")]
|
||||||
public async Task<IActionResult> RenderExport([FromRoute] string format, [FromBody] DataListSelectedRequest selectedRequest)
|
public async Task<IActionResult> RenderExport([FromBody] DataListSelectedRequest selectedRequest)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!serverState.IsOpen)
|
if (!serverState.IsOpen)
|
||||||
@@ -64,12 +61,6 @@ namespace AyaNova.Api.Controllers
|
|||||||
if (!Authorized.HasReadFullRole(HttpContext.Items, selectedRequest.AType))
|
if (!Authorized.HasReadFullRole(HttpContext.Items, selectedRequest.AType))
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(format))
|
|
||||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "format required"));
|
|
||||||
|
|
||||||
if (format != "csv" && format != "json")
|
|
||||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_INVALID_VALUE, null, "format not valid, must be 'csv' or 'json'"));
|
|
||||||
|
|
||||||
|
|
||||||
var UserId = UserIdFromContext.Id(HttpContext.Items);
|
var UserId = UserIdFromContext.Id(HttpContext.Items);
|
||||||
var UserRoles = UserRolesFromContext.Roles(HttpContext.Items);
|
var UserRoles = UserRolesFromContext.Roles(HttpContext.Items);
|
||||||
@@ -89,48 +80,27 @@ namespace AyaNova.Api.Controllers
|
|||||||
log.LogDebug($"Instantiating biz object handler for {selectedRequest.AType}");
|
log.LogDebug($"Instantiating biz object handler for {selectedRequest.AType}");
|
||||||
var biz = BizObjectFactory.GetBizObject(selectedRequest.AType, ct, UserId, UserRoles, UserTranslationId);
|
var biz = BizObjectFactory.GetBizObject(selectedRequest.AType, ct, UserId, UserRoles, UserTranslationId);
|
||||||
log.LogDebug($"Fetching data for {selectedRequest.SelectedRowIds.Length} {selectedRequest.AType} items");
|
log.LogDebug($"Fetching data for {selectedRequest.SelectedRowIds.Length} {selectedRequest.AType} items");
|
||||||
string baseFileName = FileUtil.StringToSafeFileName($"{selectedRequest.AType.ToString().ToLowerInvariant()}-{format}-{FileUtil.GetSafeDateFileName()}");
|
string baseFileName = FileUtil.StringToSafeFileName($"{selectedRequest.AType.ToString().ToLowerInvariant()}-{FileUtil.GetSafeDateFileName()}");
|
||||||
string outputSourceFileName = baseFileName + "." + format;
|
string outputSourceFileName = baseFileName + ".json";
|
||||||
string outputSourceFullPath = System.IO.Path.Combine(FileUtil.TemporaryFilesFolder, outputSourceFileName);
|
string outputSourceFullPath = System.IO.Path.Combine(FileUtil.TemporaryFilesFolder, outputSourceFileName);
|
||||||
string outputZipFullpath = System.IO.Path.Combine(FileUtil.TemporaryFilesFolder, baseFileName + ".zip");
|
|
||||||
|
|
||||||
log.LogDebug($"Calling render export data to file {outputZipFullpath}");
|
log.LogDebug($"Calling render export data to file {outputSourceFullPath}");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (format)
|
using (StreamWriter file = System.IO.File.CreateText(outputSourceFullPath))
|
||||||
|
using (JsonTextWriter writer = new JsonTextWriter(file))
|
||||||
{
|
{
|
||||||
case "csv":
|
var dat = await ((IExportAbleObject)biz).GetExportData(selectedRequest, Guid.Empty);//todo: jobify
|
||||||
using (var w = new ChoCSVWriter(outputSourceFullPath).WithFirstLineHeader().ThrowAndStopOnMissingField(false).WithMaxScanRows(100))
|
dat.WriteTo(writer);
|
||||||
{
|
|
||||||
//max scan rows means how many rows it will scan to determine field types so this affects tags because it will scan the first 100 to see the maximum tag count then only ever output that many
|
|
||||||
var dat = await ((IExportAbleObject)biz).GetExportData(selectedRequest, Guid.Empty);//todo: jobify
|
|
||||||
w.Write(ToDynamicList(dat));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "json":
|
|
||||||
using (StreamWriter file = System.IO.File.CreateText(outputSourceFullPath))
|
|
||||||
using (JsonTextWriter writer = new JsonTextWriter(file))
|
|
||||||
{
|
|
||||||
var dat = await ((IExportAbleObject)biz).GetExportData(selectedRequest, Guid.Empty);//todo: jobify
|
|
||||||
dat.WriteTo(writer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//zip it
|
|
||||||
using (FileStream fs = new FileStream(outputZipFullpath, FileMode.Create))
|
|
||||||
using (ZipArchive arch = new ZipArchive(fs, ZipArchiveMode.Create))
|
|
||||||
{
|
|
||||||
arch.CreateEntryFromFile(outputSourceFullPath, outputSourceFileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.LogDebug($"Completed, returning results");
|
log.LogDebug($"Completed, returning results");
|
||||||
return Ok(ApiOkResponse.Response(baseFileName + ".zip"));
|
return Ok(ApiOkResponse.Response(outputSourceFileName));
|
||||||
}
|
}
|
||||||
catch (ReportRenderTimeOutException)
|
catch (ReportRenderTimeOutException)
|
||||||
{
|
{
|
||||||
log.LogInformation($"RenderExport timeout data list key: {selectedRequest.DataListKey}, record count:{selectedRequest.SelectedRowIds.LongLength}, user:{UserNameFromContext.Name(HttpContext.Items)} ");
|
log.LogInformation($"RenderExport timeout data list key: {selectedRequest.DataListKey}, record count:{selectedRequest.SelectedRowIds.LongLength}, user:{UserNameFromContext.Name(HttpContext.Items)} ");
|
||||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "timeout - select fewer records"));
|
return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "timeout - select fewer records"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +143,9 @@ namespace AyaNova.Api.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
var FilePath = FileUtil.GetFullPathForTemporaryFile(fileName);
|
var FilePath = FileUtil.GetFullPathForTemporaryFile(fileName);
|
||||||
return PhysicalFile(FilePath, "application/zip");
|
|
||||||
|
//including the file name triggers save automatically "attachment" rather than viewing it "inline"
|
||||||
|
return PhysicalFile(FilePath, "application/json", fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user