当部署到Web场(基本上是2个Windows Server 2016框)时,以下代码无法从TempData读取数据。事件的顺序如下:将UserInfo页面发布到,设置TempData,然后重定向到UserInfo的GET。在GET TempData中无法读取。
[HttpPost]
public IActionResult UserInfo(Model model) {
TempData["Model"] = JsonConvert.SerializeObject(model);
return RedirectToAction("UserInfo");
}
[HttpGet]
public IActionResult UserInfo() {
string serialized = (string)TempData["Model"];
if (serialized != null) {
var model = JsonConvert.DeserializeObject<Model>(serialized);
return View(model);
} else {
// nothing here redirect home
return RedirectToAction("Landing");
}
}
我在标准日志中收到以下错误(但在我的代码中未引起异常):
warn: Microsoft.AspNetCore.Mvc.ViewFeatures.CookieTempDataProvider[3]
The temp data cookie .AspNetCore.Mvc.CookieTempDataProvider could not be loaded.
System.Security.Cryptography.CryptographicException: The key {0dd9c024-af79-407b-9820-db7f094975f9} was not found in the key ring.
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
at Microsoft.AspNetCore.Mvc.ViewFeatures.CookieTempDataProvider.LoadTempData(HttpContext context)
P.S。我应该提到,此代码可在非Web场IIS实例和Asure共享主机上使用。
答案 0 :(得分:1)
该异常会告诉您所有您需要了解的内容。它尝试读取cookie,但是解密失败,特别是因为在数据保护密钥环中找不到该密钥。这意味着您不会在服务器场中的每个实例之间共享数据保护。即使它是同一个应用程序,每个实例实际上都是它自己的实体。因此,您需要将其像需要在站点之间共享数据保护的任何其他方案一样对待:即通过使用公共密钥环存储并确保使用相同的应用程序名称:
services.AddDatProtection()
.SetApplicationName("Shared Name")
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
这样,每个实例将能够读取其他实例设置的cookie,这将使TempData
在实例之间工作。