I'm assuming you already have a Customer class that represents your database entities. You can create a second class e.g. CustomerDto that will be used to serialize the CSV entries to objects. Then you can map CustomerDtos to Customers using AutoMapper.
public class CustomerDto
{
[Name("Name")]
public string Name { get; set; }
[Name("Address")]
public string Address { get; set; }
[Name("DOB")]
public DateTime? DateOfBirth { get; set; }
}
Use an IFormFile property in your PageModel to receive the file that will be posted from the form.
Import.cshtml.cs:
using AutoMapper;
using CsvHelper;
using System.Linq;
...
public class ImportModel : PageModel
{
private readonly IMapper _mapper;
public ImportModel(IMapper mapper)
{
_mapper = mapper;
}
[BindProperty]
public IFormFile CustomersCsv { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (CustomersCsv != null)
{
try
{
using (var reader = new StreamReader(CustomersCsv.OpenReadStream()))
using (var csvr = new CsvReader(reader))
{
csvr.Configuration.Delimiter = "\t";
//csvr.Configuration.HeaderValidated = null;
//csvr.Configuration.MissingFieldFound = null;
var customerDtos = csvr.GetRecords<CustomerDto>().ToList();
var customers = _mapper.Map<IEnumerable<Customer>>(customerDtos);
// save customers to database
}
}
catch (Exception ex)
{
// handle exception
}
}
}
}
Import.cshtml:
<form method="post" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CustomersCsv" class="form-label"></label>
<input asp-for="CustomersCsv" class="form-control" />
<span asp-validation-for="CustomersCsv" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</form>