Xtensive.Orm.Web 7.1.2

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Xtensive.Orm.Web --version 7.1.2                
NuGet\Install-Package Xtensive.Orm.Web -Version 7.1.2                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Xtensive.Orm.Web" Version="7.1.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Xtensive.Orm.Web --version 7.1.2                
#r "nuget: Xtensive.Orm.Web, 7.1.2"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Xtensive.Orm.Web as a Cake Addin
#addin nuget:?package=Xtensive.Orm.Web&version=7.1.2

// Install Xtensive.Orm.Web as a Cake Tool
#tool nuget:?package=Xtensive.Orm.Web&version=7.1.2                

Xtensive.Orm.Web

Summary

The extension adds integration for DataObjects.Net and ASP.NET Core. It contains an action filter called SessionActionFilter and a middleware called OpenSessionMiddleware. The action filter is useful for providing session per MVC action. The middleware, though, has wider coverage and can provide session to actions, controllers, razor pages and to other middleware down the pipeline. Both of them open session and transaction and at the end dispose them. As obsolete SessionManager, they complete transacton scope by default unless an exeption appeared. (more info on https://dataobjects.net)

Prerequisites

DataObjects.Net 7.1 or later (https://dataobjects.net)

Usage of action filter

To start using action filter it should be added to action filters collection like so

public class Startup
{
  public Startup(IConfiguration configuration)
  {
    
  }

  public void ConfigureServices(IServiceCollection services)
  {
    var domain = BuildDomain();

    // Domain should be available as service to have
    // access to it from action filter.
    services.AddSingleton<Domain>(domain);

    // Adds SessionAccessor as scoped service (one instance per request).
    // Session accessor will be able to access Session and TransactionScope
    // instances which are in HttpContext
    services.AddDataObjectsSessionAccessor();

    // Adds the action filter
    services.AddControllers(options => options.Filters.AddDataObjectsSessionActionFilter());
  }

  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
    if (env.IsDevelopment()) {
      app.UseDeveloperExceptionPage();
    }
    else {
      app.UseExceptionHandler("/Home/Error");
    }
    app.UseStaticFiles()
      .UseRouting()
      .UseAuthorization()
      .UseEndpoints(endpoints => {
        endpoints.MapControllerRoute(
          name: "default",
          pattern: "{controller=Home}/{action=Index}/{id?}");
      });
  }
}


After action filter is added you can use it like in the example bellow

public class HomeController : Controller
{
  // If action require Session and TransactionScope to be opened then
  // just put parameter like in this method.
  // Action filter will find it wrap action with session
  public IActionResult Index([FromServices] SessionAccessor sessionAccessor)
  {
    var sessionInstance = sessionAccessor.Session;
    var transactionScopeInstance = sessionAccessor.TransactionScope;

    // some queries to database

    return View();
  }

  // If action does not require opened Session
  // then don't put SessionAccessor as parameter
  // action filter will skip openings
  public IActionResult Privacy()
  {
    return View();
  }
}


Usage of Middleware
-------------------

The middleware is needed to be placed to pipeline before any other middleware that require access
to session. Pipeline may be configured like so

public class Startup
{
  public Startup(IConfiguration configuration)
  {
    
  }

  public void ConfigureServices(IServiceCollection services)
  {
    var domain = BuildDomain();

    // Domain should be available as service to have
    // access to it from action filter.
    services.AddSingleton<Domain>(domain);

    // Adds SessionAccessor as scoped service (one instance per request).
    // Session accessor will be able to access Session and TransactionScope
    // instances which are in HttpContext
    services.AddDataObjectsSessionAccessor();

    // Adds the action filter
    services.AddControllers();
  }

  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
    if (env.IsDevelopment()) {
      app.UseDeveloperExceptionPage();
    }
    else {
      app.UseExceptionHandler("/Home/Error");
    }
    app.UseStaticFiles()
      .UseRouting()// this middleware won't have opened session
      .UseDataObjectsSessionOpener()// open Session and Transaction scope
      .UseAuthorization()// this middleware and the rest down the pipe have Session access
      .UseEndpoints(endpoints => {
        endpoints.MapControllerRoute(
          name: "default",
          pattern: "{controller=Home}/{action=Index}/{id?}");
      });
  }
}

After that you can access opened Session and TransactionScope

public class HomeController : Controller
{
  // access from controller's constructor
  public HomeController(SessionAccessor sessionAccessor)
  {
    // some work
  }

  // access from action
  public IActionResult Index([FromServices] SessionAccessor sessionAccessor)
  {
    var sessionInstance = sessionAccessor.Session;
    var transactionScopeInstance = sessionAccessor.TransactionScope;

    // some queries to database

    return View();
  }

  // NOTE that here session is opened too,
  // even there is no SessionAccessor as parameter
  // this is the difference in work of middleware and action filter
  public IActionResult Privacy()
  {
    return View();
  }
}


