C# 返回视图后生成的表单POST参数错误

C# 返回视图后生成的表单POST参数错误,c#,asp.net-mvc,razor,C#,Asp.net Mvc,Razor,我有一个CSHTML: @using (Html.BeginForm("DeleteProduct", "Shop", FormMethod.Post)) { @Html.Hidden("productId", product.ProductId); @Html.Hidden("productVariantId", product.ProductVariantId); @Html.Hidden("quantity", product.Quantity); <

我有一个CSHTML:

@using (Html.BeginForm("DeleteProduct", "Shop", FormMethod.Post))
{
    @Html.Hidden("productId", product.ProductId);
    @Html.Hidden("productVariantId", product.ProductVariantId);
    @Html.Hidden("quantity", product.Quantity);
    <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
}
控制器中的加载顺序视图如下所示:

[HttpGet]
public ActionResult Order()
{
    OrderWrapperViewModel model = GenerateOrderWrapperModel();
    return View(model);
}
当我第一次调用delete时,我删除了ID为
7
的产品和ID为
8
的产品变体。一切顺利。但返回页面后,ID为7的产品不再列出,只列出ID为1的产品。所以第二次应该是产品ID:
1
和产品变量ID:
4

DeleteProduct
返回时,url当前显示/Shop/DeleteProduct。当我调试razor代码时:

似乎是对的,对吗

嗯,html是不同的:

当然,单击按钮也会传递那些不正确的参数。我可以向您保证,这是同一个按钮,当时只显示了一个产品

我通过再次重定向到订单视图解决了这个问题,所以我更感兴趣的是为什么会发生这种情况。原因是,对于其他人,我返回了一条错误消息(使用
ModelState
)。当我重定向时,这当然不起作用


它也发生在生产环境中

这是预期行为当您尝试更改
模型的值时会发生这种情况,就像您在
DeleteProduct
中所做的那样,这是它获取旧值的原因,因为当您返回到同一视图时,首先呈现
ModelState
中的值,因此如果
ModelState
为空,它将填充
Model
中的值,因此我们使用

ModelState.Clear();
如果要更改
Model
中的值,必须首先清除
ModelState
中的值。您可以放置断点并检查
键的
,它将如下所示


这是预期的行为当您尝试更改
模型的值时会发生这种情况,就像您在
DeleteProduct
中所做的一样,这是它获取旧值的原因,因为当您返回到同一视图时,首先呈现
ModelState
中的值,因此如果
ModelState
为空,它将填充
Model
中的值,因此我们使用

ModelState.Clear();
如果要更改
Model
中的值,必须首先清除
ModelState
中的值。您可以放置断点并检查
键的
,它将如下所示


执行诸如
DeleteProduct
等操作的通常方式是在删除完成后重定向到另一个操作:

[HttpPost]
public ActionResult DeleteProduct(int productId, int? productVariantId, int quantity)
{
    //...product gets deleted, etc. Not important for this question

    return RedirectToAction("Order");
}

这样,您可以在您的
订单
方法中获得一个新的
模型状态
,这样它就不会与您传递给视图的任何
模型
参数冲突,并且用户在删除产品后会在浏览器中看到一个“更正确”的URL(例如
/Shop/Order
而不是
/Shop/DeleteProduct
).

执行
DeleteProduct
等操作的通常方法是在删除完成后重定向到另一个操作:

[HttpPost]
public ActionResult DeleteProduct(int productId, int? productVariantId, int quantity)
{
    //...product gets deleted, etc. Not important for this question

    return RedirectToAction("Order");
}

这样,您可以在您的
订单
方法中获得一个新的
模型状态
,这样它就不会与您传递给视图的任何
模型
参数冲突,并且用户在删除产品后会在浏览器中看到一个“更正确”的URL(例如
/Shop/Order
而不是
/Shop/DeleteProduct
).

正确的方法是遵循PRG模式,所以就这样做吧。但是对于行为的解释,正确的方法是遵循PRG模式,所以就这样做吧。但有关该行为的解释,请参阅