MVC 6中的ITempDataProvider使用cookie进行tempdata

时间:2016-02-03 10:07:01

标签: asp.net asp.net-core-mvc

我正在迁移一个站点以使用MVC 6.目前我在cookie中有tempdata存储,但我找不到在新的MVC框架中如何执行此操作的设置。

3 个答案:

答案 0 :(得分:0)

首先,实现您的ITempDataProvider。我是这样做的,使用JSON.Net。

public class CookieTempDataProvider : ITempDataProvider
{
    readonly string CookieKey = "_tempdata";

    public IDictionary<string,object> LoadTempData(HttpContext context)
    {
        var cookieValue = context.Request.Cookies[this.CookieKey];
        if(string.IsNullOrWhiteSpace(cookieValue))
        {
            return new Dictionary<string, object>();
        }

        var decoded = Convert.FromBase64String(cookieValue);
        var jsonAsString = Encoding.UTF8.GetString(decoded);            
        var dictionary = JsonConvert.DeserializeObject<IDictionary<string,object>>(jsonAsString, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Full });

        // The cookie really should be deleted when the SaveTempData() method is called with an empty dictionary
        // but that does not seem to be working for some reason.  Added this delete for now (maybe this is a beta issue)
        // TODO: Revisit at next release
        context.Response.Cookies.Delete(this.CookieKey);

        return dictionary;
    }

    public void SaveTempData(HttpContext context, IDictionary<string,object> values)
    {
        if (values == null || values.Count == 0)
        {
            context.Response.OnStarting(() => Task.Run(() =>
            {
                context.Response.Cookies.Delete(this.CookieKey);
            }));

            return;
        }

        var jsonAsString = JsonConvert.SerializeObject(values, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Full });
        var bytes = Encoding.UTF8.GetBytes(jsonAsString);
        var encoded = Convert.ToBase64String(bytes);

        context.Response.Cookies.Append(this.CookieKey, encoded);
    }        
}

接下来,在连接服务的Startup.cs中,将默认的ITempDataProvider替换为您的自定义版本,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    // Replace Temp Data Provider
    var existing = services.FirstOrDefault(x => x.ServiceType == typeof(ITempDataProvider));
    services.Remove(existing);
    services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
}

修改

由于RC2的原始答案不再有效,因为MVC请求生命周期中的时间变化似乎......您将收到有关无法修改标头的错误。我已经更新了上面的SaveTempData()方法来解释这个问题。

答案 1 :(得分:0)

我也有这个需求,所以我为ASP.NET Core MVC实现了一个基于cookie的 TempData 提供程序,并将其发布在NuGet上。它可用here

答案 2 :(得分:-1)

如果您考虑使用TempData类存储下一个请求的数据,则MVC 6中会有一些更改。您需要添加其他包并对其进行配置。以下是步骤:

  1. 从[project.json]的frameworks部分删除“dnxcore50”。会话尚未在dnxcore50中实现。

  2. 在[project.json]中添加:

    "Microsoft.AspNet.Session": "1.0.0-rc1-final"
    
  3. 通过在 services.AddMvc()之后添加下一行,在课程 Startup.cs ,方法配置服务中启用缓存和会话:

    services.AddCaching();
    services.AddSession();
    
  4. 在课堂上 Startup.cs ,方法配置,在 app.UseMvc(...)之前添加下一行

    app.UseSession();
    
  5. 就是这样。但请记住,您只能存储原始或可序列化的数据类型。如果需要存储用户定义的数据类型,则需要对其进行序列化。为此,我们使用“Newtonsoft.Json”lib。这是一个例子:

    string json = JsonConvert.SerializeObject(myObject);
    TempData["myKey"] = json;