CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

MonoRail --> ASP.NET On Rails?

I've been poking around into some of the Ruby on Rails stuff recently, and just watched this video extolling the virtues of Ruby on Rails, and showing the construction of a blog engine in 15 minutes..
 

Creating a weblog in 15 minutes

"In 15 minutes, we go from scratch to complete weblog engine: with comments and an administrative interface. But since the actual application only took 58 lines to complete, we also have time left over to do unit testing, examine the logs, and play around with the domain model."

First, go watch that video.  I think you'll be inspired... this is really cool stuff!  After I saw this, I sat there thinking to myself that it would be way cool to see ASP.NET for Rails.  Well, it turns out that there is!  The MonoRail project looks pretty much to me like it's ASP.NET on Rails.

MonoRail (former Castle on Rails) is a MVC web framework inspired on Action Pack. The Action Pack way of development is extremely productive, very intuitive and easily testable.

MonoRail differs from the standard WebForms way of development as it enforces separation of concerns; controllers just handle application flow, models represent the data, and the view is just concerned about presentation logic. Consequently, you write less code and end up with a more maintainable application.

I think we'd all use patterns more if we had  a framework geared towards patterns like Ruby on Rails is for the Model-View-Controller.  Sure, we've got lots of examples of the Provider pattern implemented in the new ASP.NET for things like Membership, which is fine, but how often are we really going to be writing pluggable providers?  I'd bet that more often as ASP.NET developers we'll be writing some sort of CRUD code that is best implemented as MVC.  I've gotta look into this!

-Brendan



Comments

Eric Wise said:

You write a pluggable provider anytime you need to support differences.

For example, the project I'm working on at my employer my pull its data from our store or can be substituted with a store the client chooses. ;)

But yes, provider is nearly useless for inward only projects.
# January 18, 2006 10:16 PM

Steve said:

Ruby on Rails is impressive isn't it :) It makes me wish we had something equivalent in the .NET world. I've just started looking at MonoRail myself and evaluating if and how I should start incorporating it into the "web stuff" I'm working on.

Cheers,
Steve
# January 18, 2006 10:18 PM

Sam said:

From what I remember of MonoRail:

NVelocity sucks. It's not terrible, but it's not robust either. There were obvious bugs and limitations. This is perhaps resolved by now (~3 months ago). You now have a choice in View engines too (Brail).

I never looked into ActiveRecord in MonoRail. NHibernate adds a lot of complexity I think, but if anyone can wrap that up into a simple package it'd be hammet. And I don't mean that it's hard to figure out, though sometimes I found myself wishing for better docs. I mean it's hard to maintain compared to something like RoR's ActiveRecord with zero configuration. Of course NHibernate is also _a lot_ more powerful than RoR's AR. If you need it...

Documentation on MonoRail was lacking, but it seems to be steadily improving.

I really liked WindsorContainer. By far the best IoC container on .NET IMO.

If I remember correctly, it provides some generators I think. Definitely start with those. One of the biggest advantages to RoR over ASP.NET is the inherent structure. Half the questions people ask in the .NET community seems to be about how to define a structure and know where to put code. That comes baked into RoR, and IIRC MonoRail should have something similar.

I can't stress that enough. Generators are vital. They're not code-gen tools to ignore, they're more like project skeleton generators.

The most difficult thing about MonoRail for me was leaving behind things like pre-packaged controls, but you quickly learn you just don't need them, and you don't need some complex control to abstract a bit of HTML. Not only will you write better, more standards compliant and cross-platform HTML without 'em, but I found out that WebControls are actually (IMO) pretty lousy abstractions of an already very cleanly abstracted way to write web-pages (in HTML/CSS/JS).

Of course Behaviour.js is a life-saver. Prototype.js is indespensible. Scriptaculous.js brings together some great one-liners. The list goes on.

Hammet freely admits MonoRail isn't ideal last I read. If you have a choice, RoR is actually his recommendation. I'm sure he'll stop by and speak for himself though. :-)

Just the same, MonoRail is definitely superior to vanilla ASP.NET IMO in practically every way. Get stuff done faster, that's much easier to maintain, without the questions of where to put business logic, or where to put validation code, or what's the best DataGrid, etc. After a bit of practice it's easy to whip up some standard JS and CSS to decorate any old table with functionality that'll blow any DataGrid away, and Behaviour.js will let you do it declaratively so you don't even need to edit the HTML.

Behaviour.register({
'table.tabular': function(e) { /* Get yo' decorate on! */ },
'table[sortable=true]': function(e) { /* Go ahead, use CSS3 selectors if you want. */ }});

As simple as that in your layout.js.

