need your thoughts on how the following can be implemented. I need to process on the OnPost a list of <string,file> objects and do some business logic after, but at this stage, I am unsure of how to implement it either using RazorPages logic or what was usually done with MVC.
At this stage what I can't do is to get on OnPostAsync the picked values on selectedCompany and inputFile, which I was expecting to come from the formData.
Any thoughts? TY
View
(...)
<form method="post" enctype="multipart/form-data">
<div >
<table id="filesToProcess">
<tr>
<td>
<div >
<select>
<option value="" name="selectedCompany">Pick a company ...</option>
@foreach (var company in Model.Companies)
{
<option value="@company.Id">@company.Name</option>
}
</select>
</div>
</td>
<td>
<div >
<div>
<input type="file" name="inputFile" />
</div>
</div>
<td>
</tr>
</table>
</div>
<button type="submit" style="width:150px">Calculate</button>
</form>
(...)
ViewModel
public class CalculatorModel : PageModel
{
private IHostingEnvironment _environment;
private ICompaniesService _companyService;
private IIndicatorsService _indicatorsService;
//To be presented on the front-end
public List<CompanyDto> Companies { get; set; }
//The initial idea would be that one row on the table of the front-end corresponds to one instance of IndicatorsRequest
[BindProperty]
public List<IndicatorsRequest> IndicatorsRequests { get; set; }
public class IndicatorsRequest
{
public Guid CompanyGuid { get; set; }
public IFormFile File { get; set; }
public List<IndicatorDto> CalculatedIndicators { get; set; }
}
public CalculatorModel(IHostingEnvironment environment, ICompaniesService companyService, IIndicatorsService indicatorsService)
{
_environment = environment;
_companyService = companyService;
_indicatorsService = indicatorsService;
}
public async Task OnGet()
{
Companies = await this._companyService.GetCompanies();
}
public async Task OnPostAsync(IFormCollection formData)
{
try
{
var selectedCompanies = formData.Where(f => f.Key.Contains("selectedCompany")).ToList();
var inputFiles = formData.Where(f => f.Key.Contains("inputFile")).ToList();
//Do some business logic with provided companies and files;
}
catch (Exception ex)
{
throw ex;
}
}
}
CodePudding user response:
Solution - https://www.learnrazorpages.com/razor-pages/model-binding#binding-complex-collections
View
The '0' on [0].CompanyGuid and [0].File has obviously to be an auto-generated sequencial number.
<td>
<div >
<select name="[0].CompanyGuid"> <<<<<<<<<<<<<<<
<option value="">Pick a company ...</option>
@foreach (var company in Model.Companies)
{
<option value="@company.Id">@company.Name</option>
}
</select>
</div>
</td>
<td>
<div >
<div>
<input type="file" name="[0].File" /> <<<<<<<<<<<<<
</div>
</div>
<td>
ViewModel
public async Task OnPostAsync(List<IndicatorsRequest> requests)
{
Console.WriteLine(requests.ElementAt(0).CompanyGuid);
}
public class IndicatorsRequest
{
public Guid CompanyGuid { get; set; }
public IFormFile File { get; set; }
}