I am trying to pass a Model from a Partial view back to the PageModel, but the results are always empty. In my main .cshtml, I have an 'Export' button that when clicked opens a bootstrap modal. Users then click a checkbox to select data to download. Here is my code:
In my cs, I set the partial with this code:
// FileContents contains a list of FileObjects (which include Name as IsSelected)
[BindProperty]
public FileContents ExportData { get; set; }
// Get method to return the partial.
// ExportData is passed as the model for the partial
public PartialViewResult OnGetExportModel()
{
ExportData = new FileContents();
ExportData.Files.Add(new FileObject("filename.txt", true);
return Partial("_ExportDetails", ExportData);
}
// Handles postback of the FileContents data
public IActionResult OnPostExportData(FileContents data)
{
//The count is always zero
Console.WriteLine(data.Files.Count);
}
The partial is a table with the file name and a checkbox:
@model FileContents
<div >
<table>
<tbody>
@foreach (var item in Model.Files)
{
<tr>
<td data-item="@item.Name">
@Html.CheckBoxFor(modelItem => item.IsSelected)
</td>
<td>@item.Name</td>
</tr>
}
</tbody>
</table>
</div>
In the main page .cshtml, I display the partial:
<div id="exportPartial"></div>
The partial is set with a class from a script:
function ScriptExport() {
$('.dvExport').load('/index/exportmodel);
}
I have tried several ways to pass the FileContents model of the partial, back to the .cs file.
- One by using a
<form method=post" asp-page-handler="ExportData" asp-route-data="@Model.ExportData">
. When returned,data.Files
is empty. - Second by calling an ajax postback. When serializing @Model.ExportData, the files are also empty.
How can I return FileContents model in the partial back to my main page?
CodePudding user response:
I did a test using ajax, you can refer to my code below:
_ExportDetails.cshtml:
@model FileContents
<div >
<table>
<tbody>
@foreach (var item in Model.Files)
{
<tr>
<td data-item="@item.Name">
@Html.CheckBoxFor(modelItem => item.IsSelected)
</td>
//Add a class as an identifier
<td >@item.Name</td>
</tr>
}
</tbody>
</table>
</div>
Index.cshtml:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<button type="button" onclick="ScriptExport()">ScriptExport</button>
<button type="button" onclick="ScriptSubmit()">Submit</button>
<div id="exportPartial"></div>
//Required
<div>@Html.AntiForgeryToken()</div>
<script>
function ScriptExport() {
$('.dvExport').load('index?handler=ExportModel');
}
function ScriptSubmit(){
var data = [];
$("table > tbody > tr").each(function() {
var Files = {
Name: $(this).find('.Name').text(),
IsSelected: $(this).find("input[type='checkbox']").prop("checked")
}
data.push(Files);
});
$.ajax({
type: "post",
url: "/index?handler=ExportData",
data: JSON.stringify({ Files: data }),
//Required
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
contentType: "application/json; charset=utf-8",
success: function(result)
{
alert("success");
},
error: function(error)
{
console.log(error);
}
});
}
</script>
Index.cshtml.cs:
public IActionResult OnPostExportData([FromBody]FileContents data)
{
Console.WriteLine(data.Files.Count);
return Page();
}