asp.net核心中的TempData为空
Posted
技术标签:
【中文标题】asp.net核心中的TempData为空【英文标题】:TempData null in asp.net core 【发布时间】:2017-06-03 16:40:07 【问题描述】:我正在尝试在 asp.net 核心中使用 TempData 但是我在 TempData 的 get 方法上得到一个空值。谁能告诉我如何在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%" ]
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?");
);
这里是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;
但是下面的方法在临时数据中有空值。
[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;
这是调试会话的图像
【问题讨论】:
我遇到了同样的问题,我意识到这是因为我使用的是浏览器的私人标签 供参考:docs.microsoft.com/en-us/aspnet/core/fundamentals/… 【参考方案1】:已编辑:
如https://docs.microsoft.com/en-us/aspnet/core/security/gdpr?view=aspnetcore-2.2#tempdata-provider-and-session-state-cookies-arent-essential 中所述 默认情况下,TempData cookie 由 CookiePolicy 中间件删除。这可以通过将其放入 Startup.ConfigureServices() 来更改:
// 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;
);
==============================================
旧答案:
迁移到 ASP Core 2.1 后我遇到了这个问题,经过一天的工作找到解决方案:
在 Startup.Configure()
app.UseCookiePolicy();
应该在 app.UseMVC();
之后
【讨论】:
我认为这里有很多文档。我创建了一个关于它的问题:github.com/aspnet/Docs/issues/8041 这也是为什么在使用 ASP.NET Core Identity 并且您启用了 2 Factor Authentication 时没有显示恢复代码的原因。 谢谢! 这个问题更加令人困惑,因为 netcore 2.1 和 2.2 的会话状态文档 (docs.microsoft.com/en-us/aspnet/core/fundamentals/…) 显示UseCookiePolicy()
正在配置之前 UseMVC()
,这显然是不正确的。
谢谢!节省了我一天的研究时间,我遇到了同样的问题,只是做了这个修复它。
@Katstevens 订单没有问题。在下面检查我的答案。【参考方案2】:
official docs 中描述的中间件顺序没有问题,即:
-
异常/错误处理
HTTP 严格传输安全协议
HTTPS 重定向
静态文件服务器
Cookie 政策实施
身份验证
会话
MVC
但是当我们使用 Cookie 策略实施 (UseCookiePolicy) 时,只有 必要 cookie 会发送到浏览器,而来自 Tempdata 提供者的 Cookie 不是必要的,因此会出现问题。所以我们必须根据official documentation使它变得必不可少:
临时数据提供程序 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;
);
添加这些行应该可以解决您的问题,而无需重新排序中间件。
【讨论】:
这是正确答案,应该使用(不改变服务顺序) 这是 100% 正确和正确的答案 - 我最终在调试另一个问题时删除了我的 tempdata cookie,突然 tempdata 完全停止工作!一个小时后我发现了这个问题,现在问题已经解决了。 经过几个小时试图弄清楚为什么 Tempdata 为空...这有效。 谢谢!我花了大量时间调试这个问题。 Tempdata 正在使用 vanilla return Views(),但任何 return RedirectToAction() 调用都会导致 tempdata 为空。这解决了问题(.net core 3.1)【参考方案3】:请将您的所有软件包升级到相同版本1.1.0
并添加缓存服务。这是在Asp.Net Core
中使用TempData
所需的东西
Project.json
"Microsoft.AspNetCore.Session": "1.1.0"
这是 Startup.cs 文件。 - ConfigureServices 方法
public void ConfigureServices(IServiceCollection services)
services.AddMemoryCache();
services.AddSession();
services.AddMvc();
和配置方法。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
app.UseSession();
app.UseMvc(routes =>
routes.MapRoute(
name: "default",
template: "controller=Home/action=Index/id?");
);
现在试试TempData
,它会起作用的。
您可以使用 set ASPNETCORE_ENVIRONMENT=Development 环境变量来设置环境。
PS
ASP.NET Core MVC
在Controller
上公开TempData
属性。 TempData
可用于存储仅需要在当前请求之后的单个请求中可用的临时数据。
当读取TempDataDictionary
中的对象时,将在该请求结束时将其标记为删除。
Peek
和 Keep
方法允许您读取值而不将其标记为删除。假设我们回到将值保存到 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"];
使用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"];
【讨论】:
我正在尝试在第二个 http 请求中使用。第一个方法将值存储到 tempdata,第二个请求从 tempdata 中获取数据。但是,我得到了 null 值来获取部分 我在我的系统上尝试了它,同时删除了所有身份验证和其他相关代码,它工作正常。 我在 AddUpdateMarket() 方法上添加了完整的代码。我正在从角度 2 进行第二次 httpcall。我可以在 tempdata 上看到 null 值。 让我们continue this discussion in chat. 我已添加图片以获取更多信息。请看看,让我知道以上是关于asp.net核心中的TempData为空的主要内容,如果未能解决你的问题,请参考以下文章
在 asp.net 5.0 web api 项目中访问中间件中的 TempData
ASP.NET-viewBag Viewdata Tempdata
窥探ASP.Net MVC底层原理 实现跨越Session的分布式TempData