如何从会话中调用一个对象列表?

huangapple go评论78阅读模式
英文:

How to call a list of objects from a session?

问题

以下是您要翻译的内容:

我正在创建一个这样的发票:
对于已登录的用户,我将发票和发票单元保存到数据库中(一个发票有多个发票单元),对于未登录的用户,我正在尝试将数据保存到会话中

[HttpPost]
public ActionResult Create(Invoice invoice)
{
    var userId = User.Claims.FirstOrDefault(c => c.Type == "UserId")?.Value;
    if (userId is not null)
    {
        invoice.UserId = Guid.Parse(userId.ToString());
        DateTime dateTime = DateTime.Now;
        invoice.DateCreated = dateTime;
        foreach (var invoiceUnit in invoice.InvoiceUnits)
        {
            db.InvoiceUnits.Add(invoiceUnit);
        }
        db.Add(invoice);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    else
    {
        invoice.Id = Guid.NewGuid();
        var invoicesFromSession = GetInvoicesFromSession();
        var invoiceUnitsFromSession = GetInvoiceUnitsFromSession();

        DateTime dateTime = DateTime.Now;
        invoice.DateCreated = dateTime;

        if (invoice is not null)
        {
            invoicesFromSession.Add(invoice);

            HttpContext.Session.SetString("invoice", JsonSerializer.Serialize(invoicesFromSession));

            foreach(var invoiceUnit in invoice.InvoiceUnits)
            {
                invoiceUnit.Id = new Guid();
                invoiceUnit.InvoiceId = invoice.Id;
                HttpContext.Session.SetString("invoiceUnit", JsonSerializer.Serialize(invoiceUnitsFromSession));
                invoiceUnitsFromSession.Add(invoiceUnit);
            }

        }

        return RedirectToAction("Index");
    }
}

我是这样从会话中获取发票单元的:

private List<InvoiceUnit> GetInvoiceUnitsFromSession()
{
    HttpContext.Session.LoadAsync();
    var sessionString = HttpContext.Session.GetString("invoiceUnit");
    if (sessionString is not null)
    {
        return JsonSerializer.Deserialize<List<InvoiceUnit>>(sessionString);
    }

    return Enumerable.Empty<InvoiceUnit>().ToList();
}

然后我尝试在Edit控制器中调用该函数

var sessionInvoices = GetInvoicesFromSession();
var sessionInvoiceUnits = GetInvoiceUnitsFromSession();
var invoiceFromDbSession = sessionInvoices.FirstOrDefault(i => i.Id == id);
List<InvoiceUnit> invoiceUnitsForInvoiceSession = new List<InvoiceUnit>();

foreach (var invoiceUnit in sessionInvoiceUnits)
{
    if (invoiceUnit.InvoiceId == id)
    {
        invoiceUnitsForInvoiceSession.Add(invoiceUnit);
    }
}
GenericModel sessionData = new GenericModel(invoiceUnitsForInvoiceSession, invoiceFromDbSession);
return View(sessionData);

不知何故,当我在Edit控制器中调用`GetInvoiceUnitsFromSession();`来检索特定发票的所需发票单元时,我只收到每个发票的一个发票单元(我输入的第一个发票)。当我在create函数中调试`invoiceUnitsFromSession`变量时,单位数量与特定发票的数量完全吻合,因此我认为在尝试检索会话时必须存在某种问题。有没有任何想法要进行哪些更改,以便检索我收到的所有发票单元,以便在Edit控制器中获取它们
英文:

I am creating an invoice like this:
For signed in users, I save the invoices and the invoice units to database (one invoice has many invoice units) and for users that are not signed in, I am trying to save the data into sessions

    [HttpPost]
public ActionResult Create(Invoice invoice)
{
var userId = User.Claims.FirstOrDefault(c =&gt; c.Type == &quot;UserId&quot;)?.Value;
if (userId is not null)
{
invoice.UserId = Guid.Parse(userId.ToString());
DateTime dateTime = DateTime.Now;
invoice.DateCreated = dateTime;
foreach (var invoiceUnit in invoice.InvoiceUnits)
{
db.InvoiceUnits.Add(invoiceUnit);
}
db.Add(invoice);
db.SaveChanges();
return RedirectToAction(&quot;Index&quot;);
}
else
{
invoice.Id = Guid.NewGuid();
var invoicesFromSession = GetInvoicesFromSession();
var invoiceUnitsFromSession = GetInvoiceUnitsFromSession();
DateTime dateTime = DateTime.Now;
invoice.DateCreated = dateTime;
if (invoice is not null)
{
invoicesFromSession.Add(invoice);
HttpContext.Session.SetString(&quot;invoice&quot;, JsonSerializer.Serialize(invoicesFromSession));
foreach(var invoiceUnit in invoice.InvoiceUnits)
{
invoiceUnit.Id = new Guid();
invoiceUnit.InvoiceId = invoice.Id;
HttpContext.Session.SetString(&quot;invoiceUnit&quot;, JsonSerializer.Serialize(invoiceUnitsFromSession));
invoiceUnitsFromSession.Add(invoiceUnit);
}
}
return RedirectToAction(&quot;Index&quot;);
}
}

I am getting the invoice units from session like this:

    private List&lt;InvoiceUnit&gt; GetInvoiceUnitsFromSession()
{
HttpContext.Session.LoadAsync();
var sessionString = HttpContext.Session.GetString(&quot;invoiceUnit&quot;);
if (sessionString is not null)
{
return JsonSerializer.Deserialize&lt;List&lt;InvoiceUnit&gt;&gt;(sessionString);
}
return Enumerable.Empty&lt;InvoiceUnit&gt;().ToList();
}

And then I am trying to call the function in the Edit controller

            var sessionInvoices = GetInvoicesFromSession();
var sessionInvoiceUnits = GetInvoiceUnitsFromSession();
var invoiceFromDbSession = sessionInvoices.FirstOrDefault(i =&gt; i.Id == id);
List&lt;InvoiceUnit&gt; invoiceUnitsForInvoiceSession = new List&lt;InvoiceUnit&gt;();
foreach (var invoiceUnit in sessionInvoiceUnits)
{
if (invoiceUnit.InvoiceId == id)
{
invoiceUnitsForInvoiceSession.Add(invoiceUnit);
}
}
GenericModel sessionData = new GenericModel(invoiceUnitsForInvoiceSession, invoiceFromDbSession);
return View(sessionData);

From some reason tho, when I call the GetInvoiceUnitsFromSession(); in the Edit controller to retrieve the wanted invoice unit for the specific invoice, I only receive one invoice unit for each invoice (the first one I have entered). When I debug the invoiceUnitsFromSession variable in the create function, the number of units fits just fine for the specific invoice so I think there must be some problem in the way I am trying to retreive the session. Any idea what changes to make in order to retreive all of the invoice units I recieve for all invoices so I can get them in Edit controller?

答案1

得分: 1

调用会话中的对象列表

您是否想要以下方式?

配置您的 SessionExtension 如下:

public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonSerializer.Serialize(value));
    }

    public static T? Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);
        return value == null ? default : JsonSerializer.Deserialize<T>(value);
    }
}

