所以我有这个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>
}
这称之为后端:
[HttpPost]
public ActionResult DeleteProduct(int productId, int? productVariantId, int quantity)
{
//...product gets deleted, etc. Not important for this question
//regenerate the view, same as when loading the 'Order' view initially
OrderWrapperViewModel model = GenerateOrderWrapperModel();
return View("Order", model);
}
在控制器中加载Order视图如下所示:
[HttpGet]
public ActionResult Order()
{
OrderWrapperViewModel model = GenerateOrderWrapperModel();
return View(model);
}
当我第一次致电删除时,我会删除ID为7
且产品变体ID为8
的产品。一切都很好。但是在页面返回后,ID 7的产品不再列出,只有ID为1的产品。因此第二次应该是产品ID:1
和产品变体ID:4
。
从DeleteProduct
返回时,网址目前正在显示/ Shop / DeleteProduct。当我通过剃刀代码进行调试时:
似乎没错,对吧?
嗯,html是不同的:
当然,单击按钮也会传递这些不正确的参数。我可以向您保证,这是同一个按钮,当时只显示了1个产品。
我通过简单地再次重定向到Order视图解决了这个问题,所以我对为什么这种情况更感兴趣。原因是,因为对于其他人,我返回一条错误消息(使用ModelState
)。当我重定向时,这当然不起作用。
它也发生在生产环境中。
答案 0 :(得分:2)
这是预期的行为,当您尝试更改DeleteProduct
的值时,就像您在ModelState
中获取旧值的原因一样,因为当您返回到同一视图时,值来自首先呈现ModelState
,如果Model
为空,则会填充ModelState.Clear();
的值,这就是我们使用的原因
Model
如果要更改ModelState
中的值,则必须先从value
清除值。您可以放置一个断点并检查key
new
它看起来像这样
答案 1 :(得分:1)
执行DeleteProduct
等操作的常用方法是在删除完成后重定向到另一个操作:
[HttpPost]
public ActionResult DeleteProduct(int productId, int? productVariantId, int quantity)
{
//...product gets deleted, etc. Not important for this question
return RedirectToAction("Order");
}
通过这种方式,您可以在ModelState
方法中获得全新的Order
,这样它就不会与您传递给视图的任何Model
参数冲突,并且用户看到更正确的&#39;删除产品后其浏览器中的网址(例如/Shop/Order
代替/Shop/DeleteProduct
)。