今天你抛弃了ASP.NET了吗? @@银蛋篇@@

让一头大象跳舞,不是去找一头母象,而是一只小老鼠。

---- 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=" 52px" type="text" />
    b:
<input id="Text_b" style=" 52px" type="text" />
    Result:
<input id="Text1" type="text" /><input id="Button1" type="button" value="Invoke Value" style=" 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-TemplatingJTS(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, 用<%%>服务端标记也没有任何问题。

这,还不能作为一个银弹吗?

 
原文地址:https://www.cnblogs.com/zc22/p/1838232.html