The middleware is also usable in Razor Pages projects. In this case
your Startup class may look like this:

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)
  {
    var domain = Domain.Build();
    services.AddSingleton(domain);
    services.AddDataObjectsSessionAccessor();
    services.AddRazorPages();
  }

  // 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("/Error");
    }

    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseDataObjectsSessionOpener();

    app.UseEndpoints(endpoints =>
    {
      endpoints.MapRazorPages();
    });
  }
}

And then in actual pages you can use SessionAccessor like below

public class IndexModel : PageModel {

public IndexModel(SessionAccessor accessor) { _logger = logger; }

public void OnGet([FromServices] SessionAccessor sessionAccessor) { var sessionInstance = sessionAccessor.Session;

// query some data from database

} }

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
7.2.0-Beta-1 393 12/28/2023
7.1.2 112 10/18/2024
7.1.1 523 11/14/2023
7.1.0 844 4/12/2023
7.1.0-RC 652 3/9/2023
7.1.0-Beta-2 718 12/19/2022
7.1.0-Beta-1 713 7/4/2022
7.0.5 102 6/3/2024
7.0.4 465 11/12/2023
7.0.3 1,120 3/21/2022
7.0.2 1,093 2/8/2022
7.0.1 984 10/29/2021
7.0.0 975 6/2/2021
6.0.13 134 4/4/2024
6.0.12 449 11/10/2023
6.0.11 885 1/12/2023
6.0.10 1,008 4/29/2022
6.0.9 1,045 2/2/2022
6.0.8 979 10/28/2021
6.0.7 960 8/27/2021
6.0.6 1,011 5/24/2021
6.0.5 1,065 3/9/2021
6.0.4 1,146 12/22/2020
6.0.3 1,133 9/29/2020
6.0.0 1,290 1/28/2020
5.1.0-Beta-1 4,987 1/30/2015
5.0.24 952 4/27/2021
5.0.23 1,027 2/4/2021
5.0.22 1,164 11/18/2020
5.0.21 1,148 11/6/2020
5.0.20 1,290 12/25/2019
5.0.19 1,351 5/30/2019
5.0.19-Beta-2 1,006 4/16/2019
5.0.19-Beta-1 1,113 12/29/2018
5.0.18 1,586 9/28/2018
5.0.18-Beta-3 1,307 7/2/2018
5.0.18-Beta-2 1,371 6/6/2018
5.0.18-Beta-1 1,405 4/24/2018
5.0.17 1,694 2/27/2018
5.0.17-Beta-3 1,375 2/12/2018
5.0.17-Beta-2 1,468 1/12/2018
5.0.17-Beta-1 1,479 12/28/2017
5.0.16 1,570 12/1/2017
5.0.16-Beta-1 1,327 9/27/2017
5.0.15 1,548 8/1/2017
5.0.14 1,657 6/19/2017
5.0.13 1,666 3/22/2017
5.0.12 1,702 2/14/2017
5.0.11 1,679 1/26/2017
5.0.11-RC2 1,430 12/16/2016
5.0.11-RC 1,677 9/20/2016
5.0.10 1,710 8/5/2016
5.0.10-RC 1,434 6/30/2016
5.0.9 4,023 3/3/2016
5.0.8 1,758 2/15/2016
5.0.7 1,736 1/27/2016
5.0.7-RC2 1,432 12/8/2015
5.0.7-RC 1,501 9/10/2015
5.0.6 1,838 7/3/2015
5.0.5 1,947 4/23/2015
5.0.4 1,733 3/19/2015
5.0.4-RC 1,800 2/25/2015
5.0.3 2,104 10/31/2014
5.0.2 1,822 9/11/2014
5.0.0 1,839 8/15/2014
5.0.0-RC2 1,503 8/1/2014
5.0.0-RC 1,525 7/21/2014
5.0.0-Beta-3 1,509 5/28/2014
5.0.0-Beta-2 1,600 2/28/2014
5.0.0-Beta-1 1,614 11/14/2013
4.6.9 1,645 7/3/2015
4.6.8 1,798 8/1/2014
4.6.7 1,783 6/23/2014
4.6.6 1,970 4/9/2014
4.6.5 1,841 1/7/2014
4.6.4 1,987 9/30/2013
4.6.3 1,918 2/4/2013
4.6.2 2,178 11/28/2012
4.6.0 2,086 10/11/2012
4.6.0-RC 1,739 10/4/2012
4.5.8 1,793 9/30/2013
4.5.7 1,766 2/4/2013
4.5.6 2,043 11/28/2012
4.5.5 1,976 10/11/2012
4.5.5-RC 1,658 10/4/2012
4.5.3 2,233 8/6/2012
4.5.2 2,400 5/10/2012
4.5.0 2,108 3/13/2012