在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
让一头大象跳舞,不是去找一头母象,而是一只小老鼠。
---- IT民工 第10xx01号“名言”
在今天你抛弃了ASP.NET了吗?问题篇中,我被各位“猛士们”骂了个狗血淋头,感到鸭梨很大。既然已经里外不是人,我就爽快来个玉石俱焚,鱼死网破吧!这篇文章,我通过分析现有的一些前端开发技术,显示一种ASP.NET下的快速开发模型——银蛋(SILVER EGG)!
ASP.NET中的银蛋 ------------------------------------------------------------------------ asp.net就是一头大象,为了让asp.net敏捷起来,无数的烈士们不断的去寻找着各种类型母象(ASP.NET AJAX, ASP.NET MVC, Nvelocity...),可是这头大象就是提不起精神。既然如此难伺候,那我何不请只小老鼠出来试试? 我先展示一下快速开发模型的代码和实现,然后介绍我的思考过程和资料收集过程。
1. 我的小老鼠-- JsonPage
代码
using System;
using System.Collections.Generic; using System.Text; using System.Reflection; using System.ComponentModel; using System.Globalization; using System.Data; namespace AspNetSilverBullet { public class JsonPage<T> : System.Web.UI.Page { protected override void OnLoad(EventArgs e) { // if Non-json request, directly return. if (Request.QueryString.Count == 0) { base.OnLoad(e); return; } // get method name string methodname = Request.QueryString["method"]; // reflect method info. MethodInfo method = typeof(T).GetMethod(methodname); // construct method call arguments List<object> arguments = new List<object>(); foreach (ParameterInfo parameterType in method.GetParameters()) { arguments.Add(EnsureType(parameterType.ParameterType, Request.QueryString[parameterType.Name])); } // reflect object instance object targetObject = typeof(T).GetConstructor(Type.EmptyTypes).Invoke(new object[] { }); // invoke method result object result = method.Invoke(targetObject, arguments.ToArray()); // response Response.Clear(); Response.Write(ObjectToJson(result)); Response.Flush(); Response.End(); } private object EnsureType(Type targetType, string argument) { if (targetType.Equals(typeof(string))) return argument; return TypeDescriptor.GetConverter(targetType).ConvertFrom(null, CultureInfo.InvariantCulture, argument); } private string ObjectToJson(object result) { if (result == null) return "0"; if (result.GetType().IsValueType) return result.ToString(); if (result.GetType().Equals(typeof(string))) return result.ToString(); if (result.GetType().Equals(typeof(DataTable))) return DataTableToJson(result as DataTable); return result.ToString();// TODO use Newtonsoft to serialize object to json. } private string DataTableToJson(DataTable table) { StringBuilder builder = new StringBuilder(); builder.Append("["); foreach (DataRow row in table.Rows) { builder.Append("{"); foreach (DataColumn column in table.Columns) { builder.AppendFormat("\"{0}\"", column.ColumnName.Trim().ToUpper()); builder.AppendFormat(":", new object[0]); if (column.DataType.IsValueType) { builder.Append(row[column]); } else { builder.Append("\"").Append(row[column]).Append("\""); } builder.Append(","); } builder.Remove(builder.Length - 1, 1); builder.Append("},"); } if (builder.Length > 1) { builder.Remove(builder.Length - 1, 1); } builder.Append("]"); return builder.ToString(); } } } 这是个继承了Page的类,负责分析用户请求,转化为JSon请求,然后返回客户端。
2. Default.aspx + Default.aspx.cs 微软的大象
代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Asp.net Silver Bullet</title> <script type="text/javascript" src="js/jquery-1.2.3.min.js"></script> <script type="text/javascript" src="js/ejs.04.js"></script> <script type="text/javascript" src="js/parseuri.js"></script> <script type="text/javascript" src="js/getfunctionname.js"></script> <script type="text/javascript"> // jquery extend by pixysoft, http://www.cnblogs.com/zc22 function invoke(param,callback) { var method = getFnName(invoke.caller); $.get(parseUri(window.location).file+"?method="+method, param, callback); } </script> <script type="text/javascript"> // jquery ajax $(document).ready(function() // register event { $("#Button1").bind("click", Caculate); }); function Caculate() // invoke server side. { invoke({ a: $("#Text_a").val(), b: $("#Text_b").val() }, function(responseText,textStatus) { $("#Text1").val(responseText); }); } </script> </head> <body> <div> <b>Asp.net + Jquery Example:</b><br /> a:<input id="Text_a" style="width: 52px" type="text" /> b:<input id="Text_b" style="width: 52px" type="text" /> Result:<input id="Text1" type="text" /><input id="Button1" type="button" value="Invoke Value" style="width: 104px" /> </div> </body> </html>
代码
using System;
using System.Data; using System.Configuration; using System.Collections; using System.Web; using AspNetSilverBullet; public partial class _Default : JsonPage<DefaultController> { }
3. 让大象跳舞吧!
using System;
using System.Data; using System.Configuration; public class DefaultController { public int Caculate(int a, int b) { return a + b; } }
4. 大象的舞姿!
5. 银蛋下载: http://www.boxcn.net/shared/4t3qpevyap
银蛋的 WHAT? HOW? WHY? ------------------------------------------------------------------------ 1. 什么是JsonPage, 为什么继承Page? JsonPage就是一个HttpHandler,通过拦截页面的ajax回调请求,反射逻辑方法,然后返回json结果。 同时JsonPage使用了泛型参数作为了逻辑方法的注册机制,极大简化了开发。
首先,我必须使用ASP.NET,否则所有c#代码都会报废。 我曾经思考过HttpHandler,虽然实现一个Httphandler,然后在web.config里面注册,貌似整个架构变得很干净。但是,在实际使用中,用户对服务端发出的URL请求如何被映射到我的逻辑类里面呢? 如果用spring的机制,另写一个xml做映射,这简直就是自掘坟墓。一个action写一个xml,那么一个网站不就100+条的配置了?而且一旦修改起来,很快就会崩溃,接下来就需要再写一个xml配置器了;之后xml配置器变得庞大功能越来越多,就希望集成到VS里面了。。。然后就是自己不断给自己挖坑,还被蒙的理所当然。 ASP.NET使用了一些trick,在aspx文件头有个<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>, 这是啥?这个就是个spring的动态加载!微软把用户请求路由到了磁盘的aspx文件,然后读取了头声明,动态加载了逻辑类(Codebehind),然后输出的时候再过滤掉头声明。 多么的优雅又巧妙的设计!这个是Java servlet学不来的!而且Page最终会被动态编译为一个HttpHandler。 既然微软提供了如此优雅的架构,我何不顺手拈来! 所以,最终我使用了一个继承JsonPage的类作为拦截器。即利用了微软aspx的优势,同时又嵌入了自己
2. 不使用Web Control, 页面如何回调服务端代码? 这部分就是微软的ASP.NET大象,也是让我最头疼的地方。最终: 前端我使用了Jquery作为页面的核心模块; 使用了来自博客园伟大的司徒正美的Javasctipt Template(EJS)作为前端模板 再引入了一些技巧性的Javascipt,例如获取当前页面请求的URl、当前JS调用的函数名等,简化JS代码。因此我们调用一个服务端代码仅仅需要: 注册js事件:
$("#Button1").bind("click", Caculate);
声明js事件内容并回调 invoke(param, callback): 代码
function Caculate() // invoke server side.
{ invoke({ a: $("#Text_a").val(), b: $("#Text_b").val() }, function(responseText,textStatus) { $("#Text1").val(responseText); }); }
通过一些js技巧,前端的js函数直接调用了服务端同名的类方法,简化了开发流程。
之前花了一个多星期搜索前端开发的技术,看了EXTJS,那500k+的体积让我顿时害怕。看了Mootools/Prototype/YUI等等,最终选择了Jquery,原因只有一个,很多人在用。多人用,就意味着很多人会在JQuery有贡献有积累,有沟通。我们快速开发网站也变得更加容易(copy+Paste嘛)。
可是Jquery仅仅实现了一个选择器的功能,涉及到了和服务器互通又遇到了困难。网络有人介绍使用web service / WCF / HttpHandler等和Jquery通讯,可是我实在没有兴趣。一个简单的http调用干嘛又要引入一堆的技术架构?而且使用了web service等,项目开发部署又变得复杂了,肯定又被PHP们嘲笑了。所以我就十两挑千斤,回归Page。
使用原有的aspx技术,如何去控制页面逻辑呢?例如最简单的GridView、Repeater之类的。于是看了Php/Cocoon/NVelocity/ASP.net MVC。但是都让我很失望。无意中搜索到了JQuery Template,顿时眼前一亮。我搜索了JavaScript Micro-Templating,JTS(Javascript Template Syntax), 微软的JQuery提议,甚至是让我非常激动的PURE,可是,他们离完美就是这么的差一点,So Close...。最后,我来到了博客园的司徒正美,我知道我找到了。首先不需要写各种奇怪的模板标记({{ }} ...)其次用JS就完美演绎了页面模板编程,这让前端的技术学习曲线下降了很多。使用司徒的模板,我们仅仅需要:
代码
<script id="tmpl" type="text/html"> <## javascript template #>
<ul> <# for(var i=0; i< json.length; i++){ #> <li><#= json[i].COLUMN #></li> <# } #> </ul> </script>
多么的优雅啊。
后续 ------------------------------------------------------------------------ 曾经,作为一名asp.net的我,总是发现google的前端技术, fackbook, kaixin001, digg等等他们的前端技术离我很远。看着他们很炫的JS效果,丰富的plugin,我总是不知所措。我真的很想用,但是一打开VS20xx,打开了aspx就不知所措,仿佛他们是来自另外一个世界的。 现在,我总算尝试走出了一步。 用了本文的思路,业务逻辑可以完全打包进入一个类库DLL,前端也完全可以脱离了asp.net的代码,直接用JS写各种逻辑。上一篇怨文中各种问题都不再出现。 而且,我并没有改变ASPX的开发习惯,页面还是那个页面,c#还是那个c#。如果有人觉得不爽,想用web control, 用<%%>服务端标记也没有任何问题。 这,还不能作为一个银弹吗?
|
请发表评论