Of course Prototype is duplicating Behaviour's document.getElementsBySelector() method with a $$() method. Prototype's version supports multiple selectors too though I think, which is gonna be groovy. I think the example I saw today was something like:

$$('div#content ul[sortable=true] li.menu').each(Element.hide);

That's a pretty sweet one-liner. Find the "content" div; find any ul's under it with a "sortable" attribute that equals "true", and hide every li within them that has the "menu" class applied.

Yeah, the $(), $F() and $$() functions are weird at first, but pretty quickly you get used to them and don't miss typing:

$('content')
// or would you rather:
document.getElementById('content') || document.getElementByName('content')

$F('username')
// or would you rather:
document.getElementById('username').value

$$('div#content ul.menus')
// or would you rather:
document.getElementsBySelector('div#content ul.menus')

Ok, just being able to do the last one is pretty amazing to me either way, but I can't wait for the next release of Prototype for the $$() function (it's only in the trunk right now).

Sorry for rambling. ;-)

BTW: Just to bring a little balance...

RoR sucks because:

No OS Threading in Ruby. So things like Socket reads/writes are blocking. Not cool. Doesn't affect you most of the time, but if you're waiting around for the network when you could be doing other work you'll wish for OS Threads.

The Rails Database adapters are surprisingly immature. They're getting better, but they're no where near the level of ADO.NET. In practice this doesn't affect you much, but things like closed sockets are detected and handled specifically in most first-party drivers because they're important things to have, even if you probably don't ever specifically catch and handle that specific error. Rails 0.13 just swallowed them as generic DatabaseErrors. Which is definitely not spiffy.

Rails is really geared for Linux. The supporting tools like SwitchTower, and the webserver support are very OSX and Linux centric. You can have a grand old time developing on Windows, but when it comes time to deploy it'll be much mo' beuno if Linux is the target. Ruby itself has pretty great cross-platform support, allowing stuff like Dir.grep('**/*.asp'), but the syntax is Unixey still.

Of course you can run Apache on a Windows server just fine, but you'll miss out on some of the cool stuff.
# January 18, 2006 11:49 PM

Brendan Tompkins said:

Thanks for the comments Sam...

I agree that the Ruby on Rails code generators are killer. Something I think many of us struggle with is not syntax, or language features or how to wire up controls, but generally how to structure classes and other code.
# January 19, 2006 8:54 AM

hammett said:

Hey Sam, some things I'd like to add:

- RoR is cool, but after some deep analises I realised that the coolness comes from Ruby. .net really lacks a cool dynamic language.

- RoR is much more productive, again 'cause Ruby allows you to express much with less types.

- RoR is not "enterprise ready". Unfortunatelly this is true. It doesn't mean that people shouldnt use. It does mean that it's not a silver bullet like some people think it is. The transactional support should be more than simple database transactions. RoR's AR can also lead to some major headaches as they are not scoped, but only if you slip from the standard way of way of writing Rails apps.

- On MonoRail, we're now favoring VS.Net integration than code generators. Seems that most of MS world developers feels more comfortable with that.

- RoR lacks lots of features that go unmentioned. Ruby for example seems to not support unicode. Rails does not support i18n.

- The DataBinder and ARDataBinder stuff on MonoRail are also cool stuff. I use all the time and it indeed saves me lots of aggravation.

- MonoRail is not opinated software. I truly thinks this is terrible. I'd never consider using a tool or framework that would force me to embrace some paradigms. I can agree with the very paradigms, but will my clients do the same? will my company, my co-workers? With MonoRail there's no something like the RoR's stack. AR, MR, MicroKernel are separated packages that can be optionally tied together through facilities.

Well, I don't know. I'm biased and those were my two cents :-)
# January 19, 2006 12:22 PM

Robin Curry said:

# January 19, 2006 3:45 PM

Sam said:

hammet:

I'd be careful with the "enterprise" word. I agree, but I think a lot of people will take that to mean unsafe, or not flexible, when really it basically boils down to no Two Phase Commit support in the existing database drivers. Beyond that Ruby as a language is more ready IMO than any other I've worked with. But I'm pretty much one of those people that thinks it's a silver bullet. ;-)

I could as easily say that .NET has terrible WebDAV support for example.

I was easily able to whip out a library in Ruby that did this in a few hours:

uri = 'https://example.com/exchange/admin/'
options = { :user => 'mydomain\admin', :password => 'random' }

RExchange::open(uri, options) do |mailbox|
# what might not be apparent is that "inbox" is a dynamic method
# and you can chain subfolders under it. A RExchange::Session
# doesn't actually define an inbox method.
mailbox.inbox.each { |message| p message.subject }
end

