【问题标题】:Session Store IQueryable in HttpContextHttpContext 中的会话存储 IQueryable
【发布时间】:2019-03-20 17:39:27
【问题描述】:

我正在将项目从 Net MVC 迁移到 MVC Core 2。

如何在 Sessions 中设置 IQueryable? 在 Net MVC 中是这样的,

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

上面的最后一行给出了错误:

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

_currentOwnersResult 是字符串 AllResult 是 IQueryable

当尝试在 MVC Core 中转换时,以下也不起作用

HttpContext.Session.SetString(_currentOwnersResult, allResult);

错误代码:

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

【问题讨论】:

  • IQueryable 是一个尚未运行的查询,而不是需要存储的数据。即使在 MVC 中。我希望一个名为allResult 的变量无论如何都包含查询的results,而不是查询本身。也许实际类型是 IEnumerable ?
  • 你为什么要这样做?
  • @JoeSmith 它在那里也不起作用。这不是语法问题。 allResult 是如何创建的?
  • @JoeSmith 至于 contextsession,1) does not work 是什么意思? 2) 你在哪里找到HttpContext?在 ASP.NET Core MVC 中,上下文不再是单例对象,而是注入到构造函数中。这也允许轻松测试控制器。在最新的 Razor Pages 中,它又是一个单例,但更容易测试

标签: c# asp.net-core .net-core asp.net-core-mvc .net-core-2.0


【解决方案1】:

好的,作为一个基本示例,介绍如何在 .NET Core 的 Session 中设置复杂对象:

首先设置您的会话:

在您的 Startup.cs 中,在 Configure 方法下,添加以下行:

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

并在 ConfigureServices 方法下,添加以下行:

public void ConfigureServices(IServiceCollection services)
{
  //Added for session state
  services.AddDistributedMemoryCache();

  services.AddSession(options =>
  {
  options.IdleTimeout = TimeSpan.FromMinutes(10);               
  });
}

将列表中的复杂对象添加到会话中(请注意,这只是一个示例,并不特定于您的情况,因为我不知道 PropertyOwnerRoleViewModel 定义是什么):

型号:

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

然后创建一个 SessionExtension 帮助器来将您的复杂对象设置和检索为 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);
            }
        }

将此复杂对象添加到您的会话中:

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

最后从 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();

【讨论】:

猜你喜欢
  • 2018-09-07
  • 2012-06-30
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 1970-01-01
  • 2019-05-02
  • 2015-03-12
  • 1970-01-01
相关资源
最近更新 更多