在 Dotnet Core 3.1 中将数据从一个控制器传递到另一个控制器

Posted

技术标签:

【中文标题】在 Dotnet Core 3.1 中将数据从一个控制器传递到另一个控制器【英文标题】:Passing data from one controller to another in Dotnet Core 3.1 【发布时间】:2021-04-07 09:02:04 【问题描述】:

我是整个 MVC 模式的新手,遇到以下问题:

我有 2 个控制器,PayReqControllerPayResController。我正在尝试从PayReqController 的一个操作访问PayResController 的另一个操作的数据。我试过使用TempData:

TempData["tsnpac"] = tsnpac; 

但它不起作用,因为我们需要在设置TempData 后重定向到另一个控制器。还尝试使用会话Session["TSNPAC"] = "TSNPAC"; 将其访问到另一个控制器,但它给出的值是null

我的情况是,在PayReqController 中,在一个动作中我有一个值,我需要在另一个控制器中获取它而不重定向到该控制器,因为我的用例是重定向到我作为一个其他 URL来自其他服务的响应。

【问题讨论】:

如果您显示代码可能会有所帮助,但听起来您需要将代码移出控制器。 是的,我在第一个控制器中设置一个值并移动到某个 xyz URL(我从服务中获取它作为响应),然后在重定向到该 URL 并传递一些值之后我在那里回到第二个控制器。您想查看哪个控制器的代码?有没有办法在我的场景或用例中将值传递给另一个控制器? 【参考方案1】:

要在请求范围之间(不仅仅是控制器之间)共享数据,您可以使用HttpContext.Items

分享数据:

//in the  first controller 

HttpContext.Items.Add("person", person);

以及使用共享数据:

//in the second controller

var person= HttpContext.Items["person"] as Person;

【讨论】:

人的价值为空 请注意,此方法仅适用于一个请求(而不是多个请求)的范围。 好的,有没有适合我的场景或用例的解决方案或方法,请建议【参考方案2】:
Session["TSNPAC"] = "TSNPAC";

据我所知,我们可以在控制器之间共享会话值,关于会话为空,可能问题与会话过期时间和asp.net核心中会话的使用有关。

要在 asp.net Core 中使用 session,Startup 必须包含:

任何IDistributedCache 内存缓存。 IDistributedCache 实现用作会话的后备存储。如需更多信息,请参阅Distributed caching in ASP.NET Core。 在 ConfigureServices 中调用 AddSession。 在配置中调用UseSession

Startup.cs 如下:

public class Startup

    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public IConfiguration Configuration  get; 

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        
            options.IdleTimeout = TimeSpan.FromMinutes(20); // set the session expired time.
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        );

        services.AddControllersWithViews();
    

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
        
        else
        
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseSession();

        app.UseEndpoints(endpoints =>
        
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "controller=Home/action=Index/id?");
        );
    

通过上述配置,我们将会话过期时间设置为20分钟。

然后,在控制器中,我们可以使用以下代码来获取或设置会话中的值:

    public const string SessionKeyName = "_Name";
    public IActionResult Index()
     
        //Requires: using Microsoft.AspNetCore.Http;
        if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))
        
            //set value to session
            HttpContext.Session.SetString(SessionKeyName, "The Doctor"); 
        
        //Get value from session
        var name = HttpContext.Session.GetString(SessionKeyName);

        //used to display value in the view page.
        ViewData["name"] = name; 
        return View();
    

如果你想使用 session 来存储对象,你必须添加 SessionExtensions,检查this article。

更多使用session的详细信息,请查看Session State。

如果还是无法通过session获取值,可以考虑将值存入缓存或数据库中。

【讨论】:

这是我设置会话并在重定向后将其访问到另一个控制器但我得到的值为 null 的步骤,它在我的场景中是否有效,我可以从一个控制器访问会话值以Dotnet Core 3.1 MVC 中的另一个,尽管重定向到作为来自 Web 服务的响应接收的 URL 并返回到第二个控制器以访问该值。 有什么具体的我需要尝试不让值 null 或其他方法,请建议 嗨@TSNandakumar,根据你的描述,我还创建了一个 Asp.net core 3.1 MVC 应用程序,会话可以在控制器之间共享(创建一个新的 asp.net core mvc 应用程序并使用上面的代码配置会话)。检查Session state后,似乎会话也与cookie有关,请检查浏览器并确保它启用cookie。此外,使用AddSession时,将会话cookie设置为必不可少:services.AddSession(op => op.Cookie.IsEssential = true;); 嗨@Zhi Lv,你能不能参考我下面的帖子,我在使用会话时到底尝试了什么【参考方案3】:

我尝试了以下步骤: 在 startup.cs 中,在 ConfigureServices(IServiceCollection services) 方法中`

services.AddDistributedMemoryCache();services.AddSession(options =>
options.IdleTimeout = TimeSpan.FromMinutes(20);options.Cookie.HttpOnly = true;options.Cookie.IsEssential = true;);

In Configure(IApplicationBuilder app, IWebHostEnvironment env) ,app.UseSession();In 1st Controllerstring MercerCode = "T S Nandakumar"; HttpContext.Session.SetString("Code", MercerCode);In 2nd Controllerstring codetest = HttpContext.Session.GetString("Code");`

但是在 URL 重定向后的第二个控制器中,获取 Null 值,您能否让我知道我是否遗漏了您的任何步骤?

【讨论】:

【参考方案4】:

我尝试了 TempData,但与这种方法不同,它奏效了。

我在将列表存储在 TempData 时对其进行了序列化

帐户控制器:

TempData["BiUsers"] = JsonConvert.SerializeObject(users);

(users 是 UserModel 的 IEnumerable)

并在另一个我想使用该 IEnumerable 的控制器中对其进行反序列化。

家庭控制器:

var users = JsonConvert.DeserializeObject<IEnumerable<UserModel>>(TempData["BiUsers"].ToString());

【讨论】:

以上是关于在 Dotnet Core 3.1 中将数据从一个控制器传递到另一个控制器的主要内容,如果未能解决你的问题,请参考以下文章

Dotnet Core 3.1:如何将 AddJsonFile 与文件的绝对路径一起使用?

无法从部署中心为 Dotnet core 3.1 配置 CI 构建。有啥方法可以设置 CI Azure DevOps

dotNet Core 3.1 使用 Aspose (部署 Docker)

如何将 ILoggerFactory 添加到启动 dotnet core 3.1

如何将 c# dotnet core 3.1 微服务流绑定到涡轮服务器流

同时针对 ef core 3.1 和 5 是个好主意吗?