不用asp.net MVC,用WebForm照样能够实现MVC
在《避开WebForm天坑,拥抱ASP.Net MVC吧》这篇博客中我讲到了ASP.net WebForm由于一些先天的“诱导犯罪”的缺陷,如今用ASP.net MVC的公司越来越多。可是依据那篇文章末尾的"ASP.net MVC的免费网络公开课"调查表的统计,我们发现有一大半的人还没有使用过ASP.Net MVC。而没用过ASP.net MVC的人中居然有非常多人人是由于感觉ASP.Net 难、没时间学。调查表分析数据例如以下:
初看ASP.net确实难:复杂的路由机制、 ViewData/ViewBag/TempData、过滤器、Razor、Layout、XXXHelper、验证、WebAPI、依赖注入、单元測试……光看这一堆概念头就晕了。“还是拖控件简单”。
事实上学习一个新的框架,仅仅要搞清他的原理就会“豁然开朗”,再看其它的东西就不会感觉恐惧了。
这篇文章我将会带着大家搞明确什么叫MVC模式。而且带着大家用大家熟悉的Asp.Net WebForm实现MVC。
对!
你没听错!
用Asp.Net WebForm实现MVC!
再次感受一下ASP.net WebForm吧。
如果有一个Person对象的集合,我们要在网页中以html渲染。那么要例如以下编写
1
2
3
4
5
|
< table > < asp:Repeater ID="Repeater1" < ItemTemplate >< tr >< td ><%#Eval("Name") td >< td ><%#Eval("Age") td ></ tr ></ ItemTemplate > </ asp:Repeater > </ table > |
C#代码:

if(!IsPostBack)
{
List<Person> list = new List<Person>();
list.Add(new Person { Name = "rupeng", Age = 8 });
list.Add(new Person { Name = "qq", Age = 18 });
Repeater1.DataSource = list;
Repeater1.DataBind();
}

这样做的缺点是C#代码中訪问了apsx中的控件Repeater1。也就是在aspx中必需要有一个Repeater类型、Id为Repeater1的控件,这样aspx就和C#代码耦合在了一起。麻烦在哪儿呢?
1)假设aspx有两个地方都要用list了,那么就要写两组DataSource=list;DataBind()。
2)假设aspx中突然不想要Repeater了,把Repeater1删掉C#代码就会报错
3)Aspx中忽然不想用Repeater进行数据的显示了,想换别的控件,那么C#代码也要改
再比方。在ASP.Net WebForm中,实现加法计算器会例如以下实现:
1
2
3
4
|
< asp:TextBox ID="TextBox1" asp:TextBox > +< asp:TextBox ID="TextBox2" asp:TextBox > < asp:Button ID="Button1" < asp:TextBox ID="TextBox3" asp:TextBox > |

protected void Button1_Click(object sender, EventArgs e)
{
int i1 = Convert.ToInt32(TextBox1.Text);
int i2 = Convert.ToInt32(TextBox2.Text);
int i3 = i1 + i2;
TextBox3.Text = i3.ToString();
}

