jquery RedirectToAction时丢失的价值

gijlo24d  于 2023-04-29  发布在  jQuery
关注(0)|答案(1)|浏览(138)

我有一个ASPNET Core 7 MVC应用程序在使用return view()return RedirectToAction与 AJAX 组合时显示意外行为。让我先展示相关的代码,然后我将分享问题的复制步骤。
以下是我的观点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>
}

这是我的控制器:

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

下面是我的product.js代码文件:

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

这些是我的模型类:

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

在我的应用程序中,在页面加载时,第一个js函数GetProducts()document.ready中被调用(参见product.js文件)。它实际上是通过一个虚拟API来获取一些数据。
获取数据后,它从同一个js文件调用LoadProducts()方法。
LoadProducts中,我对控制器上的action方法LoadProducts()进行 AJAX 调用,并将数据作为post请求体传递。
现在在ASP。NET Core MVC action方法,如果我使用return view(),那么它不会刷新页面:

[HttpPost]
public IActionResult LoadProducts([FromBody] ProductInfo productInfo)
{
    return View("Index", productInfo);
}

是不是这种方法是错误的,会不会不重新加载页面数据呢?
如果我使用return RedirectToAction,那么它确实调用了index.cshtml文件,调试器将移动到剃刀语法,但这一次它在视图中丢失了部分数据。

[HttpPost]
public IActionResult LoadProducts([FromBody] ProductInfo productInfo)
{
    return RedirectToAction("Index", "Home", productInfo);
}

在这里我们可以看到jQuery AJAX 已经将数据发布到action方法,现在我们将执行RedirectToAction

一旦控制在索引内移动,则限制、跳过和总计的值仅对于其变为计数零的产品存在。Product是一个类型为Product的列表,其内容在重定向到操作时丢失。

尽管限制、跳过和总计的值在索引操作方法中存在,但在视图中它总是显示为零
所以问题是:如果我使用 AJAX 和transport data to action方法,那么尽管调用了return view()语句,它还是会忽略重新呈现视图
如果jQuery像我们在这里一样发布到另一个方法, AJAX 发布到loadproducts,loadproducts调用索引并使用重定向到action语句,那么为什么只有一个属性的值丢失,而其他属性的视图仍然没有更新呢?
这种做法是否不正确?如果是的话,我可以做些什么改进呢?

5vf7fwbs

5vf7fwbs1#

不能直接从 AJAX 呈现视图。在你的情况下,我想你可以用局部视图来实现,请参考这个demo。
我创建了两个局部视图:

_PartialForm。csthml

@model ProductInfo

@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>
}

**_PartialHead.简体中文

@model ProductInfo

@if (Model != null)
{
    <p>Total : @Model.Total</p>
    <p>Skip : @Model.Skip</p>
    <p>Limit : @Model.Limit</p>
}
else
{
    <p>Total : null</p>
    <p>Skip : null</p>
    <p>Limit : null</p>
}

然后更改索引视图,如:

<div class="container container-fluid">

    <div id="partialViewHeader">       
    </div>
    
    <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 id="partialViewForm">           
                      
        </tbody>
    </table>
</div>

控制器/动作

[HttpPost]
        public IActionResult LoadProductsHead([FromBody] ProductInfo productInfo)
        {
            return PartialView("_PartialHead", productInfo);
        }

        [HttpPost]
        public IActionResult LoadProductsFrom([FromBody] ProductInfo productInfo)
        {
            return PartialView("_PartialForm", productInfo);
        }

最后,在JavaScript代码中,我写了将发送两 AJAX 到上面的动作,并将部分视图返回到索引视图。

$(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;
                        LoadProductsHead(productsInfo);
                        LoadProductsForm(productsInfo);
                    }
                    else {

                    }
                },
                error: function (e) {
                    if (e.status != 200) {
                        alert("error " + e.status + ' : ' + e.statusText);
                    }
                }
            });
        }

        function LoadProductsHead(param) {
            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "/Test/LoadProductsHead",
                data: JSON.stringify(param),
                dataType: "html",
                contentType: 'application/json; charset=utf-8',
                async: false,
                success: function (Result) {
                    if (Result) {
                        $('#partialViewHeader').html(Result)
                    }
                    else {
                    }
                },
                error: function (e) {
                    if (e.status == 200) {
                    }
                    if (e.status != 200) {
                        alert("error " + e.status + ' : ' + e.statusText);
                    }
                },
                complete: function (e) {

                }
            });
        }

        function LoadProductsForm(param) {
            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "/Test/LoadProductsFrom",
                data: JSON.stringify(param),
                dataType: "html",
                contentType: 'application/json; charset=utf-8',
                async: false,
                success: function (Result) {
                    if (Result) {
                        $('#partialViewForm').html(Result)
                    }
                    else {
                    }
                },
                error: function (e) {
                    if (e.status == 200) {
                    }
                    if (e.status != 200) {
                        alert("error " + e.status + ' : ' + e.statusText);
                    }
                },
                complete: function (e) {

                }
            });
        }

gif演示

希望这个答案能给予你一些帮助。

相关问题