【问题标题】:How to bind a model to a session in ASP MVC Core如何将模型绑定到 ASP MVC Core 中的会话
【发布时间】:2019-05-21 19:13:45
【问题描述】:

我将模型绑定到 ASP MVC 框架中的会话,如下所示:

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

现在我想在 ASM MVC Core 中做同样的事情,这是我的尝试:

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

我也有模型绑定器提供者的类。

但是我在这一行得到一个运行时错误,说对象为空:

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

“GetString(sessionKey)”返回的字符串为空。完整的信息是:

System.ArgumentNullException: 'Value cannot be null. Parameter name: value''.

【问题讨论】:

  • 什么对象为空? full 错误信息是什么?上下文还是返回的字符串? .NET Core 代码不只是从 Session 中读取某些内容,它还尝试反序列化它。如果您将空值传递给DeserializeObject,您将获得ArgumentNullException。您应该在尝试反序列化之前检查字符串的值
  • @PanagiotisKanavos 从“GetString(sessionKey)”返回的字符串为空。完整的消息是:“System.ArgumentNullException: 'Value cannot be null. Parameter name: value''。

标签: asp.net-core json.net custom-model-binder


【解决方案1】:

这个问题没有提到抛出了什么异常,但是这个代码保证在第一次尝试从会话中读取时会失败。

第二个 sn-p 尝试反序列化一个字符串而不检查它是否为空:

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

或者,以更易读的方式:

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

JsonConvert.DeserializeObject() 的参数为 null 时会抛出异常。

在调用DeserializeObject之前必须检查json字符串。通过一些清理,代码可能如下所示:

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

空安全运算符可用于处理缺失的上下文值,例如在测试期间:

var session=bindingContext?.HttpContext?.Session;

如果任何对象为空,这将返回空。

【讨论】:

  • 第一个代码 sn-p 已经工作并且已经过测试。在第二个 sn-p 中,如果我使用你的建议,这一行:'var json = session[sessionKey];'给出编译错误说:'无法将 [] 索引应用于 ISession 类型的扩展。
  • @Ivan 这根本不是重点。代码行太长了,我什至没有看到你是如何读取字符串的。由错误消息本身解释的问题是您尝试调用JsonConvert.DeserializeObject(null);
  • 是的,我明白了,但是不为 null 的解决方案是什么?
  • @Ivan 我已经发布了代码。您的原始代码以相同的方式工作 - 如果找不到项目,您将获得 null 并存储一个空的 Cart 实例。您现在必须做同样的事情 - 检查字符串是否为空,如果是则存储一个空的 Cart 实例
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 2018-11-27
  • 2019-11-11
  • 2020-09-24
  • 2014-10-14
  • 2016-12-20
  • 1970-01-01
相关资源
最近更新 更多