0

I bind the model to a session in ASP MVC Framework like this:

 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {

            Cart cart = null;


            if(controllerContext.HttpContext.Session != null)
            {
                cart = (Cart)controllerContext.HttpContext.Session[sessionKey];
            }


            if(cart == null)
            {
                cart = new Cart();

                if (controllerContext.HttpContext.Session != null)
                {

                    controllerContext.HttpContext.Session[sessionKey] = cart;
                }


            }

            return cart;
        }

Now I want to do the same thing in ASM MVC Core, and this was my attempt:

public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            Cart cart = null;

            if (bindingContext.HttpContext.Session != null)
            {
                cart = (Cart)JsonConvert.DeserializeObject(bindingContext.HttpContext.Session.GetString(sessionKey));
            }

            if (cart == null)
            {
                cart = new Cart();

                if (bindingContext.HttpContext.Session != null)
                {
                    bindingContext.HttpContext.Session.SetString(sessionKey, JsonConvert.SerializeObject(cart));
                }


            }

            return Task.CompletedTask;
        }

I also have the class for model binder provider.

But I get a run-time error on this line, saying that the object is null:

cart = (Cart)JsonConvert.DeserializeObject(bindingContext.HttpContext.Session.GetString(sessionKey));

The string returned from 'GetString(sessionKey)' is null. The full message is:

System.ArgumentNullException: 'Value cannot be null. Parameter name: value''.
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Ivan
  • 1,081
  • 2
  • 17
  • 43
  • *What* object is null? What is the *full* error message? The context or the returned string? The .NET Core code doesn't just read something from the Session, it tries to *deserialize* it as well. If you pass a null to `DeserializeObject` you'll get an `ArgumentNullException`. You should check the string's value *before* you try to deserialize it – Panagiotis Kanavos May 21 '19 at 10:26
  • @PanagiotisKanavos the string returned from 'GetString(sessionKey)' is null. The full message is: "System.ArgumentNullException: 'Value cannot be null. Parameter name: value''. – Ivan May 21 '19 at 10:30

1 Answers1

0

The question doesn't mention what exception is thrown, but this code is guaranteed to fail the first time an attempt is made to read from the session.

The second snippet tries to deserialize a string without checking whether it's null or not :

cart=(Cart)JsonConvert.DeserializeObject(bindingContext.HttpContext.Session.GetString(sessionKey));

Or, in a more readable way:

var json=bindingContext.HttpContext.Session.GetString(sessionKey);
cart = (Cart)JsonConvert.DeserializeObject(json);

JsonConvert.DeserializeObject() will throw if its argument is null.

The json string must be checked before calling DeserializeObject. With some cleanup, the code could look like this:

var session=bindingContext.HttpContext.Session;
if(session == null)
{
    return null;
}
var json = sessio.GetString(sessionKey);
if (!String.IsNullOrWhitespace(json))
{
    var cart=JsonConvert.DeserializeObject<Cart>(json);
    return cart;
}
else
{  
    var emptyCart=new Cart();
    var value=JsonConvert.SerializeObject(emptyCart);
    session.SetString(sessionKey, value);
    return emptyCart;
}

The null safe operator can be used to handle missing context values, eg during testing :

var session=bindingContext?.HttpContext?.Session;

This will return null if any of the objects is null.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • FIrst code snippet already works and it was tested. In second snippet, if I use what you suggested, this line: 'var json = session[sessionKey];' gives compilation error saying : 'Cannot apply indexing with [] to an extension of type ISession. – Ivan May 21 '19 at 11:01
  • @Ivan that's not the point at all. The code lines were so long that I didn't even see how you read the strings. The problem, which is explained by the error message itself, is that you try to call `JsonConvert.DeserializeObject(null);` – Panagiotis Kanavos May 21 '19 at 11:13
  • yes, I understand, but what is the solution for not getting null? – Ivan May 21 '19 at 11:23
  • @Ivan I already posted the code. Your original code works the same way - if an item isn't found, you get a `null` and store an empty Cart instance. You'll have to do the same now - check whether the string is null and store an empty Cart instance if it is – Panagiotis Kanavos May 21 '19 at 11:23