在成功的 POST 请求后重定向后显示一条消息,而不使用 TempData

Tur*_*rbo 5 asp.net asp.net-mvc asp.net-core-mvc asp.net-core visual-studio-2017

我正在使用Post-Redirect-Get模式。在我的 asp.net core MVC Web 应用程序中,会发生以下情况:

  1. 用户通过 POST 提交表单,将项目添加到数据库。
  2. 控制器添加新项目并使用 302/303 重定向到“/Home/Index/xxxx”,其中 xxxx 是该项目的 id。
  3. 新请求 (/Home/Index/xxxx) 由控制器提供服务,并显示该项目。地址栏中的项目 URL 是用户可以复制和共享的。

在上面的步骤 3 中,我想向用户显示一条消息“项目已成功添加”。

这是我的代码(没有成功消息):

public async Task<IActionResult> Index(string id)
{
    ItemView itemView = null;
    if (string.IsNullOrEmpty(id))
        itemView = new ItemView();  // Create an empty item.
    else
        itemView = await itemService.GetItemAsync(id);
    return View(itemView);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(ItemView itemView)
{
    string id = await itemService.AddItemAsync(itemView);
    return RedirectToAction("Index", "Home", new { id = id });
}
Run Code Online (Sandbox Code Playgroud)

我在 stackoverflow 上的其他答案中找到了几种方法可以做到这一点。

  1. 重定向到“/Home/Index/xxxx?success=true”。当action看到success=true参数时,它可以显示成功消息。但我不想使用额外的参数,因为我希望用户能够从地址栏中复制 url 并共享它。我不希望他们共享具有 success 参数的 url,因为这样每个单击共享链接的人都会看到消息“项目已成功添加”。
  2. 这篇文章建议使用 TempData,这是一个很好的解决方案。我认为这需要我在服务器上启用粘性行为,如果可能的话我想避免这种行为。
  3. 我可能可以使用引用网址来确定请求是否是在表单提交之后发出的,在这种情况下我可以显示消息。

Tur*_*rbo 7

“史努比”的原始答案确实为我指明了正确的方向。但由于某种未知的原因,该答案不再存在,因此我自己发布答案,希望它对将来的人有益。

ASP .NET Core 1.1 及更高版本支持基于 Cookie 的 Tempdata 提供程序(称为 CookieTempDataProvider)。链接到Microsoft 文档

这与基于 Session 的 Tempdata 类似,但服务器端不存储任何数据。服务器的响应设置为浏览器中的 cookie,其中包含您要存储的数据。来自浏览器的下一个请求将包含此 cookie。框架会自动解析它并将其填充到控制器可以使用的 TempData 中。一旦控制器读取此数据,CookieTempDataProvider 就会自动在响应中添加适当的标头以清除此 cookie。

在你的Startup类的ConfigureServices方法中,你需要注册CookieTempDataProvider:

services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
Run Code Online (Sandbox Code Playgroud)

要将一些数据存储在基于 cookie 的临时数据中,您只需在控制器中设置如下值:

TempData["key"] = "value";
Run Code Online (Sandbox Code Playgroud)

要读取控制器中的数据,您可以这样读取:

string value = TempData["key"];
if (value != null)
{
  // Do something with the the value.
}
Run Code Online (Sandbox Code Playgroud)

对非空值的检查会告诉您该键是否存在于 TempData 中。请注意,您还可以使用 .ContainsKey() 方法进行检查,但这不计为读取。除非您阅读,否则数据(和 cookie)不会被清除。例如,这不会清除数据:

if (TempData.ContainsKey("key"))
{
// Do something without actually reading the value of TempData["key"].
}
Run Code Online (Sandbox Code Playgroud)