老司机翻车记--为什么Session会取不到值

作为一个资深的老司机,用MVC5的WebApi做了个小应用,项目前后端分离,然后需要保持用户登录信息,所以很简单的通过在Global.asax文件中增加相应代码来使WebApi支持Session

        public override void Init()
        {
            this.PostAuthorizeRequest += (sender, e) => HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
            base.Init();
        }

然后用于存放当前用户信息的POCO类声明大致如下

    public class AuthInfo
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }

定义用于校验是否登录的Attribute

    public class ApiAuthorizeAttribute : AuthorizeAttribute
    {

        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
#if DEBUG
            return true;
#else
            return HttpContext.Current.Session[Consts.AuthSessionKey] as AuthInfo != null;
#endif
            //return base.IsAuthorized(actionContext);
        }
    }

最后定义一个所有需要登录验证的基类

    [ApiAuthorize]
    public abstract class ApiAuthBaseController : ApiController
    {
        /// <summary>
        /// 当前登录用户信息
        /// </summary>
        public AuthInfo AuthInfo
        {
            get
            {
#if DEBUG
                return new AuthInfo
                {
                    Id = "001",
                    Name = "张三",
                };
#else
                return HttpContext.Current.Session[Consts.AuthSessionKey] as AuthInfo;
#endif
            }
        }
    }

最终项目测试一切正常,但因为测试过程中经常需要重新发布,前端对于每次重发后就要重新登录感到不爽,为了和睦同事关系,咋必须做点事来解决这问题是不,所以问题就来了!

因为默认Session采用的Mode是InProc,只要任何导致IIS回收应用的情况产生,都会使当前应用的Session全被清除,所以简单的将Mode改为StateServer即可。

信心满满的改完配置,测试登录接口发现没啥问题,妥妥的告知前端此时已经搞定,结果半分钟不到,前端立马打脸过来,为啥登录完了,访问其它接口都返回401未授权!!!

事实告诉我们,再怎样的老司机,改完代码或者配置还是需要做些相应功能的完整测试,本地开启调试模式,Debug发现HttpContext.Current.Session在登录后是有值的,但到ApiAuthorizeAttribute时该值就取不出来了,也就导致每次IsAuthorized判断返回的都是false,这是为啥?

将Mode改回InProc,测试时的确又可以取到Session,百思不得其解,百度、bing了一番也没找到任何类似的问题,难道老司机就要翻车了?

当代码问题悬而未解时,历史经验告诉我们,反复钻牛角是没用的,去做些其它事情(比如喝喝水,上上厕所)转变一下状态,解决问题的答案可能就会突然出现在脑海里,果然上个厕所回来脑中突然灵光一闪,StateServer已经脱离了当前应用,那么复杂实体就需要序列化之后才能写入StateServer中,而目前AuthInfo并没有声明SerializableAttribute,实际动手为AuthInfo加上[Serializable]声明后,再测试果然问题成功解决了!

其实在写入Session时,框架如果返回了序列化失败异常的话,问题原因早就被发现了,但不知道为啥MVC框架没有这么做……

v-model指令主要用于实现双向数据绑定,通常用于表单元素的输入和输出。它将表单元素的与组件中的数据进行绑定,当表单元素的发生变化时,组件中的数据也会相应地更新;反之,当组件中的数据发生变化时,表单元素的也会相应地更新。 而函数是一种不可变的数据类型,它的不能随意地改变,因此在v-model指令中不能直接绑定函数。 如果需要在表单元素上绑定一个函数,可以使用事件监听器来实现。例如,可以使用v-on指令来监听表单元素的change事件,并在事件处理函数中调用相应的函数。 举个例子,假设我们有一个计数器组件,它的可以通过一个函数进行增减: ``` <template> <div> <input type="number" v-model="count"> <button @click="increment">+</button> <button @click="decrement">-</button> </div> </template> <script> export default { data() { return { count: 0 } }, methods: { increment() { this.count++ this.updateCount(this.count) }, decrement() { this.count-- this.updateCount(this.count) }, updateCount(count) { // 在这里调用相应的函数 } } } </script> ``` 在这个例子中,我们通过v-model指令将表单元素的与组件中的count数据进行了绑定,在点击加号或减号按钮时,会触发increment或decrement方法,并在这两个方法中更新count数据,同时调用updateCount方法将更新后的count传递给相应的函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值