ASP.NET Core中的TempData

admin
admin
2022-03-04
分享:

ASP.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();


}