asp.net核心中的TempData null

San*_*isy 27 c# asp.net asp.net-mvc asp.net-web-api asp.net-core

我试图在asp.net核心中使用TempData但是我在TempData的get方法上得到一个null值.任何人都可以让我知道如何在asp.net核心中使用TempData

以下是我根据研究添加的内容.

Project.json文件

{
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.1",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Mvc": "1.0.1",
    "Microsoft.AspNetCore.Routing": "1.0.1",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Logging": "1.1.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
    "Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final",
    "Microsoft.EntityFrameworkCore.Design": "1.1.0",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.1.0",
    "DataBase": "1.0.0-*",
    "UnitOfWork": "1.0.0-*",
    "ViewModel": "1.0.0-*",
    "Common": "1.0.0-*",
    "System.IdentityModel.Tokens.Jwt": "5.0.0",
    "Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0",
    "Microsoft.AspNetCore.Session": "1.1.0",
    "Microsoft.Extensions.Caching.Memory": "1.1.0"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final",
    "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final",
    "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "**/*.cshtml",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}
Run Code Online (Sandbox Code Playgroud)

start.cs文件

public void ConfigureServices(IServiceCollection services)
{
    services.AddMemoryCache();
    services.AddSession();
    // Add framework services.
    services.AddMvc();
    services.AddTransient<IMarketUOW, MarketUow>();
    services.AddTransient<ICategoryUow, CategoryUow>();
    services.AddTransient<IUserProfileUow, UserProfileUow>();
    services.AddTransient<IItemUow, ItemUow>();

    services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));
    var connection = Configuration.GetConnectionString("DefaultConnection");
    services.AddDbContext<EmakitiContext>(options => options.UseSqlServer(connection));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSession();
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
Run Code Online (Sandbox Code Playgroud)

这是tempdata的实现.当调用此方法时,我可以看到TempData中的值.

[HttpGet("{pageNumber}")]
public GenericResponseObject<List<MarketViewModel>> GetMarketList(int pageNumber)
{
    TempData["Currentpage"] = pageNumber;
    TempData.Keep("Currentpage");
    GenericResponseObject<List<MarketViewModel>> genericResponseObject = new GenericResponseObject<List<MarketViewModel>>();
    genericResponseObject.IsSuccess = false;
    genericResponseObject.Message = ConstaintStingValue.Tag_ConnectionFailed;
    try
    {
        var marketItem = _iMarketUow.GetMarketList(pageNumber);
        genericResponseObject.Data = marketItem.Item1;
        var totalPages = (int)Math.Ceiling((decimal)marketItem.Item2 / (decimal)10);
        genericResponseObject.TotalPage = totalPages;
        genericResponseObject.IsSuccess = true;
        genericResponseObject.Message = ConstaintStingValue.Tag_SuccessMessageRecord;
        genericResponseObject.Message = ConstaintStingValue.Tag_ConnectionSuccess;
    }
    catch (Exception exception)
    {
        genericResponseObject.IsSuccess = false;
        genericResponseObject.Message = exception.Message;
        genericResponseObject.ErrorCode = exception.HResult;
        genericResponseObject.ExceptionErrorMessage = exception.StackTrace;
    }
    return genericResponseObject;
}
Run Code Online (Sandbox Code Playgroud)

但是下面的方法在临时数据中具有空值.

[HttpPost]
public GenericResponseObject<List<MarketViewModel>> AddUpdateMarket([FromBody] MarketViewModel marketViewModel)
{
    GenericResponseObject<List<MarketViewModel>> genericResponseObject = new GenericResponseObject<List<MarketViewModel>>();
    genericResponseObject.IsSuccess = false;
    genericResponseObject.Message = ConstaintStingValue.Tag_ConnectionFailed;

    if (marketViewModel!= null && ModelState.IsValid)
    {
        try
        {
            _iMarketUow.AddUpdateMarketList(marketViewModel);
            genericResponseObject = GetMarketList(Convert.ToInt16(TempData.Peek("Currentpage")));
        }
        catch (Exception exception)
        {
            genericResponseObject.IsSuccess = false;
            genericResponseObject.Message = exception.Message;
            genericResponseObject.ErrorCode = exception.HResult;
            genericResponseObject.ExceptionErrorMessage = exception.StackTrace;
        }
    }
    else
    {
        genericResponseObject.Message = ConstaintStingValue.Tag_InputDataFormatNotMatch;
    }
    return genericResponseObject;
}
Run Code Online (Sandbox Code Playgroud)

这是调试会话的图像

http的第一个请求,它将值保存到tempdata

第二个请求上的空值

Ham*_*edH 65

迁移到ASP Core 2.1之后我遇到了这个问题,在工作了一天后找到了解决方案:

在Startup.Configure() app.UseCookiePolicy();之后应该是app.UseMVC();

  • @Katstevens订单没有问题。在下面检查我的答案。 (5认同)
  • *谢谢你!*这个问题更令人困惑,因为会话状态文档(https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore- 2.1)对于netcore 2.1和2.2显示`UseCookiePolicy()`正在配置_before_`UseMVC()`,这显然是不正确的. (2认同)

Nug*_*udi 24

官方文档中描述的中间件顺序没有问题,即:

  1. 异常/错误处理
  2. HTTP严格传输安全协议
  3. HTTPS重定向
  4. 静态文件服务器
  5. Cookie政策执行
  6. 认证方式
  7. 届会
  8. MVC

但是,当我们使用Cookie策略实施(UseCookiePolicy)时,仅将要发送到浏览器的基本 Cookie和来自Tempdata提供程序的Cookie都不是必需的,因此出现了问题。因此,根据官方文档,我们必须使其变得必不可少:

Tempdata提供程序cookie不是必需的。如果禁用了跟踪,则Tempdata提供程序将无法运行。要在禁用跟踪时启用Tempdata提供程序,请在Startup.ConfigureServices中将TempData cookie标记为必不可少的

// The Tempdata provider cookie is not essential. Make it essential
// so Tempdata is functional when tracking is disabled.
services.Configure<CookieTempDataProviderOptions>(options => {
   options.Cookie.IsEssential = true;
});
Run Code Online (Sandbox Code Playgroud)

添加这些行应该可以解决您的问题,而无需重新排序中间件。

  • 这是正确的答案,应该使用(不更改服务顺序) (4认同)
  • 这是 100% 真实和正确的答案 - 我最终在调试另一个问题时删除了我的临时数据 cookie,突然临时数据完全停止工作!一个小时后我找到了这个,现在问题解决了。 (3认同)

Ahm*_*mar 15

请将您的所有软件包升级到相同的版本1.1.0添加缓存服务.下面是使用所需的东西TempDataAsp.Net Core

Project.json

"Microsoft.AspNetCore.Session": "1.1.0"
Run Code Online (Sandbox Code Playgroud)

这是Startup.cs文件. - ConfigureServices方法

public void ConfigureServices(IServiceCollection services)
{
     services.AddMemoryCache();
     services.AddSession();
     services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)

和配置方法.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSession();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
    });
}
Run Code Online (Sandbox Code Playgroud)

现在尝试TempData,它会工作.

您可以使用设置ASPNETCORE_ENVIRONMENT =开发环境变量来设置环境.

PS

ASP.NET Core MVC公开TempData财产Controller.TempData可以用于存储瞬态数据,该瞬态数据仅需要在当前请求之后针对单个请求可用.

TempDataDictionary读取a中的对象时,它将在该请求结束时标记为删除.

PeekKeep方法,使您无需将其标记为删除读取值.假设我们回到保存值的第一个请求TempData.

通过Peek一次调用即可获得值,而无需将其标记为删除.

//second request, PEEK value so it is not deleted at the end of the request
object value = TempData.Peek("value");

//third request, read value and mark it for deletion
object value = TempData["value"];
Run Code Online (Sandbox Code Playgroud)

Keep您指定要保留的标记为删除的键时.检索对象以及稍后将其保存为删除是2个不同的调用.

//second request, get value marking it from deletion
object value = TempData["value"];
//later on decide to keep it
TempData.Keep("value");

//third request, read value and mark it for deletion
object value = TempData["value"];
Run Code Online (Sandbox Code Playgroud)