Search code examples
c#asp.net-core.net-coreasp.net-core-mvc.net-core-2.0

Session Store IQueryable in HttpContext


I am migrating project from Net MVC to MVC Core 2.

How do I set IQueryable in Sessions? In Net MVC it was the following,

    public ActionResult CurrentOwners_Read([DataSourceRequest]DataSourceRequest request, int propertyID)
    {
        if (propertyID == 0)
        {
            throw new ArgumentNullException("propertyID");
        }

        IQueryable<PropertyOwnerRoleViewModel> allResult = (IQueryable<PropertyOwnerRoleViewModel>)HttpContext.Session.GetString(_currentOwnersResult).AsQueryable();

        if (allResult == null)
        {
            PropertyOwnerManager propertyOwnerManager = new PropertyOwnerManager();
            allResult = propertyOwnerManager.GetPropertyOwnershipSummary(propertyID).AsQueryable();
            Session.Add(_currentOwnersResult, allResult);  
        }

Last Line above is giving Error:

The name 'Session' does not exist in the current context

_currentOwnersResult is string AllResult is IQueryable

When trying to convert in MVC Core, the following does not work either

HttpContext.Session.SetString(_currentOwnersResult, allResult);

Error Code:

cannot convert from 'System.Linq.IQueryable<HPE.Kruta.Model.PropertyOwnerRoleViewModel>' to 'string'    

Solution

  • Okay, so as a basic example on how to setup a complex object in your Session in .NET Core:

    First setup your session:

    In your Startup.cs, under the Configure method, add the following line:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    app.UseSession();
    }
    

    And under the ConfigureServices method, add the following line:

    public void ConfigureServices(IServiceCollection services)
    {
      //Added for session state
      services.AddDistributedMemoryCache();
    
      services.AddSession(options =>
      {
      options.IdleTimeout = TimeSpan.FromMinutes(10);               
      });
    }
    

    To add complex objects in your list to your Session (Please note that this an example only and not specific to your case since I do not know what PropertyOwnerRoleViewModel definiton is):

    Model:

    public class EmployeeDetails
    {
        public string EmployeeId { get; set; }
        public string DesignationId { get; set; }
    }
    
    public class EmployeeDetailsDisplay
    {
        public EmployeeDetailsDisplay()
        {
            details = new List<EmployeeDetails>();
        }
        public List<EmployeeDetails> details { get; set; }
    }
    

    Then create a SessionExtension helper to set and retrieve your complex object as JSON:

    public static class SessionExtensions
            {
                public static void SetObjectAsJson(this ISession session, string key, object value)
                {
                    session.SetString(key, JsonConvert.SerializeObject(value));
                }
    
                public static T GetObjectFromJson<T>(this ISession session, string key)
                {
                    var value = session.GetString(key);
    
                    return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
                }
            }
    

    Adding this complex object to your session:

     //Create complex object
     var employee = new EmployeeDetailsDisplay();
    
     employee.details.Add(new EmployeeDetails
     {
     EmployeeId = "1",
     DesignationId = "2"
     });
    
     employee.details.Add(new EmployeeDetails
     {
     EmployeeId = "3",
     DesignationId = "4"
     });
    //Add to your session
    HttpContext.Session.SetObjectAsJson("EmployeeDetails", employee);
    

    And finally to retrieve your complex objects from your Session:

    var employeeDetails = HttpContext.Session.GetObjectFromJson<EmployeeDetailsDisplay>("EmployeeDetails");
    
    //Get list of all employee id's
    List<int> employeeID = employeeDetails.details.Select(x => Convert.ToInt32(x.EmployeeId)).ToList();
    //Get list of all designation id's
    List<int> designationID= employeeDetails.details.Select(x=> Convert.ToInt32(x.DesignationId)).ToList();