I have an ASP.NET Core 7 MVC app which is showing unexpected behavior while using return view()
and return RedirectToAction
with combination of Ajax. Let me show the relevant code first, then I will share replication steps of the problem.
This is my view Index.cshtml
:
@model NoSql_MVC_Core.Models.Product.ProductInfo
@{
ViewData["Title"] = "Home Page";
}
<div class="container container-fluid">
<p>Total : @Model.Total</p>
<p>Skip : @Model.Skip</p>
<p>Limit : @Model.Limit</p>
<table id="products" class="table table-bordered table-striped">
<thead>
<tr class="table-dark">
<th>Title</th>
<th>Description</th>
<th>Price</th>
<th>discountPercentage</th>
<th>Rating</th>
<th>Stock</th>
<th>Brand</th>
<th>Category</th>
<th>Thumbnail</th>
</tr>
</thead>
<tbody>
@if(Model!= null && Model.Products != null && Model.Products.Count > 0)
{
foreach(var item in Model.Products)
{
<tr>
<td>@item.Title</td>
<td>@item.Description</td>
<td>@item.Price</td>
<td>@item.DiscountPercentage</td>
<td>@item.Rating</td>
<td>@item.Stock</td>
<td>@item.Brand</td>
<td>@item.Category</td>
<td><img src="@item.Thumbnail" style="width:120px;height:80px"></td>
</tr>
}
}
else
{
<tr>
<td colspan="9" class="text-center">No Records</td>
</tr>
}
</tbody>
</table>
</div>
@section Scripts
{
<script type="text/javascript" src="~/js/scripts/products.js"></script>
}
And this is my controller:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index(ProductInfo productInfo)
{
return View(productInfo);
}
[HttpPost]
public IActionResult LoadProducts([FromBody] ProductInfo productInfo)
{
return RedirectToAction("Index", "Home", productInfo);
}
}
Here is my product.js
code file:
$(document).ready(function () {
GetProducts();
});
function GetProducts() {
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "https://dummyjson.com/products",
dataType: "json",
async: false,
success: function (Result) {
var productsInfo = {};
if (Result) {
productsInfo.total = Result.total;
productsInfo.skip = Result.skip;
productsInfo.limit = Result.limit;
productsInfo.products = Result.products;
LoadProducts(productsInfo);
}
else {
}
},
error: function (e) {
if (e.status != 200) {
alert("error " + e.status + ' : ' + e.statusText);
}
}
});
}
function LoadProducts(param) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Home/LoadProducts",
data: JSON.stringify(param),
dataType: "json",
contentType: 'application/json; charset=utf-8',
async: false,
success: function (Result) {
if (Result) {
}
else {
}
},
error: function (e) {
if (e.status == 200) {
}
if (e.status != 200) {
alert("error " + e.status + ' : ' + e.statusText);
}
},
complete: function (e) {
}
});
}
These are my model classes:
public class ProductInfo
{
public List<Product> Products { get; set; }
public int Total { get; set; }
public int Skip { get; set; }
public int Limit { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Decimal Price { get; set; }
public float DiscountPercentage { get; set; }
public float Rating { get; set; }
public int Stock { get; set; }
public string Brand { get; set; }
public string Category { get; set; }
public string Thumbnail { get; set; }
public string[] Images { get; set; }
}
In my application, on page load, first js function GetProducts()
is invoked within document.ready
(refer to the product.js
file). It's actually hitting a dummy API to get some data.
Once it get the data, it calls LoadProducts()
method from the same js file.
Within LoadProducts
, I am making an Ajax call to the action method LoadProducts()
on my controller, and passing the data as post request body.
Now within the ASP.NET Core MVC action method, if I use return view()
, then it does not refresh the page:
[HttpPost]
public IActionResult LoadProducts([FromBody] ProductInfo productInfo)
{
return View("Index", productInfo);
}
Is this approach is wrong, will it not reload the page with data?
If I use return RedirectToAction
, then it does invoke the index.cshtml
file, debugger moves to razor syntax but this time it lost data partially in view.
[HttpPost]
public IActionResult LoadProducts([FromBody] ProductInfo productInfo)
{
return RedirectToAction("Index", "Home", productInfo);
}
Here we can see jQuery Ajax has posted data to action method and now we will do RedirectToAction
and
Once the control moved within Index, value for Limit, SKip And Total is there only for products it became as count zero. Product is a List of Type Product
and its content lost while doing redirect to action.
Although the value of Limit, SKip and Total was there in Index action method but at view it get displayed as zero always
So the question is: if I use Ajax and transport data to action method than will it ignore to re-render the view despite calling the return view()
statement
And if jQuery post to another method like we did here, Ajax posted to loadproducts and loadproducts invoke index with redirect to action statement, how does value get lost only for one property and view still not getting updated for other properties?
Is this approach incorrect? If yes, then what improvements can I make?