zoukankan      html  css  js  c++  java
  • 今天你抛弃了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, 用<%%>服务端标记也没有任何问题。

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

     
  • 相关阅读:
    Python基础知识篇
    Django框架
    Django REST Framework框架
    NoSQL
    MySQL恩恩怨怨
    Python奇技淫巧
    一文搞定Flask
    数据结构与算法(Python)
    学习数据分析
    项目杂项
  • 原文地址:https://www.cnblogs.com/zc22/p/1838232.html
Copyright © 2011-2022 走看看