即使在使用 TempData.Keep() asp.net 核心 mvc 后也无法多次使用 TempData
Unable to use TempData more than once even after using TempData.Keep() asp.net core mvc
我有一个 mvc 项目,它将在我的中间件中传递一个 tempdata["username"]
。但是在 if(tempdata.ContainsKey("username")
中调试我的中间件时,我注意到它只进入该 if 语句一次并且再也不会进入它。我阅读了这篇文章,解释了如何使用 TempData
以及如何保留数据以便能够多次使用它,但在我的情况下它不起作用。为了实现这一目标,我缺少什么吗?
我的应用程序有 4 个页面,在家庭控制器上它会要求我输入用户名。当我这样做时,然后在中间件中传递临时数据并输入 if 语句。当继续 post 方法并在新页面上时,它将不包含任何值。所以基本上在第 3 次请求时,tempdata 被删除。我该如何解决这个问题,以便它可以在我的所有页面中传递?
HomeController
:
public IActionResult Index()
{
// Gather IP
var userip = Request.HttpContext.Connection.RemoteIpAddress;
_logger.LogInformation("IP address of user logged in: {@IP-Address}", userip);
// Call AddressService API
var result = _addressServiceClient.SampleAsync().Result;
_logger.Log(LogLevel.Information, "Home Page...");
return View();
}
[HttpPost]
public IActionResult AddressValidate(IFormCollection form)
{
// if radio button was checked, perform the following var request.
// username
username = form["UserName"];
TempData["username"] = username;
TempData.Keep("username");
//HttpContext.Items["username"] = username;
string status = form["Status"];
_logger.LogInformation("Current user logged in: {@Username}", username);
switch (status)
{
case "1":
_logger.LogInformation("Address entered was valid!");
break;
case "2":
_logger.LogError("Address entered was invalid!");
ViewBag.Message = string.Format("You did not enter your address correctly! Please enter it again!");
return View("Index");
case "3":
_logger.LogError("Invalid Address");
throw new Exception("Invalid Address");
}
var request = new AddressRequest
{
StatusCode = Convert.ToInt32(status),
Address = "2018 Main St New York City, NY, 10001"
};
var result = _addressServiceClient.ValidateAddress(request).Result;
return RedirectToAction("SecIndex", "Second");
}
middleware
:
public class CorrelationIdMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory;
public CorrelationIdMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, ITempDataDictionaryFactory tempDataDictionaryFactory)
{
_next = next;
_logger = loggerFactory.CreateLogger<CorrelationIdMiddleware>();
_tempDataDictionaryFactory = tempDataDictionaryFactory;
}
public async Task Invoke(HttpContext context)
{
string correlationId = null;
string userName;
var tempData = _tempDataDictionaryFactory.GetTempData(context);
var key = context.Request.Headers.Keys.FirstOrDefault(n => n.ToLower().Equals("x-correlation-id"));
if (!string.IsNullOrWhiteSpace(key))
{
correlationId = context.Request.Headers[key];
_logger.LogInformation("Header contained CorrelationId: {@CorrelationId}", correlationId);
}
else
{
if (tempData.ContainsKey("username"))
{
userName = tempData["username"].ToString();
context.Response.Headers.Append("X-username", userName);
}
correlationId = Guid.NewGuid().ToString();
_logger.LogInformation("Generated new CorrelationId: {@CorrelationId}", correlationId);
}
context.Response.Headers.Append("x-correlation-id", correlationId);
using (LogContext.PushProperty("CorrelationId", correlationId))
{
await _next.Invoke(context);
}
}
}
当您总是想为另一个请求保留值时,可以使用 Peek。当保留值取决于附加逻辑时使用 Keep。
在您的情况下,您必须使用 Peek。而不是 var val= TempData["username"] 使用 val = TempData.Peek("username");
当您调用 val= TempData["username"] 时,在后台返回数据后
自动调用 TempData.Remove("username").
我有一个 mvc 项目,它将在我的中间件中传递一个 tempdata["username"]
。但是在 if(tempdata.ContainsKey("username")
中调试我的中间件时,我注意到它只进入该 if 语句一次并且再也不会进入它。我阅读了这篇文章,解释了如何使用 TempData
以及如何保留数据以便能够多次使用它,但在我的情况下它不起作用。为了实现这一目标,我缺少什么吗?
我的应用程序有 4 个页面,在家庭控制器上它会要求我输入用户名。当我这样做时,然后在中间件中传递临时数据并输入 if 语句。当继续 post 方法并在新页面上时,它将不包含任何值。所以基本上在第 3 次请求时,tempdata 被删除。我该如何解决这个问题,以便它可以在我的所有页面中传递?
HomeController
:
public IActionResult Index()
{
// Gather IP
var userip = Request.HttpContext.Connection.RemoteIpAddress;
_logger.LogInformation("IP address of user logged in: {@IP-Address}", userip);
// Call AddressService API
var result = _addressServiceClient.SampleAsync().Result;
_logger.Log(LogLevel.Information, "Home Page...");
return View();
}
[HttpPost]
public IActionResult AddressValidate(IFormCollection form)
{
// if radio button was checked, perform the following var request.
// username
username = form["UserName"];
TempData["username"] = username;
TempData.Keep("username");
//HttpContext.Items["username"] = username;
string status = form["Status"];
_logger.LogInformation("Current user logged in: {@Username}", username);
switch (status)
{
case "1":
_logger.LogInformation("Address entered was valid!");
break;
case "2":
_logger.LogError("Address entered was invalid!");
ViewBag.Message = string.Format("You did not enter your address correctly! Please enter it again!");
return View("Index");
case "3":
_logger.LogError("Invalid Address");
throw new Exception("Invalid Address");
}
var request = new AddressRequest
{
StatusCode = Convert.ToInt32(status),
Address = "2018 Main St New York City, NY, 10001"
};
var result = _addressServiceClient.ValidateAddress(request).Result;
return RedirectToAction("SecIndex", "Second");
}
middleware
:
public class CorrelationIdMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory;
public CorrelationIdMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, ITempDataDictionaryFactory tempDataDictionaryFactory)
{
_next = next;
_logger = loggerFactory.CreateLogger<CorrelationIdMiddleware>();
_tempDataDictionaryFactory = tempDataDictionaryFactory;
}
public async Task Invoke(HttpContext context)
{
string correlationId = null;
string userName;
var tempData = _tempDataDictionaryFactory.GetTempData(context);
var key = context.Request.Headers.Keys.FirstOrDefault(n => n.ToLower().Equals("x-correlation-id"));
if (!string.IsNullOrWhiteSpace(key))
{
correlationId = context.Request.Headers[key];
_logger.LogInformation("Header contained CorrelationId: {@CorrelationId}", correlationId);
}
else
{
if (tempData.ContainsKey("username"))
{
userName = tempData["username"].ToString();
context.Response.Headers.Append("X-username", userName);
}
correlationId = Guid.NewGuid().ToString();
_logger.LogInformation("Generated new CorrelationId: {@CorrelationId}", correlationId);
}
context.Response.Headers.Append("x-correlation-id", correlationId);
using (LogContext.PushProperty("CorrelationId", correlationId))
{
await _next.Invoke(context);
}
}
}
当您总是想为另一个请求保留值时,可以使用 Peek。当保留值取决于附加逻辑时使用 Keep。
在您的情况下,您必须使用 Peek。而不是 var val= TempData["username"] 使用 val = TempData.Peek("username");
当您调用 val= TempData["username"] 时,在后台返回数据后 自动调用 TempData.Remove("username").