Search code examples
c#razorrazor-pagescsvhelper

ASP.NET Core - How do I upload a CSV file and convert the rows into Objects in DB?


Im new to ASP.NET Core and am tasked with creating an app that can import CSV files and basically convert the rows into Data Objects.

Ex.

Import CSV with Name Address and DOB Insert each record into Customer object

This needs to be done from a user uploading the CSV to the web app, so uploading the CSV straight to the SQL DB will not work.

Im curious how I approach this as I am new to ASP.NET Core and Razor pages.


Solution

  • 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>