返璞归真 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,  stringmasterPath) 
                { 
                        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
 
 



     本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/341960 ,如需转载请自行联系原作者

相关文章
|
8天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
18 0
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
32 0
|
2月前
mvc.net分页查询案例——mvc-paper.css
mvc.net分页查询案例——mvc-paper.css
5 0
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
101 5
|
4月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
45 0
|
9月前
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
118 0
|
10月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
67 0
|
10月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
117 0
|
10月前
|
SQL 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)
[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)
145 0
|
10月前
|
开发框架 缓存 JSON
ASP.NET Core MVC 从入门到精通之Filter
ASP.NET Core MVC 从入门到精通之Filter
122 0

相关实验场景

更多