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

时间:2017-08-01 00:07:20

标签: asp.net asp.net-mvc asp.net-core asp.net-core-mvc visual-studio-2017

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

  1. 用户通过POST提交表单,向db。添加项目。
  2. Controller添加新项目并使用302/303重定向到“/ Home / Index / xxxx”,其中xxxx是项目的ID。
  3. 新请求(/ Home / Index / xxxx)由控制器提供,并显示该项目。地址栏中的项目网址是用户可以复制和共享的内容。
  4. 在上面的第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 });
    }
    

    我在堆栈溢出的其他答案中找到的方法很少。

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

1 个答案:

答案 0 :(得分:2)

“史努比”的原始答案确实指出了我正确的方向。但由于某些未知的原因,这个答案已不复存在,所以我自己也会发布答案,希望将来有人会受益。

ASP .NET Core 1.1及更高版本支持基于Cookie的Tempdata提供程序,名为CookieTempDataProvider。链接到Microsoft Docs

这类似于基于会话的Tempdata,但是没有数据存储在服务器端。来自服务器的响应在浏览器中设置了一个cookie,其中包含您要存储的数据。来自浏览器的下一个请求将包含此cookie。框架自动解析它并在TempData中填充它,控制器可以使用它。控制器读取此数据后,CookieTempDataProvider会自动在响应中添加相应的标头以清除此cookie。

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

services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();

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

TempData["key"] = "value";

要读取控制器中的数据,请按以下方式阅读:

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

检查非null会告诉您该密钥是否存在于TempData中。请注意,您也可以使用.ContainsKey()方法进行检查,但这不算作读取。除非您阅读,否则不会清除数据(&amp; cookie)。例如,这不会清除数据:

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