[asp.net mvc 奇淫巧技] 02 - 巧用Razor引擎在Action内生成Html代码

  在web开发中经常会遇到在内部代码中获取Html,这些Html是需要和数据进行一起渲染。并不是直接把Html代码返回给客户端。这样的做法有很多应用场景,例如分页、Ajax一次性获取几段Html片段、生成邮件发送模板、生成Html静态页面等等。比较简单的或者容易想到的做法就是直接拼接Html,当然这肯定不是最合适的做法。

应用场景

1、在分页中,有一种做法是用ajax获取table的html代码和一些分页信息的Json

var json = {
    "table": "<table><tr/><td>1</td></tr></table>",
    "pageSize": 10,
    "currentIndex": 1,
    "count": 100
}

2、Ajax一次性获取几段Html片段

var json = {
    "leftHtml": "<div><h1>HHHHHHHHHH</h1></div>",
    "rightHtml": "<table><tr/><td>1</td></tr></table>"
}

3、生成邮件发送模板、生成Html静态页面

  我们经常会生成一些邮件模板,比如推广一些产品的html代码。

  生成Html静态页面就更加常用了。

应用场景分析

  我们这些应用都是在内部代码中生成html,然后在对html代码进行处理,比如拼接成json,或者发送邮件,在或者生成静态html页面。

  生成Html在asp.net中莫过于Razor引擎,总之就是很好用,语法也很强大,如果我们把需要生成的html用Razor引擎生成岂不是很好,如果熟悉asp.net mvc 管道的话就可以很简单的解决这个问题。

1、查找View(cshtml)

可以用ViewEngines.Engines.FindView查找View。

public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName);

FindView需要ControllerContext、viewName和masterName,其中masterName是母版视图的名称目前可以忽略。

viewName就是我们需要查找的View,查找View的方式和在Action中return View(string viewName)的方式一致,也就是说有两种方式,一个是全路径,如:"~/Views/Home/Html1.cshtml",必须带后缀名cshtml。还有一种方式是直接写"Html1",也就是相对路径, 如果cshtml文件的位置不在Controller所对应的文件夹中,则可以写"../Folder/Html1"。此方式同样适应于普通执行Controller中Action直接return View(string viewName)。

ControllerContext是封装有关与指定的 System.Web.Routing.RouteBase 和 System.Web.Mvc.ControllerBase 请求的信息

public ControllerContext(RequestContext requestContext, ControllerBase controller);

在构造函数中需要RequestContext和ControllerBase,ControllerBase就是this,RequstContext可以在Action中和容易的获取。

最终查找View的代码

ControllerContext context = new ControllerContext(Request.RequestContext, this);
ViewEngineResult result = ViewEngines.Engines.FindView(context, "Html1", "");

2、Render View

最终我们需要执行View的Render方法,来获取生成的html

void Render(ViewContext viewContext, TextWriter writer);

Render 代码

using (var sw = new StringWriter())
{
    var viewContext = new ViewContext(context, result.View, context.Controller.ViewData, context.Controller.TempData, sw);
    result.View.Render(viewContext, sw);

    string html = sw.ToString();
}

代码中html就是我们需要获取的html。

传递数据至View

如何传递数据至View,这个和普通的Action执行一致,也就是说我们熟悉的ViewBag,ViewData,TempData以及Model都可以用。

1、设置数据

在调用View.Render前设置数据即可。

context.Controller.ViewBag.Name = "Emrys";
context.Controller.ViewData["Age"] = 10;
context.Controller.TempData["City"] = "上海";
context.Controller.ViewData.Model = new UserInfo { Name = "Emrys", Age = 10, City = "上海" };

2、在View(html)获取数据,也就是Html1.cshtml中的Razor代码。

@{
    Layout = null;
}
@model UserInfo 

Name:@ViewBag.Name<br />

Age:@ViewData["Age"]<br />

City:@TempData["City"]<br />

Name:@Model.Name<br />
Age:@Model.Age<br />
City:@Model.City

总结

最终Action中的代码

ControllerContext context = new ControllerContext(Request.RequestContext, this);
ViewEngineResult result = ViewEngines.Engines.FindView(context, "Html1", "");

context.Controller.ViewBag.Name = "Emrys";
context.Controller.ViewData["Age"] = 10;
context.Controller.TempData["City"] = "上海";
context.Controller.ViewData.Model = new UserInfo { Name = "Emrys", Age = 10, City = "上海" };

using (var sw = new StringWriter())
{
    var viewContext = new ViewContext(context, result.View, context.Controller.ViewData, context.Controller.TempData, sw);
    result.View.Render(viewContext, sw);

    string html = sw.ToString();
}

这样我们就可以巧用Razor获取我们需要和数据组合的html代码,以供我们使用。

最后望对各位有所帮助,本文原创,欢迎拍砖和推荐

时间: 2024-10-14 09:53:23