后台的C#代码和aspx的耦合要求aspx视图中必须有三个名字各为TextBox1、TextBox2、TextBox3的TextBox类型的server控件。
假设我想把计算的结果从TextBox改成span就不行。
前端设计人员看到TextBox绝对没有input亲切。前端人员对input 的把控能力会被TextBox更好。另外不必再说WebForm引入的ViewState、页面生命周期、ClientID等令人作呕的问题。
有同学会说了:你有病吗,开发时候aspx怎么可能总是变来变去,即使aspx变了,你C#代码也就变呗。有什么大不了的?
假设说系统小的话可能无所谓,对于比較复杂的系统,假设aspx和C#这样紧密的耦合。维护还会特别麻烦。并且假设实现像一些CMS系统那样能够动态改动模板文件的话就是存在着“C#无法预測、无法强制要求aspx究竟怎么写”的问题。
这还不过展示一个集合的问题。假设要展示复杂的扁平化数据或者须要从用户输入中获取数据,用这样的方式更灾难。
那么MVC思想怎么解决呢?逻辑代码(Controller)不直接和页面视图(View)进行交互,他们之间用Model(数据模型)作为沟通的通道。当须要展示数据的时候由Controller收集到数据(Model)。然后把数据交给View去展示;当Controller须要读取View中用户输入内容的时候,框架会把View中的数据映射到Model中,然后Controller读取Model中的数据进行兴许的逻辑处理。这样就把逻辑代码(俗称C#代码)和视图(俗称页面)进行解耦了。
光说概念没用。还是先看代码把。以下使用MVC模式改造的“显示Person集合”:
View视图PersonsView.aspx

<%@ Page Language="C#"%>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="WebApplication1" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<table>
<%
var persons = (List<Person>)Context.Items["persons"];
foreach(var person in persons)
{
%>
<tr><td><%=person.Name %></td><td><%=person.Age %></td></tr>
<%
}
%>
</table>
</body>
</html>

注意,我把aspx相关的两个自己主动生成的.cs文件删掉了,而且把<%@Page%>标签的AutoEventWireup、CodeBehind、Inherits等几个属性也都干掉了,这样aspx就变成了一个纯粹的“模板引擎”
作为Controller的Index.ashx的代码例如以下:

public void ProcessRequest(HttpContext context)
{
List<Person> list = new List<Person>();
list.Add(new Person { Name="rupeng",Age=8});
list.Add(new Person { Name = "qq", Age = 18 });
context.Items["persons"] = list;
context.Server.Transfer("PersonsView.aspx");
}

这里借鉴了JSP中“request.getRequestDispatcher("index.jsp").forward(request,response)”一样的思路。
context.Server.Transfer是在server内部把请求处理权转交给"PersonsView.aspx"处理。HttpContext中的Items的生命周期是整个请求响应,这样我们在一般处理程序中把数据放到context.Items中。然后在"PersonsView.aspx"中就能够能够通过Context.Items["persons"]拿到这个数据从而进行数据的展示。
为什么把数据放到HttpContext.Items中呢。因为Transfer不过server内部处理权的转接。可是仍然是在一个请求中的,所以放到Context.items是最好的。
假设放到Session、Application等中会有并发的问题。
这样Controller(一般处理程序)和View(aspx)之间仅仅要维持一个“要传递一个名字为persons类型的List<Person>”这样一个弱耦合关系就可以,至于aspx用不用这个persons、用几次persons、怎么用persons。你Controller都不用管。
依照相同方法改造加法计算器
以下是视图AddView.aspx的代码

<%@ Page Language="C#"%>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<%dynamic viewBag = Context.Items["ViewBag"]; %>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>加法计算器</title>
</head>
<body>
<form id="form1">
<input type="hidden" name="action" value="addSubmit" />
<input type="text" name="i1" value="<%=viewBag.i1 %>" />+<input type="text" name="i2" value="<%=viewBag.i2%>" />
<input type="submit" value="=" /><input type="text" value="<%=viewBag.i3 %>" />
</form>
</body>
</html>

而AddHandler.ashx的主体代码例如以下:

public void ProcessRequest(HttpContext context)
{
string action = context.Request["action"];
dynamic viewBag = new System.Dynamic.ExpandoObject();
if(string.IsNullOrEmpty(action))
{
viewBag.i1 = "";
viewBag.i2 = "";
viewBag.i3 = "";
}
else if(action=="addSubmit")
{
int i1 = Convert.ToInt32(context.Request["i1"]);
int i2 = Convert.ToInt32(context.Request["i2"]);
int i3 = i1 + i2;
viewBag.i1 = i1;
viewBag.i2 = i2;
viewBag.i3 = i3;
}
context.Items["ViewBag"] = viewBag;
context.Server.Transfer("AddView.aspx");
}

因为View和Controller之间传递的数据比較复杂、比較多。为了简化开发,这样用了dynamic 动态类型。熟悉ASP.Net MVC的同学是不是感觉这个和ASP.net MVC中的ViewBag异曲同工呢。
在这个加法计算器中假设我想把结算结果用span显示。那么仅仅要把<input type="text" name="i2" value="<%=viewBag.i2%>" />改成<span><%=viewBag.i2%></span>就能够了。美工也easy介入页面美化。
假设我想把页面的Title从“加法计算器”改成“3和5相加的结果”,那么仅仅要这样改就能够:<title><%=viewBag.i1 %>和<%=viewBag.i2 %>相加的结果</title> 这样model里的数据我aspx想用几次用几次,想怎么用就怎么用。
有没有感觉到和WebForm不一样的地方呢?
所以仅仅要思想想通了,事实上实现MVC模式不一定要用ASP.net MVC。我见过非常多项目都是自己搞的MVC机制。
当然既然ASP.net MVC已经这么优秀了,普通情况不是必需像我这样又一次自己发明一个轮子用。这里给大家讲ASPX实现MVC仅仅是用大家熟悉的东西让大家明确原理,project项目应用还是用ASP.Net MVC吧。
如鹏网.Net培训班正在报名,有网络的地方就能够參加如鹏网的学习,学完就能高薪就业,点击此处了解
三年前仅仅要懂“三层架构”就能够说“精通分层架构”。如今则须要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值钱;
三年前仅仅要会SQLServer就能够说自己“精通数据库开发”;如今则需还须要掌握MySQL等开源数据库才干说是“.Net开源”时代的程序猿;
三年前仅仅要会进行用户上传内容的安全性处理就可以;如今则须要熟悉云存储、CDN等才干在云计算时代游刃有余。
三年前仅仅要掌握Lucene.Net就会说自己“熟悉站内搜索引擎开发”;如今大家都用ElasticSearch了,你还用Lucene.Net就太老土了。
三年前发邮件还是用SmtpClient;如今做大型站点发邮件必须用云邮件引擎;
三年前缓存就是Context.Cache。如今则是Redis、Memcached的天下;
如鹏网再次引领.Net社区技术潮流!点击此处了解如鹏网.Net最新课程
不用asp.net MVC,用WebForm照样能够实现MVC的更多相关文章
- 不用asp.net MVC,用WebForm照样可以实现MVC(请看最后一句话)
在<避开WebForm天坑,拥抱ASP.Net MVC吧>这篇博客中我讲到了ASP.net WebForm由于一些先天的“诱导犯罪”的缺陷,现在用ASP.net MVC的公司越来越多.但是 ...
- ASP.NET MVC与WebForm区别
[转贴一] 使用ASP.NET MVC框架,创建默认项目,第一直观感觉就是地址都是Rewrite过的.对源码和配置文件稍加分析不难看出,MVC使用了httpModules来拦截地址请求,具体用到了Sy ...
- (读书笔记)Asp.net Mvc 与WebForm 混合开发
根据项目实际需求,有时候会想在项目中实现Asp.net Mvc与Webform 混合开发,比如前台框架用MVC,后台框架用WebForm.其实要是实现也很简单,如下: (1)在MVC 中使用Webfo ...
- 在ASP.NET非MVC环境中(WebForm中)构造MVC的URL参数
目前项目中有个需求,需要在WebForm中去构造MVC的URL信息,这里写了一个帮助类可以在ASP.NET非MVC环境中(WebForm中)构造MVC的URL信息,主要就是借助当前Http上下文去构造 ...
- ASP.NET MVC显示WebForm网页或UserControl控件
ASP.NET MVC显示WebForm网页或UserControl控件 学习与使用ASP.NET MVC这样久,还是对asp.net念念不忘.能否在asp.net mvc去显示aspx或是user ...
- Asp.net Mvc 与WebForm 混合开发
根据项目实际需求,有时候会想在项目中实现Asp.net Mvc与Webform 混合开发,比如前台框架用MVC,后台框架用WebForm.其实要是实现也很简单,如下: (1)在MVC 中使用Web ...
- 在ASP.NET非MVC环境中(WebForm中)构造MVC的URL参数,以及如何根据URL解析出匹配到MVC路由的Controller和Action
目前项目中有个需求,需要在WebForm中去构造MVC的URL信息,这里写了一个帮助类可以在ASP.NET非MVC环境中(WebForm中)构造MVC的URL信息,主要就是借助当前Http上下文去构造 ...
- [转]Asp.net Mvc 与WebForm 混合开发
本文转自:https://www.cnblogs.com/dooom/archive/2010/10/17/1853820.html 根据项目实际需求,有时候会想在项目中实现Asp.net Mvc与W ...
- Asp.net: WebForm基础上构建Mvc的方法
添加引用: System.Web.Routing System.Web.Abstractions System.Web.Mvc 添加文件夹: Controllers, Views, Views / ...
随机推荐
- python迭代器以及itertools模块
迭代器 在python中,迭代器协议就是实现对象的__iter()方法和next()方法,其中前者返回对象本身,后者返回容器的下一个元素.实现了这两个方法的对象就是可迭代对象.迭代器是有惰性的,只有在 ...
- Java工具类之——BigDecimal运算封装(包含金额的计算方式)
日常对于金额计算,应该都是用的BigDecimal, 可是苦于没有好的工具类方法,现在贡献一个我正在用的对于数字计算的工具类,项目中就是用的这个,简单粗暴好用,话不多说,代码奉上(该工具类需要引入g ...
- javascript第十章--Ajax与Comet
① XMLHttpRequest对象 ② XMLHttpRequest2级 ③ 进度事件 ④ 跨域源资源共享 ⑤ 其他跨域技术
- struts2的简单执行过程
struts2是最近刚学的一个框架,想通过写篇文章来加深下印象,这也是本篇博文产生的由来,下面进入正题 Struts2本身是一个挺简单的框架,我们通过写一个登陆的过程来具体描述下其执行过程 1.首先我 ...
- Swiper 判断上滑下拉操作
onTouchMove: function(swiper){ //手动滑动中触发//判断上滑下拉var i = mySwiper.translate;setTimeout(function() {va ...
- 基于FPGA的有限状态机浅析
前言:状态机大法好,状态机几乎可以实现一切时序逻辑电路. 有限状态机(Finite State Machine, FSM),根据状态机的输出是否与输入有关,可分为Moore型状态机和Mealy型状态机 ...
- [NOIP]玩具装箱
题目:(非常经典的模拟赛题,适合动规入门的OIer) 简要分析: 动态规划,用一维数组 f[i] 表示从位置1 到 位置i 的最优花费 ,由于 f[i ] 以前的最优花费都是确定的,故只需要在 1 ...
- TFboy养成记
转自:http://www.cnblogs.com/likethanlove/p/6547405.html 在tensorflow的使用中,经常会使用tf.reduce_mean,tf.reduce_ ...
- LSF-SCNN:一种基于 CNN 的短文本表达模型及相似度计算的全新优化模型
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 本篇文章是我在读期间,对自然语言处理中的文本相似度问题研究取得的一点小成果.如果你对自然语言处理 (natural language proc ...
- 浅析php命名空间
介绍 印象中只有java代码才会用到一大堆的import,当初看到后一脸懵逼并对php心生自豪:还是我大php牛逼够简洁,殊不知php也有命名空间这一说,这些年用的越来越多.那么,为什么要搞那么麻烦呢 ...