• ASP.NET MVC与RAILS3的比较


    进入后Web年代之后,MVC框架进入了快速演化的时代,Struts等垂垂老矣的老一代MVC框架因为开发效率低下而逐渐被抛弃,新一代的MVC则高举敏捷的大旗,逐渐占领市场,其中的代表有Rails (ruby), .NET MVC (.NET), Django (Python),Symfony (PHP)等等,这些框架的思想都大同小异,这里列举出Rails3和.NET MVC的一些的区别,以方便Web开发者从Rails迁移到.NET MVC,或者反之,从.NET MVC迁移到Rails. 

    生成项目 
    Rails和.NET MVC都能够产生项目的基本骨架,只是生成的方式略有不同,Rails采用的是命令行的方式: 

    Java代码  收藏代码
    1. rails tapir  


    而Microsoft则秉承其强大的IDE,提供了项目向导。 

    最终得到的目录结构,仅在测试和配置项上略有不同。 

    Rails ASP.NET MVC
    /app/models /Models
    /app/controllers /Controllers
    /app/views /Views
    /public/javascript /Scripts
    /public /Content
    /db /App_Data
    /test 单独的VS项目
    /config /Global.asax, /Properties, Web.config



    值得一提的是rails的一个亮点:rails可以预先配置三个不同的环境:开发、测试、最终产品,可以通过RAILS_ENV这个环境变量来做简单切换,.NET MVC并未提供这样的配置环境,你可以通过手工配置来完成。 

    模型Model 
    Rails默认采用ActiveRecord作为模型,当然切换到其他的框架也很简单,可选项有 Neo4J, MongoDB,和DataMapper。在Rails中,还是采用命令行来创建模型,Rails会生成一些骨架代码,包括:模型、迁移任务和测试。你可以用-o来选择其他模型、-t来选择其他测试框架: 

    Java代码  收藏代码
    1. $ rails g model customer name:string email:string  
    2.       invoke  active_record  
    3.       create    db/migrate/20100419094010_create_customers.rb  
    4.       create    app/models/customer.rb  
    5.       invoke    test_unit  
    6.       create      test/unit/customer_test.rb  
    7.       create      test/fixtures/customers.yml  



    Rails默认采用Sqlite3作为后台数据库,而且Rails会很贴心的为开发、测试、生产三个环境分别产生一个数据库拷贝。 

    在Rails中,所有的数据库的操作都通过脚本和迁移来完成,Rails中的迁移应该是最有价值的一个东西,当不同的开发者同时在修改一个数据库,或者您在升级现有的生产环境下的数据库,迁移就显示出它的强大威力: 

    Java代码  收藏代码
    1. class CreateCustomers < ActiveRecord::Migration  
    2.   
    3.   # Called when migrating up to this version  
    4.   def self.up  
    5.     create_table :customers do |t|  
    6.       t.string :name  
    7.       t.string :email  
    8.       t.timestamps  
    9.     end  
    10.   end  
    11.   
    12.   # Called when migrating down from this version  
    13.   def self.down  
    14.     drop_table :customers  
    15.   end  
    16. end  



    我们可以通过rake db:migrate命令迁移到不同的数据库版本上去。 

    和Rails不同的是,.NET MVC并为绑定一个模型框架,你要从既有的框架中选择一个适合你的,这个名单里可以用Nhibernate,Linq to SQL, Entity Framework,Castle ActiveRecord或者Ruby的ActiveRecord,不过.NET MVC没有迁移的概念,这有点遗憾。 

    大部分情况下Linq To SQL就很适合项目开发。 

    查询语言 
    Rails3使用AREL(Active Record Relations),LINQ-to-SQL则使用LINQ。 二者都是相当优美的语言 

    Java代码  收藏代码
    1. # A simple query with AREL  
    2. User.where(users[:name].eq('Anders')).order('users.id DESC').limit(20)  



    Java代码  收藏代码
    1. // The same with C#  
    2. // Lambda Syntax  
    3. db.Users.where(u => u.Name == "Anders").orderBy(u => u.Id).Take(20)  
    4.   
    5. // LINQ Syntax  
    6. (from u in db.Users  
    7. where u.Name == "Anders"  
    8. orderby u.Id descending  
    9. select u).Take(20);  



    现在除了在.NET中采用Ruby的ActiveRecord(借助ironruby),目前还没有其他框架提供类似Ruby的findbyXXX的功能,不过C# 4.0的method_missing使得这类框架应该会很快出现(比如Nhibernate 3.0) 

    控制器 
    在.NET MVC中,你在Controller目录上点添加,就有很贴心的向导引导你为项目添加控制器,甚至还可以增加基本的CRUD的功能。 

    Java代码  收藏代码
    1. public class CustomersController : Controller {  
    2.       // GET: /Customers/  
    3.       public ActionResult Index() {  
    4.           return View();  
    5.       }  
    6.   
    7.       // GET: /Customers/Details/5  
    8.       public ActionResult Details(int id) {  
    9.           return View();  
    10.       }  
    11.   
    12.       // GET: /Customers/Create  
    13.       public ActionResult Create() {  
    14.           return View();  
    15.       }  
    16.   
    17.       // POST: /Customers/Create  
    18.       [HttpPost]  
    19.       public ActionResult Create(FormCollection collection) {  
    20.           try {  
    21.               // TODO: Add insert logic here  
    22.               return RedirectToAction("Index");  
    23.           } catch {  
    24.               return View();  
    25.           }  
    26.       }  
    27. }  



    和Rails的脚手架代码一样,这些最基本的代码99%会被废弃,但是提供了“让程序跑起来看看”的基础。 

    Rails还是通过命令行来为项目增加控制器,你还可以在命令行里制定为控制器生成哪些Action。 

    过滤器 
    Rails很容易为某个Action添加个过滤器 

    Java代码  收藏代码
    1. class ItemsController < ApplicationController  
    2.   before_filter :require_user_admin, :only => [ :destroy, :update ]  
    3.   before_filter :require_user, :only => [ :new, :create]  
    4. end  


    .NET也不含糊,只要重载OnActionExecuting就可以实现同样的功能: 

    Java代码  收藏代码
    1. override void OnActionExecuting(ActionExecutingContext filterContext)  
    2. {  
    3.     var action = filterContext.ActionDescriptor.ActionName;  
    4.     if (new List<string>{"Delete", "Edit"}.Contains(action)) {  
    5.         RequireUserAdmin();  
    6.     }  
    7.     if ("Create".Equals(action)) {  
    8.         RequireUserAdmin();  
    9.     }  
    10. }  


    或者通过.NET的attribute更漂亮的完成 

    Java代码  收藏代码
    1. [RequireUserAdmin("Delete", "Edit")]  
    2. [RequireUser("Create")]  
    3. public class CustomersController : Controller  



    路由 
    在Rails中,可以修改routes.rb来修改路由,默认的Rails的路由被配置成RESTful: 

    Java代码  收藏代码
    1. Tapir::Application.routes.draw do |map|  
    2.   resources :animals  
    3.   
    4.   get "customer/index"  
    5.   get "customer/create"  
    6.   
    7.   match "/:year(/:month(/:day))" => "info#about",  
    8.     :constraints => { :year => /d{4}/,  
    9.         :month => /d{2}/,  
    10.         :day => /d{2}/ }  
    11.   match "/secret" => "info#about",  
    12.     :constraints => { :user_agent => /Firefox/ }  
    13. end  


    通过rake routes你可以快速查看路由的结果。 

    ASP.NET MVC的路由稍微复杂一些,不过同样强大: 

    Java代码  收藏代码
    1. // Global.asax.cs  
    2.  public class MvcApplication : System.Web.HttpApplication {  
    3.     public static void RegisterRoutes(RouteCollection routes) {  
    4.         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");   
    5.   
    6.         // Constrained route  
    7.         routes.MapRoute( "Product", "Product/{productId}",  
    8.             new {controller="Product", action="Details"},  
    9.             new {productId = @"d+" } ); // Constraint  
    10.   
    11.         // Route with custom constraint, defined below    
    12.         routes.MapRoute( "Admin", "Admin/{action}",  
    13.             new {controller="Admin"},  
    14.             new {isLocal=new LocalhostConstraint()} );  
    15.     }  
    16. ...  
    17. }  
    18.   
    19. public class LocalhostConstraint : IRouteConstraint {  
    20.     public bool Match ( HttpContextBase httpContext, Route route,  
    21.         string parameterName, RouteValueDictionary values,  
    22.         RouteDirection routeDirection )  
    23.     {  
    24.         return httpContext.Request.IsLocal;  
    25.     }  
    26. }   



    View 
    二者在View上的表现十分接近,添加控制器的时候,会自动创建相应的视图,规则也类似:视图所在的文件夹以控制器的名字命名,视图的文件名则以控制器的action命令,二者也都提供了从某个模型创建脚手架视图的能力。 

    Partials 
    Rails和Asp.NET MVC都提供了在文件中包含部分HTML文件能力,ASP.NET MVC的文件采用ASP,而Rails默认是ERB或HAML. 

    Java代码  收藏代码
    1. <!-- Rails -->  
    2. <%= render 'form' %>  



    Java代码  收藏代码
    1. <!-- ASP.NET MVC -->  
    2. <% Html.RenderPartial("Form", Model);%>  



    .NET MVC 2中更做出了一些改进,提倡用2个替代的方法来产生代码: 

    Java代码  收藏代码
    1. <%= DisplayFor("Address", m => m.Address ) %>  
    2.   
    3. <%= EditorFor("Address", m => m.Address ) %>  




    尾声 
    这篇文章对Rails和.NET MVC作了一个快速的浏览,目的是让有相应编程经验的程序员能快速了解另一个框架。无论Rails还是.NET MVC,都只是一个工具,一个好的程序员应该能随心摆弄他的工具,而不是被工具所摆布。 


    参考: 
    http://blog.jayway.com/2010/04/23/asp-net-mvc-vs-rails3/

  • 相关阅读:
    爬取网页图片
    python 猜数字游戏
    位移运算
    生成随机的名字
    不截半个汉字
    一致性hash的实现
    安装前端脚手架
    什么是快速排序?
    HTML5有趣的标签
    stopPropagation / stopImmediatePropagation
  • 原文地址:https://www.cnblogs.com/ranran/p/3818782.html
Copyright © 2020-2023  润新知