Home > OS >  Pass Model from Partial View to the PageModel in Asp.Net Core Razor
Pass Model from Partial View to the PageModel in Asp.Net Core Razor

Time:01-07

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();
}

Test Result: enter image description here enter image description here

  • Related