原文:返璞归真 asp.net mvc (4) - View/ViewEngine

[索引页]

[源码下载]

返璞归真 asp.net mvc (4) - View/ViewEngine

作者:webabcd





介绍

asp.net mvc 之 View 和 ViewEngine

  • ViewData 和 TempData 都可以向 View 传递数据,其中 TempData 是保存在 Session 中的,一次请求后此 Session 会被清除
  • HtmlHelper - 在 View 中显示 HTML 元素的一个帮助类
  • IViewEngine - 自定义的视图引擎需要实现此接口
  • VirtualPathProviderViewEngine - 实现了 IViewEngine 接口的抽象类,实现了根据指定的路径格式搜索对应的页面文件的功能(内用缓存机制)
  • IView - 只有一个需要实现的方法,就是呈现 HTML 结果

示例

1、演示 View 的 Demo

ViewDemoController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax; using MVC.Models; namespace MVC.Controllers
{
    public class ViewDemoController : Controller
    {
        ProductSystem ps = new ProductSystem();         public ActionResult Details(int id)
        {
            var product = ps.GetProduct(id);             if (product == null)
            {
                return View("NotFound");
            }
            else
            {
                product.CategoriesReference.Load();                 // 编辑 Product 的时候需要在一个 DropDownList 中选择其所对应的 Category, 所以这里要构造一个 SelectList 类型的 ViewData
                if (product.Categories == null)
                    ViewData["CategoryList"] = new SelectList(new CategeorySystem().GetCategory(), "CategoryId", "CategoryName");
                else
                    ViewData["CategoryList"] = new SelectList(new CategeorySystem().GetCategory(), "CategoryId", "CategoryName", product.Categories.CategoryID);                 // ViewData 和 TempData 都可以向 View 传递数据,其中 TempData 是保存在 Session 中的,一次请求后此 Session 会被清除
                // 在 View 中使用的时候,ViewData[key] 或 TempData[key] 即可
                TempData["Temp"] = "TempData";                 return View("Details", product);
            }
        }         [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Update(int id, FormCollection formValues)
        {
            var product = ps.GetProduct(id);             // 可以通过 UpdateModel, 让系统自动为属性赋值(通过反射的方式,取得对象的属性名称,然后和 Request 的 key 做匹配,匹配成功的则赋值)
            UpdateModel<Products>(product);             // 通过以下的方式让 UpdateModel 只更新指定属性
            // string[] allowedProperties = new[] { "ProductName", "UnitPrice" };
            // UpdateModel(product, allowedProperties);             var category = new CategeorySystem().GetCategory(int.Parse(Request.Form["Category"]));
            product.CategoriesReference.EntityKey = ps.CreateEntityKey("Categories", category);             if (!product.IsValid)
            {
                foreach (var validation in product.GetValidation())
                {
                    // 设置验证信息
                    ModelState.AddModelError(validation.PropertyName, validation.ErrorMessage);
                }
            }
            else
            {
                ps.Save();
            }             ViewData["CategoryList"] = new SelectList(new CategeorySystem().GetCategory(), "CategoryId", "CategoryName", category.CategoryID);             return View("Details", product);
        }
    }
}

Details.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVC.Models.Products>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Details
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <style type="text/css">
        .bold
        {}{
            font-weight: bold;
        }
    </style>
    <h2>
        Details</h2>
    <%= Html.ValidationSummary("输入信息有误") %>
    <% Html.BeginForm("Update", "ViewDemo", new { id = Model.ProductID }, FormMethod.Post); %>
    <p>
        <strong>ProductID:</strong>
        <%= Html.Encode(Model.ProductID) %>
    </p>
    <p>
        <label for="ProductName">
            ProductName:</label>
        <%= Html.TextBox("ProductName", Model.ProductName, new { style = "color: blue;", @class = "bold" })%>
        <%= Html.ValidationMessage("ProductName", "*") %>
    </p>
    <p>
        <label for="Category">
            Category:</label>
        <%-- Html.ListBox() 和 Html.DropDownList() 需要 IEnumerable<SelectListItem> 类型的数据做数据源 --%>
        <%= Html.DropDownList("Category", ViewData["CategoryList"] as SelectList)%>
    </p>
    <p>
        <strong>UnitPrice:</strong>
        <%= Html.Encode(string.Format("{0:F2}", Model.UnitPrice))%>
    </p>
    <p>
        <input type="submit" value="Save" />
    </p>
    <p>
        <%= TempData["Temp"]%>
    </p>
    <% Html.EndForm(); %>
    <p>
        <%=Html.RouteLink("返回首页", new { Controller = "Home" })%>
    </p>     
<%-- 需要使用 Web Form 方式的话,则在后置代码中继承 System.Web.Mvc.ViewPage 或 System.Web.Mvc.ViewPage<T> 即可-- %>
    
    
<%-- 
HtmlHelper 简要说明: 可以用如下的方式生成 form
using (Html.BeginForm()) { }
using (Html.BeginRouteForm()) { }
Html.BeginForm(); Html.EndForm(); 可以使用 Html.ListBox(), Html.RadioButton() 之类的来生成 html 元素 Html.ValidationMessage() - 指定的 ModelName 输入信息不合法时所输出的验证信息
Html.ValidationSummary() - 汇总所有验证信息
验证信息可以在 Action 中用 ModelState.AddModelError() 的方式来添加
验证信息的样式通过样式表修改 .field-validation-error{} .input-validation-error {} .validation-summary-errors {} Html.Encode(); Html.AttributeEncode(); 用于对输出的内容做编码 Html.RenderPartial() - 引入一个 Partial View Html.ActionLink() - 根据 Action 找目标
Html.RouteLink() - 根据路由找目标 Html.ViewContext - View 的上下文信息。包括 Controller, TempData, ViewData, 路由信息, HttpContext 等信息
--%>
</asp:Content>

2、创建一个自定义的 ViewEngine 的 Demo

MyView.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; using System.Web.Mvc;
using System.IO;
using System.Text.RegularExpressions; namespace MVC
{
    /**//// <summary>
    /// 自定义的视图
    /// 视图需要继承 IView 接口
    /// </summary>
    public class MyView : IView
    {
        // 视图文件的物理路径
        private string _viewPhysicalPath;         public MyView(string viewPhysicalPath)
        {
            _viewPhysicalPath = viewPhysicalPath;
        }         /**//// <summary>
        /// 实现 IView 接口的 Render() 方法
        /// </summary>
        public void Render(ViewContext viewContext, TextWriter writer)
        {
            // 获取视图文件的原始内容  
            string rawContents = File.ReadAllText(_viewPhysicalPath);             // 根据自定义的规则解析原始内容  
            string parsedContents = Parse(rawContents, viewContext.ViewData);             // 呈现出解析后的内容
            writer.Write(parsedContents);
        }         public string Parse(string contents, ViewDataDictionary viewData)
        {
            // 对 {##} 之间的内容作解析
            return Regex.Replace
            (
                contents, 
                @"\{#(.+)#\}",                  // 委托类型 public delegate string MatchEvaluator(Match match)
                p => GetMatch(p, viewData)
            );
        }         protected virtual string GetMatch(Match m, ViewDataDictionary viewData)
        {
            if (m.Success)
            {
                // 获取匹配后的结果,即 ViewData 中的 key 值,并根据这个 key 值返回 ViewData 中对应的 value
                string key = m.Result("$1");
                if (viewData.ContainsKey(key))
                {
                    return viewData[key].ToString();
                }
            }             return string.Empty;
        }
    }
}

MyViewEngine.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; using System.Web.Mvc; namespace MVC
{
    // MvcContrib 中提供了很多 ViewEngine, 还提供了以 asp.net mvc 框架为基础的一些额外的功能
    // 地址:http://www.codeplex.com/MVCContrib     /**//// <summary>
    /// 自定义的视图引擎
    /// 视图引擎需要继承 IViewEngine 接口
    /// VirtualPathProviderViewEngine 继承了 IViewEngine 接口,实现了根据指定的路径格式搜索对应的页面文件的功能(内用缓存机制)
    /// </summary>
    public class MyViewEngine : VirtualPathProviderViewEngine
    {
        public MyViewEngine()
        {
            // 自定义 View 路径格式
            base.ViewLocationFormats = new string[] 
            { 
                "~/Views/{1}/{0}.my", "~/Views/Shared/{0}.my" 
            };
        }         protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
        {
            return this.CreateView(controllerContext, partialPath, string.Empty);
        }         /**//// <summary>
        /// 根据指定路径返回一个实现了 IView 接口的对象
        /// </summary>
        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
        {
            var physicalPath = controllerContext.HttpContext.Server.MapPath(viewPath);             return new MyView(physicalPath);
        }
    }
}

Global.asax.cs

protected void Application_Start()
{
    // 增加新的视图引擎 ViewEngine
    ViewEngines.Engines.Add(new MyViewEngine());  
}

CustomViewEngineController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax; namespace MVC.Controllers
{
    /**//// <summary>
    /// 用于演示自定义的 ViewEngine 的 Controller
    /// </summary>
    public class CustomViewEngineController : Controller
    {
        public ActionResult Index()
        {
            ViewData["name"] = "webabcd";
            ViewData["age"] = "70";             // 如果视图文件中有 {##} 形式的字符串,则 MyViewEngine 会对其做相应的解析
            // 如 {#name#} 会被解析为 webabcd             return View();
        }  
    }
}

Index.my(智能感知在“工具 - 选项 - 文本编辑器 - 文件扩展名”中编辑)

<html>
<head>
    <title>创建自定义的 ViewEngine 的 Demo</title>
</head>
<body>
    <div>name: {#name#}</div>
    <div>age: {#age#}</div>
</body>
</html>

运行结果:

name: webabcd

age: 70





OK

[源码下载]

返璞归真 asp.net mvc (4) - View/ViewEngine的更多相关文章

  1. 返璞归真 asp.net mvc (9) - asp.net mvc 3.0 新特性之 View(Razor)

    原文:返璞归真 asp.net mvc (9) - asp.net mvc 3.0 新特性之 View(Razor) [索引页][源码下载] 返璞归真 asp.net mvc (9) - asp.ne ...

  2. 返璞归真 asp.net mvc (7) - asp.net mvc 3.0 新特性之 Controller

    原文:返璞归真 asp.net mvc (7) - asp.net mvc 3.0 新特性之 Controller [索引页][源码下载] 返璞归真 asp.net mvc (7) - asp.net ...

  3. 返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model

    原文:返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model [索引页][源码下载] 返璞归真 asp.net mvc (8) - asp.net mvc ...

  4. 返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test

    原文:返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test [索引页] [源码下载] 返璞归真 ...

  5. 返璞归真 asp.net mvc (3) - Controller/Action

    原文:返璞归真 asp.net mvc (3) - Controller/Action [索引页] [源码下载] 返璞归真 asp.net mvc (3) - Controller/Action 作者 ...

  6. 返璞归真 asp.net mvc (1) - 添加、查询、更新和删除的 Demo

    原文:返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo [索引页] [源码下载] 返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo 作者 ...

  7. 返璞归真 asp.net mvc (12) - asp.net mvc 4.0 新特性之移动特性

    原文:返璞归真 asp.net mvc (12) - asp.net mvc 4.0 新特性之移动特性 [索引页][源码下载] 返璞归真 asp.net mvc (12) - asp.net mvc ...

  8. 返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性

    原文:返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性 [索引页][源码下载] 返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性 ...

  9. 预热ASP.NET MVC 的View

    ASP.NET MVC 的View 预设是Load on Demand(按需加载),也就是说View 第一次要Render 的时候才会去载入跟编译,这个就会造成一个现象,即使Web 应用程式已经完成启 ...

随机推荐

  1. linux下安装QT过程

    说QT是linux下主要的图形开发工具一点都不过分,虽然诺基亚公司放弃Meego.遣散了Qt开发团队,但是它的各种商业.企业版本还是的到了很好的保护,linux下的开发工具集里还是经常看到它的身影,毕 ...

  2. UML简单介绍

    UML的全称是统一建模语言:Unified Modeling Language. 是用来为面向对象开发系统的产品进行说明可视化和编制文档的方法. 它是一种标准的图形化建模语言,是面向对象分析与设计的一 ...

  3. iphone开发中数据持久化之——模型对象归档(二)

    在Cocoa世界中,术语“归档”是指另一种形式的序列化,它可以实现对任何对象的序列化.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文件,然后再从中读取它们.只要在类中实现的每个属性都是标量(如 ...

  4. CF 518D(概率dp)

    传送门:Ilya and Escalator 题意:有n个人排队进车厢,每秒只能进一个人,而且第1个人进了后面的人才能进,第一个人每秒进入车厢的概率为p,不进的概率为1-p,求t秒后进入车厢总人数的数 ...

  5. 关于Platinum库的MediaRender具体C++代码实现探讨

    接上篇博文 NDK下 将Platinum SDK 编译成so库 (android - upnp) 讲述了如何利用该代码库编译给android程序调用的so库,其中也提到了,在使用sample-upnp ...

  6. logstash+ElasticSearch+Kibana VS Splunk

    logstash+ElasticSearch+Kibana VS Splunk 最近帮磊哥移植一套开源的日志管理软件,替代Splunk. Splunk是一个功能强大的日志管理工具,它不仅可以用多种方式 ...

  7. SWT的CheckBoxTreeView

    其实CheckBoxTreeView和TreeView基本上是一样的,他们共同的方法有: TreeViewer 类封装了tree控件.树查看器按照父子关系来显示分等级的对象列表.此查看器需要设置标签供 ...

  8. SWT实践过程中遇到的问题

    1.import org.eclipse.swt.widgets.Text; 诸如右所示的找不到这个包. 解决办法:project->properties->build path-> ...

  9. A Game of Thrones(2) - Catelyn

    Catelyn had never liked this godswood(神木林). She had been born a Tully, at Riverrun far to the south, ...

  10. cocos2D-x 3.5 引擎解析之--引用计数(Ref),自己主动释放池(PoolManager),自己主动释放池管理器( AutoreleasePool)

    #include <CCRef.h> Ref is used for reference count manangement. If a classinherits from Ref. C ...