.Net MVC4 被坑心得 (八) 缓存,弹出提示

   继续mvc4的研究学习,今天先来研究缓存技术。因为每次都去读取数据库,是效率极其低下的,尤其是对一些变化不是很大,实时性要求不是很高的内容,比如分类列表,地市列表之类的,实在不应该每次都进行磁盘操作。虽然数据库也有缓存策略,但是我们更应该将他挡在web层,在一次访问后,应当一定时期内从缓存读取数据,而根本不要建立起数据库的连接。

   当然可以自己写缓存,不过mvc究竟有没有已经实现的缓存方案呢。

   查阅资料,发现有OutputCacheAttribute这个继承自ActionFilterAttribute的Attribute,可以轻松实现缓存action结果。

  

[OutputCache(Duration = 30)]

   只需在action或者controller上加上此特性,并指定缓存时间,就可以实现缓存页面输出。当然也可以用在缓存json输出上。注意Duration的单位为秒。

   接下来要考虑些实际问题了。对于静态页,缓存当然不会有问题,或者一些只读的Action 也是没问题的,但是 如果action中有处理Form提交数据,并且有数据库操作,这个缓存显然是不能做的。可是偏偏有一些页面,一部分是可以、需要缓存的,展示的部分,另一部分 确是要处理的,不能缓存的部分(常见于同一个action时,用HttpPostAttribute修饰的处理Action)。这个怎么做呢。

   考虑两种解决方案:

   1是将需要缓存的部分,做成partialVIew和相应的action,在主体View中引用。

   2是提交不允许再次的数据绑定以绕开需要缓存的部分,具体做法可为

        a、提交通过ajax方式,返回后处理,ajax到action时,action不缓存。

        b、不用ajax提交,仍旧是表单提交,只是提交后不进行页面绑定直接跳转(如果绑定了,缓存策略等于白做了,虽然get方式打开时 使用了缓存,但是一旦提交数据,又要访问数据库),此action一样不能缓存。  这就涉及到了一会儿要讲的,如何在添加、修改、删除完成后进行页面弹出提示和跳转。

   当然,根据参数不同而做出不同缓存策略,想也是支持的。看看Attibute其他的参数:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class OutputCacheAttribute : ActionFilterAttribute, IExceptionFilter
    {
        // 摘要:
        //     初始化 System.Web.Mvc.OutputCacheAttribute 类的新实例。
        public OutputCacheAttribute();

        // 摘要:
        //     获取或设置缓存配置文件名称。
        //
        // 返回结果:
        //     缓存配置文件名称。
        public string CacheProfile { get; set; }
        //
        // 摘要:
        //     获取或设置子操作缓存。
        //
        // 返回结果:
        //     子操作缓存。
        public static System.Runtime.Caching.ObjectCache ChildActionCache { get; set; }
        //
        // 摘要:
        //     获取或设置缓存持续时间(以秒为单位)。
        //
        // 返回结果:
        //     缓存持续时间。
        public int Duration { get; set; }
        //
        // 摘要:
        //     获取或设置位置。
        //
        // 返回结果:
        //     位置。
        public OutputCacheLocation Location { get; set; }
        //
        // 摘要:
        //     获取或设置一个值,该值指示是否存储缓存。
        //
        // 返回结果:
        //     如果应存储缓存,则为 true;否则为 false。
        public bool NoStore { get; set; }
        //
        // 摘要:
        //     获取或设置 SQL 依赖项。
        //
        // 返回结果:
        //     SQL 依赖项。
        public string SqlDependency { get; set; }
        //
        // 摘要:
        //     获取或设置基于内容变化的编码。
        //
        // 返回结果:
        //     基于内容变化的编码。
        public string VaryByContentEncoding { get; set; }
        //
        // 摘要:
        //     获取或设置基于自定义项变化的值。
        //
        // 返回结果:
        //     基于自定义项变化的值。
        public string VaryByCustom { get; set; }
        //
        // 摘要:
        //     获取或设置基于标头变化的值。
        //
        // 返回结果:
        //     基于标头变化的值。
        public string VaryByHeader { get; set; }
        //
        // 摘要:
        //     获取或设置基于参数变化的值。
        //
        // 返回结果:
        //     基于参数变化的值。
        public string VaryByParam { get; set; }

       
    }

    其中有类似VaryByxxxx的一堆可疑属性,微软的注释实在是不知所云,去msdn上看到的跟元数据里的注释也没什么差别,看了还是跟没看一样。具体怎么使用,等有空在研究。(知道的朋友也可以交流下)


   先看第二个问题,返回处理结果并弹出提示,然后跳转。这个在webform时代,使用ScriptManager可以很好的解决,RegisterStartupScripts等一系列函数轻松实现了跳转后或者ajax的绑定(区别仅仅在于有没有updatepanel)。 但是在mvc,大有回复html本质的赶脚(虽然还是面目全非了,但是相对于webform这种从代码直接看,完全看不出生成的html是啥样的来说,确实是贴近了许多)。 于是,弹出提示,看起来似乎麻烦了点。

    最直接的想法,对于ajax,可以通过返回的json来判断操作结果,然后根据结果来直接alert相应提示,这个比较好理解。只是,这样,必须用ajax方式,提交到的action不能返回view了,如果返回partialview仅仅是一句alert和href,似乎有点大材小用。于是,我们来做个统一点的开关好了。

   修改_Layout.cshtml,这个是在_ViewStart.cshtml里指定的模板view,_ViewStart.cshtml属于约定的,所有view初始化时都会先走一遍的view。 

   

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @if (ViewBag.Alert != null && ViewBag.AlertRedirect != null)
    {
        <script type="text/javascript">
            alert('@ViewBag.Alert');
            window.location = '@ViewBag.AlertRedirect';
        </script>
    }
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @RenderSection("css", required: false)
</head>
<body>
    @if (ViewBag.Alert == null || ViewBag.AlertRedirect == null)
    {
        @RenderBody()
    }

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
    @RenderSection("scripts", required: false)

    @if (ViewBag.Alert != null && ViewBag.AlertRedirect == null)
    {
        <script type="text/javascript">
             alert('@ViewBag.Alert');
        </script>
    }
</body>
</html>

什么意思呢,很简单了, 通过两个动态属性来判断返回的VIew是不是需要弹出提示和跳转。

ViewBag.Alert和ViewBag.AlertRedirect都是字符串。

如果定义了 ViewBag.Alert,并且定义了ViewBag.AlertRedirect。在页面绑定时,head里会出现弹出提示和跳转的js语句,并且,整个body部分将不再绑定,生成的页面弹出提示内容为ViewBag.Alert,点击确定后就会跳转到ViewBag.AlertRedirect的地址。

如果定义了ViewBag.Alert但是没有定义ViewBag.AlertRedirect,页面会正常绑定,并且在页面的最后生成alert语句。页面效果是在页面加载的最后一步弹出提示,这个时候 页面已经全部显示出来了。

如果ViewBag.Alert未定义,那么ViewBag.AlertRedirect不管有没有定义都不会产生影响,结果都是body正常绑定,头和尾都不会有alert出现。

这样,如果需要弹出消息,可以放心大胆的按照写普通action一样写,最后在return View();之前,只需要稍稍加一句

ViewBag.Alert="修改成功";
就实现了返回的view会弹出提示。

是不是很神奇。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值