Ruby supports unicode just fine. Strings are binary in Ruby. What it doesn't support (out of the box) are regular expressions against arbitrary encodings since a String has no concept of an encoding.

Basically this means you can do the same stuff in Ruby, but you have to know more about your target encoding like how to write the Byte Order Marks for UTF16LE/BE or UTF-8, and in Windows you have to open your files with the 'b' switch (for binary read/write).

It could definitely be better, but in practice, you can use Time.to_s(:format) or 10.usd.in_yen.to_s(:format), so the claim it doesn't support i18n (internationalization) is really unfounded IMO.

The main sticking points for Ruby's Strings and usage with arbitrary encodings are Regular Expressions and File Encodings. packing/unpacking a String from your application wide culture-code ($KCODE) to/from Unicode or UTF-8 is actually pretty simple, but not well documented.

Or you could just set your $KCODE to 'u' (UTF-8) and be done with it if you can gaurantee UTF-8 input/output.

(And I've written a Rails app that had to work in english and japanese, so I'm not talking about theoretical or complicated stuff, but it's one of the points in Ruby and Rails that could be much better documented for sure.)

Of course it sounds like MonoRail is really making great progress. And your ActiveRecord implementation already has a lot of advantages. Thanks for clearing some of that up for me!
# January 19, 2006 7:26 PM

hammett said:

Hey Sam,

Don't take my comments on Ruby and Rails into heart, people can be amazingly passionated about it, which from my standpoint does not create a healthy discussion ;-)

By enterprise I go beyond 2PC and two databases, I've worked on projects that message queue and the filesystem were transactional. That's what I meant by going further than database transactions. However I think I'd be able to contribute this to Ruby community (I love the XA protocol and the infrastructure for transactional processing), but need to find time to do it... *sigh*

On Ruby, well, we completely agree here. The language is just beautiful. But accordingly to this guy [http://www.cse.iitb.ac.in/~kart/writings/Ruby%20vs.%20Boo%20(long).html], ruby strings are not unicode. And when I talked about i18n, I said Rails does not support it (AFAIC). By that I mean that the framework does not provide (yet) functionality to strip and separate text, image location, date and currency format and adjust that according to the session/user location.

I'm not competing with RoR here. But as I always say 'there are scenarios and there are scenarios'. For some projects RoR will be just fine. For some MR can fit nicely. Others you may want to embrace an ugly J2EE stack. None of those are silver bullets, all have their flaws and problems, some of them you can help improve, some you can't. That's life ;-)

Cheers!

# January 19, 2006 8:39 PM

Sam said:

regarding i18n:

The link you posted is kinda right, this explains a bit more: http://wiki.rubyonrails.com/rails/pages/HowToUseUnicodeStrings

Basically the deal is this: Strings are Unicode in .NET. More specifically they're UTF-16 (I'm guessing they lack the BOM). All IO wether it be through the Console, File, etc goes through the Encoding classes (I say this like it's fact, but it's just a logical guess).

Ruby is different. There's no such thing as Encoding. Instead Ruby uses encoding-aware methods. This means many of the standard String methods can change behaviour based on the $KCODE. This includes RegExp.

And that's really all there is to it. This means when dealing with IO in Ruby you have to be aware of the source Encodings and what you're current $KCODE is since that controls the native types.

There are different libraries you can use if you need Unicode support, but none are even de-facto standards as far as I can tell.

Rite (Ruby 2.0) is supposed to add m17n support (where every String is encoding aware, much more flexible than i18n), but that's months away at least and I wouldn't be surprised if we don't see it before Christmas so that's not really part of the picture right now.

Now as far as Time and Currency go, ActiveSupport extends Time to provide custom date/time formats. You can define your own at any time. So scraping a list of culture-codes and formats to add as definitions is a piece of cake.

If you didn't want to have to remember to call Time::now.to_s(:ja_JP) you could even overwrite to_s to get it's culture code from the Singleton instance and have Times displayed in the proper format in your ERb output "automagically".

Currency is another matter. You can use 'units/currency' like I mentioned earlier and extend to_s to be culture-aware by returning a Currency class from Numeric#in_currency instead of another Numeric. Then you could handle to_s pretty much the same as Time but with the correct formatting for a particular currency.

There's also no reason you couldn't easily set your current culture from the Request.

The biggest issue is making sure you keep your IO friendly with UTF-8. I believe Onigurama (the RegExp engine to be used for Rite) works with UTF-8 without any String packing, and you can build it in Ruby 1.8.4 easily enough.

So writing an internationalized website in Rails is actually pretty dang easy, though it does take more thought than a comparable .NET application would I'd agree.

I'm not trying to sound argumentative BTW, it's just nice to be able to hash stuff out through discussion (even if I'm often wrong).

Anyways, thank you very much for MonoRail! I'm split about 50/50 on going with Rails or MonoRail for an upcoming project. It's good to hear you're still bustin' out the code. :-)
# January 20, 2006 1:12 AM

hammett said:

Sam, if you have to _write_ the code to format currency and dates accordingly to the user's location, then you don't have locationzation support. That's my point.

On a .net web application all I have to do is

amout.ToString("C")

and set the Thread culture/UI info. It will format to $ or to R$, to that pound symbol and so on automatically.

Cheers!
# January 20, 2006 5:45 AM

Sam Gentile said:

Just so the record is clear, since I am being mistaken for the "Sam" in the post, it is not me which is identified by y CodeBetter name
# January 20, 2006 10:43 AM

Sam said:

D'oh!

What are the odds of two Sams in the world? ;-)