[asp.net mvc 奇淫巧技] 02 - 巧用Razor引擎在Action内生成Html代码的相关文章

[asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?

在QQ群或者一些程序的交流平台,经常会有人问:我怎么传一个数组在Action中接收.我传的数组为什么Action的model中接收不到.或者我在ajax的data中设置了一些数组,为什么后台还是接收不了.还有一些怎么传送一个复杂的对象或者Action怎么接收一个复杂的对象等等这些问题.或者有些人遇到复杂的对象或者数组直接就传送个json字符串,然后在Action中把json字符串转成model对象,当然这也是一种做法,但也许不是最优的做法. 一.需求 按照如图的数据格式,传入到Action,用一

[asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的

一.感慨 很久前看到一篇博客中有句话大致的意思是:“asp.net 程序性能低下的主要原因是开发人员技术参差不齐”,当时看到这句话不以为然,然而时间过的越久接触的.net 开发人员越多就越认同这句话:特别最近发现非常一个成熟的项目中有些问题非常非常影响性能,最终影响的是用户体验,借此给大家分享一下关于asp.net中一个小小的点,但对项目有很大的性能提升:以前觉得自己接触的项目少小,然后接触的项目越多,越大就会越发现,同样的问题依旧存在: 二.先从最简单的asp.net mvc例子说起 1.Co

[asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper

一.需求 我们在开发中经常会遇到一些枚举,而且这些枚举类型可能会在表单中的下拉中,或者单选按钮中会用到等. 这样用是没问题的,但是用过的人都知道一个问题,就是枚举的命名问题,当然有很多人枚举直接中文命名,我是不推荐这种命名规则,因为实在不够友好. 那有没有可以不用中文命名,而且可以显示中文的方法呢.答案是肯定的. 二.特性解决枚举命名问题 那就是用特性解决命名问题,这样的话既可以枚举用英文命名,显示又可以是中文的,岂不两全其美. /// <summary> /// 性别 /// </su

【C#冷知识系列】(一)那些你知道或者不知道的奇淫巧技

引子 正如我在个人介绍中所写,我是一个仍然坚持.NET的头铁高级软件工程师,研究C#,.NET已经六年多,一直坚持认为自己的能力不足以教授别人,所以一直没有想法写博客.工作几年,内容涵盖了.NET框架下的各种软件的开发,WPF,WinForm,WebForm,ASP.NET,MVC5,开发的软件几乎涵盖了.NET家族的各个成员.让我下定决心写一系列C#高级开发文章的原因并不是因为某天早上起床突如其来的兴致勃勃的决定要将自己这些年积累的经验分享给大家,而是是因为公司前端的一句"快脱坑吧,你们做WP

ASP.NET Core 奇淫技巧之伪属性注入

原文:ASP.NET Core 奇淫技巧之伪属性注入 一.前言 开局先唠嗑一下,许久未曾更新博客,一直在调整自己的状态,去年是我的本命年,或许是应验了本命年的多灾多难,过得十分不顺,不论是生活上还是工作上.还好当我度过了所谓的本命年后,许多事情都在慢慢变好,我将会开始恢复更新博客,争取恢复到以前的速度上(因为工作比较忙,所以这个过程可能需要一段时间). 二.关于属性注入 说到属性注入,我们就不得不提一下 DI(Dependency Injection),即依赖注入,用过 ASP.NET Core

[javascript 实践篇]——那些你不知道的“奇淫巧技”

1. 空(null, undefined)验证 刚开始,我是比较蠢的验证(我还真是这样子验证的) if (variable1 !== null || variable1 !== undefined || variable1 !== '') { let variable2 = variable1; } 大哥教会了我这样子验证,你会惊叹一下的 let variable2 = variable1 || ''; 如果你不信,在谷歌浏览器开发者面板的控制台下试试! //值为null的例子 let vari

源码解析中看到的奇淫巧技

源码解析中看到的奇淫巧技 一. 数组重置 let arr = [123,123] arr.length // 2 arr.length = 0 arr // [] 当我们给数组的length 属性设置成 0 .那么数组就会被重置为空. (很神奇有木有 二. 数据类型判断 1. 判断是否为 undefined let isUndef = function(v) { return v === undefined || v === null } 2. 判断是否 不为空 let isDef = func

asp.net mvc 3.0 知识点整理 ----- (2).Controller中几种Action返回类型对比

通过学习,我们可以发现,在Controller中提供了很多不同的Action返回类型.那么具体他们是有什么作用呢?它们的用法和区别是什么呢?通过资料书上的介绍和网上资料的查询,这里就来给大家列举和大致的概括下. (1). ActionResult(base):最基本的Action类型,返回其他类型都可以写ActionResult. (2). ContentResult:返回ContentResult用户定义的内容类型. public ActionResult Content() { return

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装  (5):前台Jquery easyUI实现   (6):EF上下文实例管理   (7):DBSession的封装 前言:通过上篇博客我们完成了对DbSession的代码编写,DbSession就相