然后使用以下方式的方法:

////  您的对象列表
List<MyClass> classCollection = new List<MyClass>();

//// 在会话中设置值
HttpContext.Session.Set<List<MyClass>>("someKey", classCollection);

//// 从会话中获取值
List<MyClass> classCollection = HttpContext.Session.Get<List<MyClass>>("someKey");

阅读 Set and get Session values 了解更多信息。

英文:

> call a list of objects from a session

Do you want the below way?

Configure your SessionExtension like below:

public static class SessionExtensions
{
public static void Set&lt;T&gt;(this ISession session, string key, T value)
{
session.SetString(key, JsonSerializer.Serialize(value));
}
public static T? Get&lt;T&gt;(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default : JsonSerializer.Deserialize&lt;T&gt;(value);
}
}

Then use methods like below:

////  your list object
List&lt;MyClass&gt; classCollection = new List&lt;MyClass&gt;();
//// To set value in session
HttpContext.Session.Set&lt;List&lt;MyClass&gt;&gt;(&quot;someKey&quot;, classCollection);
//// To Get Value from Session
List&lt;MyClass&gt; classCollection = HttpContext.Session.Get&lt;List&lt;MyClass&gt;&gt;(&quot;someKey&quot;);

Read Set and get Session values to know more.

答案2

