返璞归真 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();

ActionResult Details() 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)]
ActionResult Update() 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;

MyView() MyView( string viewPhysicalPath)
                {
                        _viewPhysicalPath = viewPhysicalPath;
                }

                /**//// <summary>
                /// 实现 IView 接口的 Render() 方法
                /// </summary>
void Render() void Render(ViewContext viewContext, TextWriter writer)
                {
                        // 获取视图文件的原始内容    
                         string rawContents = File.ReadAllText(_viewPhysicalPath);

                        // 根据自定义的规则解析原始内容    
                         string parsedContents = Parse(rawContents, viewContext.ViewData);

                        // 呈现出解析后的内容
                        writer.Write(parsedContents);
                }


string Parse() string Parse( string contents, ViewDataDictionary viewData)
                {
                        // 对 {##} 之间的内容作解析
                        return Regex.Replace
                        (
                                contents,    
                                 @"\{#(.+)#\}",    

delegate string MatchEvaluator() delegate string MatchEvaluator(Match match)
                                p => GetMatch(p, viewData)
                        );
                }

virtual string GetMatch() 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
        {
MyViewEngine() MyViewEngine()
                {
                        // 自定义 View 路径格式
                        base.ViewLocationFormats = new string[]    
                        {    
                                 "~/Views/{1}/{0}.my", "~/Views/Shared/{0}.my"    
                        };
                }

override IView CreatePartialView() override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
                {
                        return this.CreateView(controllerContext, partialPath, string. Empty);
                }

                /**//// <summary>
                /// 根据指定路径返回一个实现了 IView 接口的对象
                /// </summary>
override IView CreateView() override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
                {
                        var physicalPath = controllerContext.HttpContext.Server.MapPath(viewPath);

                        return new MyView(physicalPath);
                }
        }
}
 
Global.asax.cs
void Application_Start() 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
        {
ActionResult Index() 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
[源码下载]

你可能感兴趣的:(mvc,asp,休闲,ViewEngine,返璞归真)