Hello,
Because the header names of the CSV file do not exactly match the expected header names in the code. Specifically:
Expected header names: Date, Open, High, Low, Close, SharesTraded
Actual header names: Date, Open, High, Low, Close, Shares Traded, Turnover
As you can see, the actual header names contain extra spaces (e.g. Date instead of Date), and SharesTraded is written as Shares Traded (with a space in between).
If you cannot change the value of CSV file, you can Ignore header validation errors and Ignore missing headers by setting CsvConfiguration in LoadCsvFromString method.
public IEnumerable<StockData> LoadCsvFromString(string csvData)
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
// Ignore header validation errors
HeaderValidated = null,
// Ignore missing headers
MissingFieldFound = null
};
using (var reader = new StringReader(csvData))
using (var csv = new CsvReader(reader, config))
{
return csv.GetRecords<StockData>().ToList();
}
}
And I find <input >
tag cannot set the InputFileChangeEventArgs
, I change it to <InputFile>
tag, and use <label> to warp it, you do not need to add TriggerFileInput method to implement the click event.
@inject CsvService CsvService
<PageTitle>Stock Data</PageTitle>
<h3>Stock Data</h3>
<label class="btn btn-primary">
<InputFile style="display: none" OnChange="OnFileChange" />
Choose csv File
</label>
@if (stockData == null)
{
<p>Loading...</p>
}
else
{
<table>
<thead>
<tr>
<th>Date</th>
<th>Open</th>
<th>High</th>
<th>Low</th>
<th>Close</th>
<th>Shares Traded</th>
<th>Turnover</th>
</tr>
</thead>
<tbody>
@foreach (var data in stockData)
{
<tr>
<td>@data.Date.ToShortDateString()</td>
<td>@data.Open</td>
<td>@data.High</td>
<td>@data.Low</td>
<td>@data.Close</td>
<td>@data.SharesTraded</td>
<td>@data.Turnover</td>
</tr>
}
</tbody>
</table>
}
@code {
private IEnumerable<StockData> stockData;
private async Task OnFileChange(InputFileChangeEventArgs e)
{
var file = e.File;
if (file != null)
{
using var stream = file.OpenReadStream();
using var reader = new StreamReader(stream);
var csvData = await reader.ReadToEndAsync();
stockData = await Task.Run(() => CsvService.LoadCsvFromString(csvData));
}
}
}
Best Regards,
Leon Lu
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
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.