ASP.NET MVC之持久化TempData及扩展方法(十三)

前言

之前在开始该系列之前我们就讲述了在MVC中从控制器到视图传递数据的四种方式,但是还是存在一点问题,本节就这个问题进行讲述同时进行一些练习来看看MVC中的扩展方法。

话题

废话不必多说,我们直接进入主题,关于TempData的基本用法就不需要再进行讲述,其生命周期确实很短,但是对于其用法也就存在一定可能性,当我们需要从一个页面到另外一个页面进行数据传递时,此时就需要用到该对象。该对象数据进行第一次加载后则其生命周期结束,但是我们如何做到持久化该对象中的数据呢?请往下看。

持久化TempData

我们首先来看一个例子。

    public class TempDataController : Controller
    {
        public ActionResult Index()
        {
            TempData["cnblogs"] = "xpy0928";
            return View();
        }

        public ActionResult GetTemData()
        {
            var blogName = TempData["cnblogs"].ToString();
            return View();
        }

    }

当第一次访问 GetTemData 时,会正确显示 blogName = "xpy0928" ,当刷新该页面时则出现【未将该对象实例化到对象的实例】。

那么问题来了,我们如何持久化该TempData中的数据即刷新该页面时使该对象的数据不为null。 

原来在MVC中是利用 Keep 方法来实现该对象中的数据持久化。我们来看看。

    public class TempDataController : Controller
    {
        public ActionResult Index()
        {
            TempData["cnblogs"] = "xpy0928";
            TempData.Keep();
            return View();
        }

        public ActionResult GetTemData()
        {
            var blogName = TempData["cnblogs"].ToString();
            TempData.Keep("cnblogs");
            return View();
        }

    }

此时当我们即使多次刷新页面GetTemData视图时则该对象的键cnblogs对应的值都一直存在。 

RedirectToRouteResult和RedirectResult

下面我们再来看一例。

        public ActionResult Index()
        {
            TempData["cnblogs"] = "xpy0928";
            return new RedirectToRouteResult(new
                        RouteValueDictionary(new { controller = "TempData", action = "GetTemData" }));
        }

        public ActionResult GetTemData()
        {
            var blogName = TempData["cnblogs"].ToString();
            TempData.Keep("cnblogs");
            return View();
        }

在上述中我们在Index方法中未直接调用 TempData.Keep() ,此时直接重定向到GetTemData方法,当再次刷新时,该对象中的值仍存在。也就是说RedirectToRouteResult默认是一直调用TempData.Keep方法使其对象的值一直存在(对于RedirectResult同理)。

void Keep()

在当前Action方法中调用Keep方法则保证在当前请求中TempData对象中所存储的键都不会被移除。

void Keep(string key)

在当前Action方法中调用Keep方法保证在当前请求中TempData对象中的某一特定项不会被移除。

总结

(1)当利用TempData对象存储值而未调用TempData.Keep方法时,此时只要该对象被已读,然后该对象中的所有项将被标记为删除状态。

(2)若调用TempData.Keep(string key)方法,此时不会进行标记。

(3)RedirectToRouteResult和RedirectResult总是会调用TempData.Keep()方法,保证该对象中的所有项不会被移除。

 MVC扩展方法

这一小节的写出是通过对出现的问题进行解决而想到,下面我将一步一步来进行演示。

在实际应用中我们会遇到利用Tab来切换得到不同的视图。下面我们用Bootstrap来实现,如下:

<ul id="nav" class="nav nav-tabs">
    <li class="active"><a href="/Professional/Rota">值班表</a></li>
    <li><a href="/Professional/OverValue">超有限值</a></li>
    <li><a href="/Professional/NoOverValue">无超有限值</a></li>
    <li><a href="/Professional/DifferenceWeight">差值加权</a></li>
    <li><a href="/Professional/Difference">差值</a></li>
    <li><a href="/Professional/ClassTotal">班总和</a></li>
    <li><a href="/Professional/ClassAverage">班平均</a></li>
</ul>

