I have a razor pages handler
public IActionResult OnGetAddObjective(string newObjective)
{
ViewData["MyTestData"] = "hi";
return Partial("_ObjectiveRow", new ObjectiveViewModel { ObjectiveText = newObjective });
}
However, in the _ObjectiveRow partial, the ViewData is not being passed. I can't seem to find an overload that allows this. Which calling the partial on the main page, the ViewData from the parent is accessible.
How do I pass the ViewDataDictionary to the partial?
In ASP.NET Core Razor Pages, the Partial method itself does not support directly passing ViewData. While you cannot directly override the built-in Partial method, you can achieve similar functionality through alternative approaches to ensure that your partial views receive the necessary data.
1
Use a custom method PartialView
with PartialViewResult
to return a partial view:
namespace PartialDataReturnTest.Pages
{
public class TestModel : PageModel
{
public void OnGet() { }
public ObjectiveViewModel Model { get; set; }
public IActionResult OnGetPartial(string newObjective)
{
var model = new TestModel()
{
Model = new ObjectiveViewModel
{
ObjectiveText = newObjective
}
};
return PartialView("_ObjectiveRow", model);
}
[NonAction]
public virtual PartialViewResult PartialView(string viewName, object model)
{
ViewData.Model = model;
ViewData["MyTestData"] = "hi";
return new PartialViewResult()
{
ViewName = viewName,
ViewData = ViewData,
};
}
}
public class ObjectiveViewModel
{
public string ObjectiveText { get; set; }
}
}
In the Test.cshtml:
@page
@model PartialDataReturnTest.Pages.TestModel
<h1>AJAX Partial View Example</h1>
<button id="loadPartialButton">Load Partial View</button>
<div id="partialContainer"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#loadPartialButton').click(function() {
var data = "Some text";
$.ajax({
url: '@Url.Page("Test", "Partial")', // Adjust URL if necessary
type: 'GET',
data: {
newObjective: data
},
success: function(result) {
$('#partialContainer').html(result);
},
error: function() {
alert('Failed to load partial view.');
}
});
});
});
</script>
Then in the _ObjectiveRow
Partial:
@model PartialDataReturnTest.Pages.TestModel
@{
var myTestData = ViewData["MyTestData"];
}
<div>
<p>Test Data: @myTestData</p>
<p>Objective Text: @Model.Model.ObjectiveText</p>
</div>
2 Or you can use the Html.PartialAsync
in the page, refer to the tutorial Access data from partial views and the code example in this link.
Sample test:
public class Test2Model : PageModel
{
public ObjectiveViewModel Model { get; set; }
public void OnGet()
{
Model = new ObjectiveViewModel()
{
ObjectiveText = "Test text.",
};
}
}
In the Test2.cshtml:
@page
@model PartialDataReturnTest.Pages.Test2Model
@{
var viewData = new ViewDataDictionary(ViewData)
{
["MyTestData"] = "Hi."
};
}
<h1>Partial View Example2</h1>
@await Html.PartialAsync("_ObjectiveRow1", Model, viewData)
In the _ObjectiveRow1
Partial:
@model PartialDataReturnTest.Pages.Test2Model
@{
var myTestData = ViewData["MyTestData"];
}
<div>
<p>Test Data: @myTestData</p>
<p>Objective Text:@Model.Model.ObjectiveText </p>
</div>
The Test2 Result: