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

时间:2017-04-16 14:56:45

标签: 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);
    <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。当我通过剃刀代码进行调试时:

generate form

似乎没错,对吧?

嗯,html是不同的:

different html

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

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

它也发生在生产环境中。

2 个答案:

答案 0 :(得分:2)

这是预期的行为,当您尝试更改DeleteProduct的值时,就像您在ModelState中获取旧值的原因一样,因为当您返回到同一视图时,值来自首先呈现ModelState,如果Model为空,则会填充ModelState.Clear(); 的值,这就是我们使用的原因

Model

如果要更改ModelState中的值,则必须先从value清除值。您可以放置​​一个断点并检查key new它看起来像这样

How to use $http promise response outside success handler.

答案 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)。