将得到如下效果:

那么问题来了,有七个tab,那么是不是应该在每个页面都得定义如上的一个Ul,而唯一不同的只是切换不同li,则该li的样式为active呢?

刚开始我也是这样做的,后来越想越不对劲,每个页面都这样定义一下,而只是激活点击的li为active。此时想到的是将上述Ul定义为一个母版页,而想办法对其点击的class为active即可,于是出现了如下:

@{
    ViewBag.Title = "_TabLayout";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<ul id="nav" class="nav nav-tabs">
    <li><a href="/Professional/Rota">值班表</a></li>
    <li><a href="/Professional/OverValue">超有限值</a></li>
    <li><a href="/Professional/NoOverValue">无超有限值</a></li>
    <li><a href="/Professional/DifferenceWeight">差值加权</a></li>
    <li><a href="/Professional/Difference">差值</a></li>
    <li><a href="/Professional/ClassTotal">班总和</a></li>
    <li><a href="/Professional/ClassAverage">班平均</a></li>
</ul>
@RenderBody()
<script type="text/javascript">
    $(function () {
        $("#nav li").eq(0).addClass("active");
    });
</script>

其他tab都用上述js来添加样式active。(当然可直接在模板中控制点击的li再添加样式比上述更简洁,就不再演示)。

下面我们不用Bootstrap,自定义并用MVC扩展方法来实现切换tab(利用js不再叙述)。

(1)母版页变成如下 

@{
    ViewBag.Title = "_TabLayout";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using PowerAssessmentSystem.MvcExtend;

<link href="~/Content/tab.css" rel="stylesheet" type="text/css" />
<div class="menu-tabs">
    <ul>
        <li>@Html.ActiveLink("值班表", "Rota", "Professional")</li>
        <li>@Html.ActiveLink("超有限值", "OverValue", "Professional")</li>
        <li>@Html.ActiveLink("无超有限值", "NoOverValue", "Professional")</li>
        <li>@Html.ActiveLink("差值加权", "DifferenceWeight", "Professional")</li>
        <li>@Html.ActiveLink("差值", "Difference", "Professional")</li>
        <li>@Html.ActiveLink("班总和", "ClassTotal", "Professional")</li>
        <li>@Html.ActiveLink("班平均", "ClassAverage", "Professional")</li>

    </ul>
</div>

@RenderBody()

(2)@Html.ActiveLink扩展方法实现点击Active样式

    public static class ActiveHelper
    {
        public static MvcHtmlString ActiveLink(this HtmlHelper helper, string linkText, string actionName, string controllerName)
        {
            var routevalueDic = new RouteValueDictionary();
            var acName = helper.ViewContext.RouteData.Values["action"].ToString();
            var ctlName = helper.ViewContext.RouteData.Values["controller"].ToString();
            if (acName.Equals(actionName, StringComparison.OrdinalIgnoreCase))
            {
                if (ctlName.Equals(controllerName, StringComparison.OrdinalIgnoreCase))
                {
                    routevalueDic.Add("class", "active");
                }
            }

            return helper.ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), routevalueDic);
        }
    }

(3)相关样式

a:hover {
    text-decoration: none;
    color: #f01400;
}

.menu-tabs {
    border-bottom: 1px solid #D1D6DA;
}

    .menu-tabs ul {
        height: 45px;
        line-height: 45px;
    }

    .menu-tabs li {
        list-style-type: none;
        float: left;
        height: 100%;
        text-align: center;
        width: 13.63636364%;
    }

    .menu-tabs a {
        display: block;
        font-size: 16px;
    }

.active {
    color: #f01400;
    font-weight: bold;
    border-bottom: 2px solid #f01400;
    height: 55px;
}

我们再来看看最终的演示效果:

总结

本节我们讲解了TempData的持久化以及MVC中扩展方法,本节结束。

 

时间: 2025-01-30 00:40:18

ASP.NET MVC之持久化TempData及扩展方法(十三)的相关文章

ASP.NET MVC 2的客户端验证扩展

