您的位置:首页 > 编程语言 > ASP

asp.net mvc - View/ViewEngine

2012-09-12 01:39 369 查看
介绍

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: