返璞归真 asp.net mvc (4) - View/ViewEngine-阿里云开发者社区

开发者社区> 杰克.陈> 正文

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

简介: 原文:返璞归真 asp.net mvc (4) - View/ViewEngine[索引页][源码下载] 返璞归真 asp.net mvc (4) - View/ViewEngine 作者:webabcd 介绍 asp.
+关注继续查看
原文:返璞归真 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
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
{
    
public class ViewDemoController : Controller
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
{
        ProductSystem ps 
= new ProductSystem();

        
public ActionResult Details(int id)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            var product 
= ps.GetProduct(id);

            
if (product == null)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
{
                
return View("NotFound");
            }

            
else
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
{
                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)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            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)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
{
                
foreach (var validation in product.GetValidation())
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                
{
                    
// 设置验证信息
                    ModelState.AddModelError(validation.PropertyName, validation.ErrorMessage);
                }

            }

            
else
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
{
                ps.Save();
            }


            ViewData[
"CategoryList"= new SelectList(new CategeorySystem().GetCategory(), "CategoryId""CategoryName", category.CategoryID);

            
return View("Details", product);
        }

    }

}

Details.aspx
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif<%@ 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">
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif    
<style type="text/css">
        .bold
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{}{
            font-weight
: bold;
        
}

    
</style>
    
<h2>
        Details
</h2>
    
<%= Html.ValidationSummary("输入信息有误"%>
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif    
<% 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>
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif        
<%-- 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>
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif    
<% Html.EndForm(); %>
    
<p>
        
<%=Html.RouteLink("返回首页"new { Controller = "Home" })%>
    
</p>

    
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
<%-- 需要使用 Web Form 方式的话,则在后置代码中继承 System.Web.Mvc.ViewPage 或 System.Web.Mvc.ViewPage<T> 即可-- %>
    
    
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
<%-- 
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
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
{
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
/**//// <summary>
    
/// 自定义的视图
    
/// 视图需要继承 IView 接口
    
/// </summary>

    public class MyView : IView
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
{
        
// 视图文件的物理路径
        private string _viewPhysicalPath;

        
public MyView(string viewPhysicalPath)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            _viewPhysicalPath 
= viewPhysicalPath;
        }


img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
/**//// <summary>
        
/// 实现 IView 接口的 Render() 方法
        
/// </summary>

        public void Render(ViewContext viewContext, TextWriter writer)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            
// 获取视图文件的原始内容  
            string rawContents = File.ReadAllText(_viewPhysicalPath);

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

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



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

                
// 委托类型 public delegate string MatchEvaluator(Match match)
                p => GetMatch(p, viewData)
            );
        }


        
protected virtual string GetMatch(Match m, ViewDataDictionary viewData)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            
if (m.Success)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
{
                
// 获取匹配后的结果,即 ViewData 中的 key 值,并根据这个 key 值返回 ViewData 中对应的 value
                string key = m.Result("$1");
                
if (viewData.ContainsKey(key))
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                
{
                    
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
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
{
    
// MvcContrib 中提供了很多 ViewEngine, 还提供了以 asp.net mvc 框架为基础的一些额外的功能
    
// 地址:http://www.codeplex.com/MVCContrib

img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
/**//// <summary>
    
/// 自定义的视图引擎
    
/// 视图引擎需要继承 IViewEngine 接口
    
/// VirtualPathProviderViewEngine 继承了 IViewEngine 接口,实现了根据指定的路径格式搜索对应的页面文件的功能(内用缓存机制)
    
/// </summary>

    public class MyViewEngine : VirtualPathProviderViewEngine
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
{
        
public MyViewEngine()
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            
// 自定义 View 路径格式
            base.ViewLocationFormats = new string[] 
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            

                
"~/Views/{1}/{0}.my""~/Views/Shared/{0}.my" 
            }
;
        }


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


img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
/**//// <summary>
        
/// 根据指定路径返回一个实现了 IView 接口的对象
        
/// </summary>

        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            var physicalPath 
= controllerContext.HttpContext.Server.MapPath(viewPath);

            
return new MyView(physicalPath);
        }

    }

}


Global.asax.cs
protected void Application_Start()
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
{
    
// 增加新的视图引擎 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
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
{
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
/**//// <summary>
    
/// 用于演示自定义的 ViewEngine 的 Controller
    
/// </summary>

    public class CustomViewEngineController : Controller
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
{
        
public ActionResult Index()
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
{
            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
[源码下载]

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
6353 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
2162 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
3955 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
4962 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
5669 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
10711 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
2000 0
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
3803 0
+关注
杰克.陈
一个安静的程序猿~
9798
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载