ASP.NET MVC 2内置支持在服务器上验证数据注释验证属性,本文介绍如何使用System.ComponentModel.DataAnnotations中的基础类构建自定义验证属性,关于ASP.NET MVC 2中数据注释是如何工作的,请参考Brad的博客(http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html). 我会介绍如何连接到ASP.NET MVC 2的客户端验证扩展,以便你可以在客

ASP.NET MVC 5 - 查询Details和Delete方法

原文:ASP.NET MVC 5 - 查询Details和Delete方法 在这部分教程中,接下来我们将讨论自动生成的Details和Delete方法. 查询Details和Delete方法 打开Movie控制器并查看Details方法. public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Movie movie

Asp.net Mvc Framework 十二 Castle扩展

由于Monorail是.net下MVC的先驱所以 Asp.net MVC理所当然要支持老的Castle用户 在Asp.net MVC扩展包中就提供了对Castle的支持与兼容 虽然这个扩展还有很多BUG与不足,但已从其中窥见Asp.net的扩展性之一斑 扩展的下载地址:http://www.codeplex.com/MVCContrib 其中的\Samples\MvcContrib.Samples.NVelocityViewFactory\就是一个Castle使用NVelocity为脚本的示例

Asp.net MVC Render及Redirect的扩展

这个是Redirect的扩展 namespace System.Web.Mvc {     using System;     /// <summary>     /// 对Controller的Redirect操作的扩展     /// blog:http://chsword.cnblogs.com/     /// </summary>    public static class RedirectExtension     {         /// <summary&

《Pro ASP.NET MVC 3 Framework》学习笔记之十三【示例项目SportsStore】

接着我们添加一个分页功能.修改ProductController,如下所示: public class ProductController : Controller {public int PageSize = 4;//后面会更改 private IProductsRepository repository;public ProductController(IProductsRepository productRepository) { repository = productRepositor

ASP.NET MVC Performance Tips(1):RenderPartial性能优化

背景 在ASP.NET MVC中,HtmlHelper的扩展方法RenderPartial为我们使用UserControl带来了 极大的方便,当我们指定一个UserControl时,RenderPartial会在当前View文件夹下查找相应的 UserControl,如果没有找到则会到Shared文件夹下查找.然后在使用RenderPartial方法有一些性能方面 的考虑,值得我们去关注. 设想有这样一个场景,一篇文章有很多个评论,在页面中我们需要呈 现出一个评论列表,自然我们会定义一个评论的U

ASP.NET MVC:Razor 引入命名空间

原文:ASP.NET MVC:Razor 引入命名空间 页面中引用 c# @using MvcApplication83.Models @using MvcApplication83.Common 行尾不需要加分号,加上也无妨(不过得全加上). VB.Net @Imports MvcApplication83.Models @Imports MvcApplication83.Common 配置文件中引用 必须在 Views 文件夹中的 Web.config 文件中添加引用.见下图: 打开该文件,

Asp.Net Mvc: 浅析TempData机制

环境: Windows 2008, VS 2008 SP1, Asp.Net Mvc 1.0 一. Asp.Net Mvc中的TempData 在Asp.Net Mvc框架的ControllerBase中存在一个叫做TempData的Property,它的类型为 TempDataDictionary,顾名思义是一个字典类.TempData在Asp.Net Mvc中的作用是:可用于在Action执 行过程之间传值.简单的说,你可以在执行某个Action的时候,将数据存放在TempData中,那么在

ASP.NET MVC的View是如何被呈现出来的?[设计篇]

在前面的四篇文章中,我们介绍了各种ActionResult以及相关的请求响应机制,但是与"View的呈现"相关的ActionResult是ViewResult.通过ViewResult的执行实现的对View的呈现比上面我们介绍的各种ActionResult要复杂得多,ASP.NET MVC内部设计了一个扩展的View引擎实现了最终的View呈现工作.[本文已经同步到<How ASP.NET MVC Works?>中] 一.View引擎中的View ASP.NET MVC为我