hammet: I concede. :-)

I guess the reason it seems like a non-issue to me, is I'm talking about something like this:

class Time
alias old_to_s to_s
def to_s(format)
return old_to_s(@@culture_code) if @@culture_code
return old_to_s(format)
end
end

And besides a language-change hook you'd need in any language, and a few minutes writing a scraper if you can't already find a dictionary of Ruby time formats per culture-code, you're done.

So is it an issue? I dunno. You decide.
# January 20, 2006 7:03 PM

Christopher Steen said:

.Net Unwrapped [Via:
paul ]
Access a file with a different user identity with Enterprise
Services...
# January 20, 2006 11:50 PM

DMITR said:

Hm... interesting to think.
# July 13, 2006 10:22 PM

Brendan Tompkins said:

James Avery talks about Pete Wright leaving Microsoft "I have a ton of respect for Pete and look

# September 15, 2006 9:16 AM

Not well informed said:

ASP.NET is an implementation of MVC. .NET on Rails doesn't make sense.

Ruby.NET or C# on Rails might make sense.

# September 23, 2006 1:53 AM

megalex said:

From a complete newbie looking for .net frameworks MonoRail is a bad choice.

Documentation is Lacking SEVERELY. I tried to get their basic tutorial working and it was a nightmare. It left you with more questions than answers. They need to take a look at Codeigniters and come up with something that simple ( extract and start coding ).

# October 6, 2006 3:44 PM

Marc Hoeppner said:

Viel Hype um Ruby On Rails. Wer sich mal ein Bild verschaffen will, der hat hier einen guten Einstieg.

# October 16, 2006 2:53 AM

Kaveh Shahbazian said:

Microsoft is all about increasing coupling between it's products and you are learning and doing "microsoft" not programming!

I am starting to dump microsoft in all aspects.

Me? from 2002 C#/ASP.NET, .NET compact, windows applications, SQL server and before that VC++/MFC and I was a fellow of microstf ... I "was" ... That's my biggest shame!

Do not like this? Then go microsoft! But in anyway you are just pieces of it's technology; you are some part of it's $ making machine! Is $ bad? No! Not in anyway. But microsoft is not a provider; it is an eater!

# January 24, 2007 12:58 AM

billie said:

It would be a good day when Microsoft adopts and or builds upon monorail

# July 17, 2007 3:33 PM

railsfan said:

just use Rails

# December 24, 2007 1:23 PM

brendon s japanese name in ruby said:

Pingback from  brendon s japanese name in ruby

# June 27, 2008 4:12 AM

David Mariacher said:

Hi,

have you some experience with MonoRail and multiple languages? We use MonoRail and my programmers can't get it done somehow.

The problem is- we have german and english label-texts, both lie with a *.resx-File. Now the customer wants to edit the *.resx-Files to use his own texts.

The problem is, that this requires a recompilation of the application since the *.resx-Files are somehow linked into the binary.

Is there any solution, that will work _without_ recompiling (and delivering) the whole thing?

Best regards

David

# August 12, 2008 10:36 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Brendan Tompkins

Brendan has been programming with .NET since the first public beta and is owner and operator of Port Technology Services, a consultancy company providing .NET application development services to the Maritime industry. In July, 2007, he was awarded the Microsoft MVP award for ASP.NET. He's also a proud co-founder of failed .COM startup Intrinsigo, and has had a hand in the failure of numerous other businesses. He currently runs CodeBetter.Com and Devlicio.us, and lives in Norfolk, Virgina with his wife Tiara and son Ian.

View Brendan's profile on LinkedIn

Check out Devlicio.us!

Our Sponsors