ASP.NET Core中的TempData
admin
2022-03-04ASP.NET Core中的TempData
导航:
在本视频中,我们将讨论ASP.NET Core中TempData的使用。
现在让我们通过一个案例的来了解它的使用场景。
目前,当我们点击更新消息通知
按钮时,确认消息将显示在编辑学生
Razor Pages上。
在 Razor Pages之间传递查询字符串参数
现在我们的需求有点变化,我们希望将请求重定向到“学生详情”的Razor Pages,然后显示确认消息。
而要实现此效果一种方法便是是,将确认消息
作为查询字符串参数从“Edit.cshtml” Razor Pages传递到“Details.cshtml” Razor Pages中。
编辑Edit.cshtml页面
我们不再需要以下代码,它的位置在编辑
Razor Pages,更新消息通知
按钮下方
因此请删除它。
//删除它们
@if (!string.IsNullOrEmpty(Model.Message))
{
<div class="alert alert-primary">
@Model.Message
</div>
}
Edit.cshtml.cs
修改我们的OnPostUpdateNotificationPreferences
方法。
public string Message { get; set; }
public IActionResult OnPostUpdateNotificationPreferences(int id)
{
if (Notify)
{
Message = "您已经打开了消息通知功能";
}
else
{
Message = "你已经关闭了消息通知功能";
}
// 将请求重定向到Details Razor Pages,并传递StudentId和Message。
//StudentId作为路由参数传递 , 将Message作为查询字符串传递
return RedirectToPage("Details", new { id = id, message = Message });
}
}
Details.cshtml.cs
添加一个名称为Message的公共属性。这是视图模板中会用到的绑定属性。
[BindProperty(SupportsGet = true )]
public string Message { get; set; }
Details Razor Pages将消息作为查询字符串参数接收。模型绑定将自动将URL中的查询字符串参数值映射到 公共属性-Message
。
Details.cshtml
显示消息属性中的值
@if (!string.IsNullOrEmpty(Model.Message))
{
<div class="col-sm-8">
<div class="alert alert-primary">
@Model.Message
</div>
</div>
}
通过上述更改,确认消息将作为查询字符串参数在URL中传递。
http://localhost:51734/Students/Details/students/view/2?message=%E6%82%A8%E5%B7%B2%E7%BB%8F%E6%89%93%E5%BC%80%E4%BA%86%E6%B6%88%E6%81%AF%E9%80%9A%E7%9F%A5%E5%8A%9F%E8%83%BD
为什么查询字符串参数总是小写
这是因为我们在Startup类的ConfigureServices()方法中将RouteOptions对象的LowercaseQueryStrings属性设置为true。
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSingleton<IStudentRepository, MockStudentRepository>();
services.Configure<RouteOptions>(options =>
{
//如果你希望URL中的查询字符串为小写
//就需要将LowercaseUrls为true,默认值为false
options.LowercaseUrls = true;
//LowercaseQueryStrings的值也需要设置为true,默认值为false
options.LowercaseQueryStrings = true;
// 在生成的URL后面附加一个斜杠
options.AppendTrailingSlash = true;
options.ConstraintMap.Add("even", typeof(EvenConstraint));
});
}
但是现在还存在一个Bug需要解决
如果用户对此URL加了书签并在以后再次使用它,他仍将看到确认消息。
这可能会使用户感到困惑。 我没有更改任何通知设置,为什么收到此消息。
这可以通过使用TempData轻松解决。
使用TempData在ASP.NET Core中的 Razor Pages之间传递数据
TempData 翻译为 临时数据,它是一个继承自TempDataDictionary
类的字典对象,默认情况下使用基于 cookie 的 TempData 提供程序将 TempData 存储于 cookie。
当然也可以让存储在其他地方,比如Session,如果我们要自定义扩展的话,可以自定义的ITempDataProvider来完成。,它可以暴露在 ASP.NET Core 中可以在Razor Pages或 MVC控制器中,TempData属性用于存储数据,直到在另一个请求中读取它为止。可以使用Keep(String)和Peek(string)方法检查数据,也不需要在请求结束时将其删除。
Keep 会将标记字典中的所有项以进行保留。
TempData的提供场景通常为
- 当多个请求需要数据时,对于重定向很有用。
- 由TempData提供程序使用cookie或会话状态实现。
编辑Edit.cshtml.cs
public string Message { get; set; }
public IActionResult OnPostUpdateNotificationPreferences(int id)
{
if (Notify)
{
Message = "您已经打开了消息通知功能";
}
else
{
Message = "你已经关闭了消息通知功能";
}
//将确认消息存储在TempData中
TempData["Message"] = Message;
// 将请求重定向到Details Razor Pages,并传递StudentId
//StudentId作为路由参数传递
return RedirectToPage("Details", new { id = id });
}
Details.cshtml视图
显示来自TempData的确认消息。顾名思义,TempData是临时的。仅适用于给定的请求。 从TempData中读取数据后,该数据将被删除,无法用于后续请求。
因此,如果我们刷新页面或书签并在以后访问该页面,则不会看到通知确认消息。
这正是我们想要的结果,TempData非常适合这样的业务场景。
@if (TempData["Message"] != null)
{
<div class="col-sm-8">
<div class="alert Messagealert-primary">
@TempData["message"]
</div>
</div>
}
验证下 http://localhost:2221/students/details/students/view/2/
使用TempData属性访问TempData
访问TempData的一种方法是使用字符串键,在我们的例子中,@TempData["Message"]。
或者,在PageModel类中,创建一个与@TempData
键名称相同的公共属性,并使用[TempData]属性对其进行修饰。
[TempData]
public string Message { get; set; }
在显示模板中,我们现在可以简单地使用Model中的Message属性。
@if (Model.Message != null)
{
<div class="col-sm-8">
<div class="alert alert-primary">
@Model.Message
</div>
</div>
}
如何保留TempData
使用TempData.Keep()方法。顾名思义,Keep()方法即使在读取后仍保留临时数据值。 在下面的示例中,仅保留TempData词典中的消息键值。读取后,所有其他键及其值将被删除。
在Details.cshtml.cs类文件中
public IActionResult OnGet(int id)
{
TempData.Keep("Message");
// TempData.Keep();
Student = _studentRepository.GetStudent(Id);
}
如果要保留整个TempData字典,即所有键及其值,请使用不带任何参数的Keep()方法的重载版本。
TempData.Keep();
配置TempData 的Session提供程序
默认情况下使用基于 cookie 的 TempData 提供程序将 TempData 存储于 cookie。 cookie 数据是先使用 IDataProtector(用 Base64UrlTextEncoder 编码)进行加密,再进行区块处理。 由于加密和分块,最大 cookie 大小小于 4096 个字节。 未压缩 cookie 数据,因为压缩加密的数据会导致安全问题,如 CRIME 和 BREACH 攻击。 若要详细了解基于 cookie 的 TempData 提供程序,请参阅 CookieTempDataProvider。
若要启用基于会话的 TempData 提供程序,请使用 AddSessionStateTempDataProvider 扩展方法。 只需要调用 AddSessionStateTempDataProvider:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages()
.AddSessionStateTempDataProvider();
services.AddSession();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){
app.UseSession();
}