You should be using async file and database calls, or you will limit scaling.
It also looks like you write a file, then read it back. And why the extra memory copy?
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
I work on asp.net core 2.2 web API using C# language
I need to rewrite function below with best syntax and with best practice
web API below get Excel file from upload and return Excel file
it working without any issue but I need to rewrite it with best syntax and practice
some points I need to changes :
concatenate path is best thing using
are streaming using correctly
are memory copying file is correct
[HttpPost, DisableRequestSizeLimit]
[Route("Upload")]
public IActionResult Upload()
{
try
{
var DisplayFileName = Request.Form.Files[0];
string fileName = DisplayFileName.FileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
string Month = DateTime.Now.Month.ToString();
string DirectoryCreate = myValue1 + "\\" + Month + "\\" + fileName;
string exportDirectory = myValue2 + "\\" + Month;
string exportPath = myValue2 + "\\" + Month + "\\" + fileName;
string FinalPath = exportPath;
if (!Directory.Exists(DirectoryCreate))
{
Directory.CreateDirectory(DirectoryCreate);
}
if (!Directory.Exists(exportDirectory))
{
Directory.CreateDirectory(exportDirectory);
}
CExcel ex = new CExcel();
if (DisplayFileName.Length > 0)
{
var filedata = ContentDispositionHeaderValue.Parse(Request.Form.Files[0].ContentDisposition).FileName.Trim('"');
var dbPath = Path.Combine(DirectoryCreate, fileName);
using (var stream = new FileStream(dbPath, FileMode.Create))
{
Request.Form.Files[0].CopyTo(stream);
stream.Flush();
stream.Close();
}
GC.Collect();
string error = "";
int rowCount = 0;
string inputTemplatePath = "";
var InputfilePath = System.IO.Path.Combine(GetFilesDownload, "DeliveryGeneration_Input.xlsx");
bool areIdentical = ex.CompareExcel(dbPath, InputfilePath, out rowCount, out error);
if (areIdentical == true)
{
List<InputExcel> inputexcellist = new List<InputExcel>();
inputexcellist = ex.Import(dbPath);
List<string> mods = new List<string>();
mods = inputexcellist.Select(x => x.ModuleName).Distinct().ToList();
var OutputfilePath = System.IO.Path.Combine(GetFilesDownload, "DeliveryGeneration_Output.xlsx");
if (System.IO.Directory.Exists(Path.Combine(exportDirectory, fileName)))
{
throw new Exception("Ok so the error message IS right.");
}
System.IO.File.Copy(OutputfilePath, Path.Combine(exportDirectory, fileName), true);
SqlConnection con;
foreach (var m in mods)
{
List<InputExcel> inputmodulelist = new List<InputExcel>();
inputmodulelist = inputexcellist.Where(x => x.ModuleName == m).ToList();
var dtimport = DatatableConversion.ToDataTable(inputmodulelist);
DataTable dtexport = new DataTable();
dtexport = _deliveryService.LoadExcelToDataTable(_connectionString, dtimport);
ex.Export(dtexport, m, exportPath);
}
}
var memory2 = new MemoryStream();
using (var stream = new FileStream(exportPath, FileMode.Open))
{
stream.CopyTo(memory2);
}
memory2.Position = 0;
return File(memory2, "text/plain", Path.GetFileName(exportPath));
}
else
{
return BadRequest();
}
}
catch (Exception ex)
{
return StatusCode(500, $"Internal server error: {ex}");
}
}
You should be using async file and database calls, or you will limit scaling.
It also looks like you write a file, then read it back. And why the extra memory copy?
Hi @ahmed salah ,
can you please see me how to use async task on web api above
To convert the Upload method to the async method, you can refer the following sample:
in the service methods: from your code, since you are using _deliveryService to call the database, you can change the code as below:
public interface IDeliveryService
{
Task<string> LoadExcelToDataTableAsync(string connectionstring, string inport);
}
public class DeliveryService : IDeliveryService
{
private readonly ApplicationDbContext _context;
public DeliveryService(ApplicationDbContext context)
{
_context = context;
}
public async Task<string> LoadExcelToDataTableAsync(string connectionstring, string inport)
{
// do something
//access the database via _context.
return await Task.FromResult<string>("OK");
}
}
In the above code, I access the database via EF code, more detail you can refer this article.
Then, in the controller, the code as below:
private readonly IDeliveryService _deliveryService;
public HomeController(IDeliveryService deliveryService)
{
_deliveryService = deliveryService;
}
public async Task<IActionResult> UploadAsync()
{
var result = await _deliveryService.LoadExcelToDataTableAsync("connection", "inport");
return View();
}
More detail information about asynchronous programming, see Asynchronous programming with async and await.
Besides, here is an article about ASP.NET Core Performance Best Practices, you can refer it.
If the answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion