简体   繁体   中英

Serialize and deserialize an IEnumerable in Session

I have this method:

public static class SessionExtension
{

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

}

Which is useful to serialize my list of IEnumerable:

public IEnumerable<FBudget> RecordsList { get; set; }

So after filtering the data I serialize the object:

//BUILD FILTER
static Expression<Func<FBudget, bool>> BuildFilter(BudgetViewModel budget)
{
    ...
}


 /*STORE THE ACTUAL FILTER IN SESSION*/
 SessionExtension.SetObjectAsJson(HttpContext.Session, "SessionFilter", budget);

An the deserialize it:

 public IActionResult Index()
    {
        var json = SessionExtension.GetObjectFromJson<IEnumerable<FBudget>>(HttpContext.Session, "SessionFilter");

        BudgetVM = new BudgetViewModel()
        {
            FBudget = new FBudget(),

            ...

           
            RecordsList = json



    };

        return View(BudgetVM);

    }

But when I try to deserialize it, the compiler give the the following error:

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[...]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'FBudget', line 1, position 11.'

Also I'm trying to do this in order to keep in session the result of the BuildFilter() method, so when the user return to a previous page the filters are saved.

Is the correct approach? What am I doing wrong?

This is the Json which is sendend to the method GetObjectFromJson:

{"BudgetId":0,"Year":0,"FreeOfCharge":null,"Currency":null,"UnitPrice":0.0,"MonthNr":null,"UnitOfMeasure":null,"Quantity":0,"TotalAmount":0.0,"LastUser":null,"ProgramId":0,"LastUpdate":"2021-11-03T15:08:15.65645+01:00","ItemMasterId":0,"ItemMaster":{"ItemMasterId":0,"ItemNumber":0,"ShortItem":null,"ItemDescription":null,"UnitOfMeasure":null,"FBudgets":null,"PharmaFormId":0,"PharmaForm":null,"ProductGroupId":0,"ProductGroup":null,"UnToBulkId":0,"UnToBulk":null,"UnToKgId":0,"UnToKg":null},"CompanyId":2,"Company":null,"LedgerTypeId":0,"LedgerType":null,"CustomerId":0,"Customer":{"CustomerId":0,"CustomerName":null,"CustomerGroupCode":null,"CountryCode":null,"CustomerGroupName":null,"LicensingArea":null,"FBudgets":null}}

Since your mentioned json is an object not an array, for deserialize try the below code:

public IActionResult Index()
{
    var json = SessionExtension.GetObjectFromJson<FBudget>(HttpContext.Session, "SessionFilter");

    BudgetVM = new BudgetViewModel()
    {
        FBudget = new FBudget(),
        ...
       
        RecordsList = new List<FBudget> { json }
    };

    return View(BudgetVM);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM