【问题标题】:Unable to use TempData more than once even after using TempData.Keep() asp.net core mvc即使在使用 TempData.Keep() asp.net core mvc 之后也无法多次使用 TempData
【发布时间】:2021-08-11 17:14:20
【问题描述】:

我有一个 mvc 项目,它将在我的中间件中传递一个 tempdata["username"] 。但是在if(tempdata.ContainsKey("username") 中调试我的中间件时,我注意到它只进入了一次 if 语句,并且再也没有进入它。我读了这篇文章,它解释了如何使用TempData 以及如何保持数据能够多次使用它,但在我的情况下它不起作用。为了实现这一目标,我是否缺少一些东西?

在我的应用程序中,我有 4 个页面,在家庭控制器上,它会要求我输入用户名。当我这样做时,然后传递中间件中的临时数据并输入 if 语句。当继续使用 post 方法并在新页面上时,它不会保留任何值。所以基本上在第三次请求临时数据被删除。我该如何解决这个问题,以便它可以在我的所有页面中传递?

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);
            }
        }
    }

【问题讨论】:

    标签: c# html .net-core asp.net-core-mvc middleware


    【解决方案1】:

    当您总是想为另一个请求保留值时,可以使用 Peek。保留值时使用 Keep 取决于附加逻辑。

    在您的情况下,您必须使用 Peek。而不是 var val= TempData["username"] 使用 val = TempData.Peek("username");

    当您调用 val= TempData["username"] 时,在引擎盖下,在返回数据之后 自动调用 TempData.Remove("username")。

    【讨论】:

    • 谢谢!我查看了 Peek() 的实现并注释掉了 TempData.Keep("username") 并做了 TempData["username"] = username;var val = TempData.Peek("username"); 然后 TempData.Peek("username"); 我遇到了同样的问题。所以从第一页过渡到第二页没问题。但是当我点击第二页的一个按钮跳转到第三页时,中间件中的if语句条件(tempdata)没有命中。我没有正确实现 peek 吗?
    • 对不起,我没有使用var val = TempData["username"];。目前我有username = form["UserName"],它将保存用户在文本框中输入的值。然后我有TempData["username"] = username;,然后是var val = TempData.Peek("username");。但是,像这样我仍然得到相同的结果。
    • @MarkCo 我的意思是在你的中间件而不是 userName = tempData["username"].ToString();使用 userName =tempData.Peek("username").ToString();
    • 哦,我明白了,将实现这一点。那么在家庭控制器中,我应该保留它已经是username = form["UserName"];,然后是TempData["username"] = username;,最后是TempData.Keep("username");,还是我也需要在家庭控制器中进行一些修改?
    • @MarkCo 不要使用 TempData.Keep("username");一点也不。检查我的答案更新
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 2012-09-07
    相关资源
    最近更新 更多