返璞归真 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的更多相关文章
- 返璞归真 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 ...
- 返璞归真 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 ...
- 返璞归真 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 ...
- 返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test
原文:返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test [索引页] [源码下载] 返璞归真 ...
- 返璞归真 asp.net mvc (3) - Controller/Action
原文:返璞归真 asp.net mvc (3) - Controller/Action [索引页] [源码下载] 返璞归真 asp.net mvc (3) - Controller/Action 作者 ...
- 返璞归真 asp.net mvc (1) - 添加、查询、更新和删除的 Demo
原文:返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo [索引页] [源码下载] 返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo 作者 ...
- 返璞归真 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 ...
- 返璞归真 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 新特性 ...
- 预热ASP.NET MVC 的View
ASP.NET MVC 的View 预设是Load on Demand(按需加载),也就是说View 第一次要Render 的时候才会去载入跟编译,这个就会造成一个现象,即使Web 应用程式已经完成启 ...
随机推荐
- 虚拟机VM10装Mac OS X 10.9.3
近期WWDC放出终极大招--新的编程语言Swift(雨燕),导致一大波程序猿的围观和跃跃欲试.当然了,工欲善其事,必先利其器,所以对于那些没有Mac又想要尝鲜的小伙伴肯定非常为难.可是,请放心,本文教 ...
- 《TCP/IP作品详细解释2:实现》笔记--Radix树路由表
通过IP完整的路由是路由机制,它通过搜索路由表来确定从哪个分组被发送的接口执行此,它是不一样的路由策略,路由策略 它是一组规则,这些规则可以被用来确定哪些路由编程到路由表,Net/3内核实现的路由机制 ...
- 三框架:使用数据源dbcp注意
使用spring整合hibernate时间,需要使用该数据源,数据源使用apache的dbcp,使用dbcp当需要依靠pool的jar包.选择dbcp和pool当你需要注意. DBCP 2 compi ...
- oschina jQuery 插件
jQuery 插件 jQuery自动完成插件(25) jQuery分页插件(20) jQuery 文件上传(21) jQuery 地图插件(14) jQuery对话框(109) jQuery图片展示/ ...
- 命令模式在MVC框架中的应用
事实上在项目开发中,我们使用了大量的设计模式,不过这些设计模式都封装在框架中了,假设你想要不只局限于简单的使用,就应该深入了解框架的设计思路. 在MVC框架中,模式之中的一个就是命令模式,先来看看模式 ...
- android
在特殊应用的特殊功能,以帮助通信系统的问题
在实际工程中的应用,进入一个特殊的应用后,系统的某个功能不能起作用. 当然,这个通信有非常多办法能够做到.笔者能够想到的至少有例如以下几种 1.利用property熟悉来实现,这种话须要添加一个特殊的 ...
- hdu3485(递推)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3485 分析: a[i]表示长度为i,第i位为0的,符合情况的个数. b[i]表示长度为i,第i位为1的 ...
- hdu3602(变形背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3602 题意是:N个国家,M个飞船,每个国家有人数num,如果上飞船就给联合国value钱,选出某些国家 ...
- Ubuntu12.04下使用virtualbox4.3.12 amd64安装XP系统教程
首先第一步打开已安装好的Virtualbox4.3.12,效果图例如以下: 第二步:点击新建进入新建虚拟电脑界面,填写名称,选择类型和版本号(我这里使用的三XP 64bit): 第三步:选择内存大小, ...
- H3C TE BGP拓扑排错报告
BGP排错报告 故障一:PPP链路 ...