得分: 1

以下是翻译好的部分:

问题出现在这个代码块中:

                foreach(var invoiceUnit in invoice.InvoiceUnits)
                {
                    invoiceUnit.Id = new Guid();
                    invoiceUnit.InvoiceId = invoice.Id;
                    HttpContext.Session.SetString(&quot;invoiceUnit&quot;, JsonSerializer.Serialize(invoiceUnitsFromSession)); // 具体是这行
                    invoiceUnitsFromSession.Add(invoiceUnit);
                }

在这里,您在每次循环重复之前都写入了键invoiceUnit的值,因此至少最后一行始终会丢失。您可以改变顺序:

                foreach(var invoiceUnit in invoice.InvoiceUnits)
                {
                    invoiceUnit.Id = new Guid();
                    invoiceUnit.InvoiceId = invoice.Id;
                    invoiceUnitsFromSession.Add(invoiceUnit);
                    HttpContext.Session.SetString(
                       &quot;invoiceUnit&quot;, 
                       JsonSerializer.Serialize(invoiceUnitsFromSession));
                }

或者将存储发票单位到会话中的行移到循环之外,以避免不必要的重复:

                foreach(var invoiceUnit in invoice.InvoiceUnits)
                {
                    invoiceUnit.Id = new Guid();
                    invoiceUnit.InvoiceId = invoice.Id;
                    invoiceUnitsFromSession.Add(invoiceUnit);
                }
                HttpContext.Session.SetString(
                   &quot;invoiceUnit&quot;, 
                   JsonSerializer.Serialize(invoiceUnitsFromSession));
英文:

The issue you see comes from this block:

                foreach(var invoiceUnit in invoice.InvoiceUnits)
                {
                    invoiceUnit.Id = new Guid();
                    invoiceUnit.InvoiceId = invoice.Id;
                    HttpContext.Session.SetString(&quot;invoiceUnit&quot;, JsonSerializer.Serialize(invoiceUnitsFromSession)); // Specifically this line
                    invoiceUnitsFromSession.Add(invoiceUnit);
                }

Here you're writing the value for the key invoiceUnit on each repetition of the loop before you actually update the value, so at least the last line will always be missing. You would want to either change the order:

                foreach(var invoiceUnit in invoice.InvoiceUnits)
                {
                    invoiceUnit.Id = new Guid();
                    invoiceUnit.InvoiceId = invoice.Id;
                    invoiceUnitsFromSession.Add(invoiceUnit);
                    HttpContext.Session.SetString(
                       &quot;invoiceUnit&quot;, 
                       JsonSerializer.Serialize(invoiceUnitsFromSession));
                }

or move the line that stores invoice units into the session out of the loop completely to avoid unnecessary repetition:

                foreach(var invoiceUnit in invoice.InvoiceUnits)
                {
                    invoiceUnit.Id = new Guid();
                    invoiceUnit.InvoiceId = invoice.Id;
                    invoiceUnitsFromSession.Add(invoiceUnit);
                }
                HttpContext.Session.SetString(
                   &quot;invoiceUnit&quot;, 
                   JsonSerializer.Serialize(invoiceUnitsFromSession));

huangapple
  • 本文由 发表于 2023年1月9日 01:05:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75049755.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定