February 2010 Entries

430489129_88c2d4a072 On the surface, I suppose this is YAMVCVWFC (Yet Another MVC vs. WebForms Comparison). If this topic doesn’t appeal to you, or you’re sick and tired of this discussion then I encourage you to move on. I won’t be offended, promise. This post is here to serve as my living, breathing arguments for fighting for MVC and it will serve to highlight my major gripes with Web Forms.

The motivation for this post came from an all-too-familiar IRC chat in #asp.net – for those of you unfamiliar with IRC, it’s a lot like the Twitter of the 90s.

Fallacy: Web Forms does everything I need it to

(01:29p) <webformsdev> 99.9999999999% of client requests, project requirements, etc etc, can easily and equally be done using webforms or mvc
(01:30p) <webformsdev> webforms + jquery = does everything I need
(01:30p) <@mattman> getting something done, and getting something done in a testable, maintainable, long-term way, are entirely different

Fallacy: MVC is just a bunch of <%= HtmlHelpers %>

(01:33p) <webformsdev> how is <%HtmlHelper%> innovative
(01:34p) <@mattman> HtmlHelpers are 4% of the ASP.NET MVC platform. That’s like saying <asp:Textbox> is all of asp.net webforms
(01:35p) <@mattman> http://www.codethinked.com/post/2010/01/22/Controls-Do-Not-Make-You-More-Productive.aspx 

Fallacy: Web Forms is easier

(01:41p) <webformsdev> but i believe if you know how to use webforms, properly, you don't encounter that bullshit
(01:41p) <@mattman> no one knows how to use webforms properly
(01:42p) <@mattman> developers every day struggle with dynamic controls and databinding in even slightly-complex real-world scenarios. Mindlessly tweaking code and refreshing the page to see what ASP.NET will render.
(01:42p) <@mattman> Commenting and uncommenting out blocks of if(!Page.IsPostBack) logic, moving chunks of manipulation code from PreInit, to Init, to Load, to PreRender. All Trial and error, ad infinitum.
(01:42p) <@mattman> I've personally wasted more time on that than I ever care to admit

Fact: Web Forms is Black Magic

(01:43p) <@mattman> Here’s the thing, I hate black magic, I hate not knowing what's going on in my framework, especially when you get UpdatePanels involved, etc. Its an abstraction I just don't need. It doesn't make me faster, more productive, help other developers understand or maintain my code later, or help me understand how things are really working in case I need to dive in and debug. You just tweak it ‘til it works and then go home
(01:43p) <@mattman> MVC has none of that. It’s just HTTP, GETs and POSTs, with a pluggable model binding mechanism, pluggable validation, some scaffolding options if you want them, etc.

Fact: MVC enables robust AJAX support

(01:44p) <@mattman> With MVC the HTML is free to craft as you wish. This alone allows much, much better javascript/DOM interaction, needless to say with frameworks like jQuery. Without having to worry about posting __VIEWSTATE back or deal with the page lifecycle, TRUE partial page updates are a reality in a much more intuitive way. Not to mention entirely more efficient on both the client and the server when compared to UpdatePanels

Fact: MVC is closer to the metal

(01:44p) <webformsdev> mattman, then you must really like PHP too, minus the lack of IDE/framework
(01:45p) <@mattman> I have done plenty of PHP work. Which is why I was able to adapt to MVC quicker than most with a WebForms background. 50% of ASP.NET Web Forms developers have no idea what an HTTP POST is.
(01:45p) <@mattman> I liked the web side of PHP very much. I liked knowing at a glance WHY something was being rendered a certain way, even if it wasn’t entirely maintainable and a big mix of logic. I liked for loops to build my grids, with condition logic plainly visible to tweak a row based on some “data binding” logic

Fact: DataBinding is confusing, full of indirection and runtime logic

(01:46p) <@mattman> INSTEAD OF Repeaters with OnItemDataBound and runtime casting an e.Item.DataItem object, getting properties on that object state, and then using e.Item.FindControl to manipulate the data binding template --  with EVEN MORE most casting and runtime failures
(01:46p) <@mattman> ItemDataBound and the likes are completely counter-intuitive and cause developers to really hunt around looking for rendering logic in the template itself, the code-behind, etc

Fact: MVC lends itself to good design

(01:47p) <@mattman> Web Forms has is so tightly coupled at every layer it makes true separation of concerns almost impossible. The Page is instantiated by the runtime, making ground-up use of an IOC container inflexible, and a burden to say the least. WCSF from P&P helps with this, but having used it on a large project it was not nearly as useful as MVC has been.
(01:47p) <@mattman>The MVC designers recognized this and created the ControllerFactory class for us, so using IOC and a container can be seamlessly used from the start of the request pipeline. MVC is entirely extensible and pluggable at every stage.

Fact: Web Forms is miserable without JavaScript

(01:50p) <@mattman> How many ASP.NET developers test their pages without javascript? Take that a step further, how many of them are even aware that their precious <asp:LinkButton> won’t even work with JavaScript disabled? Will my GridView still sort without javascript? HINT: It won’t!
(01:50p) <@mattman> While this technically isn’t the fault of Web Forms at its core, it does happily guide developers down a path without even remotely presenting the repercussions of those decisions. Not many people fully appreciate that their simple use of an <asp:LinkButton> has now prevented all visitors without javascript from using the site correctly. Those same users can’t even go to the second page of a GridView.
(01:51p) <@mattman> MVC makes javascript use explicit. And in fact encourages the use of graceful degradation or progressive enhancement techniques. These ideas are becoming increasingly commonplace for modern web sites for a host of reasons.

Fact: MVC is testable

This wasn’t discussed in the conversation, but I will throw it in. MVC is testable, simple as that. Not many care about testing – in fact far fewer than I wish unfortunately. But it is becoming increasingly important in professional development shops. There have been tons of debates that I wish I had the logs for on this topic, ranging from people swearing that Web Forms is testable if you are careful, etc. But the fact of the matter is, people are not careful. We’ve all seen the reality of modern ASP.NET development, people don’t like to think about where their code goes – just put it in the simplest place that could work (code-behind), load the page, and call it a day. Regression bugs run rampant in many ASP.NET projects because it is so tightly coupled that changing a single user control by removing some if(!Page.IsPostBack) logic causes a huge cascade of failures in pages you never even heard of. MVC intuitively gives the Views so little power that it is actually more of chore to put some untestable logic into this “quick fix” than it is to do it the right way.

Fact: MVC allows multiple <form> tags

I will never forget the look on a friend’s face when I told him that ASP.NET forced developers to use one <form> per page. This friend was a classic ASP developer and has since moved on to other things, but the sheer notion of this limitation literally made his jaw drop. This is such a ridiculous constraint on Page developers that I can recall first moving to ASP.NET from PHP and having such a hard time getting my head around such an outrageous constraint. MVC takes developers back to the way the web was meant to be utilized. This single change offers so many benefits I am disappointed with myself that I left it so far down the list.

Summary

That about wraps up the 20-minute conversation. I will probably be amending this post in the future should any new areas for discussion come about. Comments are welcome!

 

Technorati Tags: ,,

I saw the following question asked earlier today -- the only context given was the code itself.

Can anyone tell me what’s wrong with this
Dim min As Integer = Integer.Parse(leavingTimeTextBox.Text.Substring(leavingTimeTextBox.Text.IndexOf(":") + 1, leavingTimeTextBox.Text.Length) -1 )?
it shows me an exception index out of range exception: length and index must be within the range of the string, parameter name: length 
so its five characters and on debug time : index is 2 so I'm starting from index 3 to length which is 5 -1 "4"

627226315_325aa7b527 It was clear that he looking to parse some sort of pre-defined time format, but just to be sure I confirmed it with him. While I could have helped this person resolve the question he asked about (the IndexOutOfRangeException), instead I took a step back to focus on what he really wanted to achieve. His immediate  problem was that he was too focused on the details – the how. He knew what he wanted: the hour, and the minute of the occurrence in a timestamp, but using SubString and IndexOf was not going to be the most robust solution to this problem.

Two immediate solutions came to mind:

var time1 = TimeSpan.Parse(leavingTimeTextBox.Text);
var time2 = DateTime.ParseExact(leaveTimeTextBox.Text, "HH:mm");

Without more context on his actual needs, the most useful solution is up to him, but at least this pointed him in the right direction.

The key take-away of this post is as follows:

Your problem is not unique. Someone has had this problem, and solved it before. More often than not, that very solution can be found in the .NET base class libraries. If something is painful (and I consider most code combining Substring and IndexOf to be painful), take a step back and think about what you’re really trying to achieve, instead of the exact means of achieving it.

LINQ is another prime example of this simple concept: focus on the what.

P.S.

I’ve paid closer attention to some of my favorite blogs (and magazine articles, and newspapers, etc) and noticed that they make good use of images to offset the text in their content. I don’t particularly care for this image or placement within this post, but it’s a work in progress!

 

Technorati Tags: ,

As a brief recap, the reason this post even exists is because the generated code from the EF4 designer does not properly suppress code analysis warnings. In that post, I mentioned that I would provide a proper T4 template and tutorial on integrating it into your EDMX model. This post details the steps to creating and customizing an Entity Framework 4 T4 template.

T4 (the Text Template Transformation Toolkit) is the code generation technology built into Visual Studio. Thankfully, the EF4 designer has been enhanced to support customizable templates so that developers are free to change the code that is generated for your ObjectContext and Entity classes.

To get started, I am assuming you already have an EDMX file that has been generated from your database.

Beta Note

These steps were written for Visual Studio 2010 Beta 2, so they may change slightly before RTM.

Step 1

Open the EDMX Designer, right-click on the design surface, and select “Add Code Generation Item…”

addcodegenitem 

Step 2

Select the “ADO.NET EntityObject Generator” from the Add New Item dialog

Note: The specific instructions below only work for the standard EntityObject Generator, and will not apply directly to the Self-Tracking Entities template. If you wish to use Self-Tracking entities, the instructions in this post should be sufficient to customize the template yourself.

image

Now you should have a new EfModel.tt file in your project. This is the T4 template that the EDMX designer will use to generate the classes that represent your EDMX model.

Step 3

Open the newly created EfModel.tt file.

From here, you can customize the template yourself (instructions are provided in Step 3b, or simply download the T4 template that I have provided in Step 3a)

 

Step 3a – Download the corrected template

  1. Open the T4 Template
  2. Overwrite all text in your .tt file with the text from the link above
  3. Change the token “YOUR_EDMX_FILE.edmx” to be the file name of you actual edmx file
  4. Proceed to step 4

 

Step 3b - Customize your template manually

To suppress code analysis, you need to decorate each class definition with a [GeneratedCode] attribute, as follows:

      [global::System.CodeDom.Compiler.GeneratedCode("EdmxTool", "1.0.0.0")]

You can use the standard Visual Studio Find dialog to find all instances where classes are being generated. In the Template that I am using (The one that shipped with Visual Studio 2010 Beta 2) there were 3 places to decorate the code.

  1. The ObjectContext class
  2. The Entity classes
  3. The ComplexType classes

Following is a snippet from my modified ObjectContext generation.

/// <summary>
/// <#=SummaryComment(container)#>
/// </summary><#=LongDescriptionCommentElement(container, region.CurrentIndentLevel)#>
[global::System.CodeDom.Compiler.GeneratedCode("EdmxTool", "1.0.0.0")]
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : ObjectContext

Repeat this process for the 3 remaining class definitions by using the standard Find… dialog. I found it easiest to search for the text “partial class”

Step 4

Open the EDMX designer and Ctrl+S to save it.

If all goes correctly, the T4 template should kick into action and a new .cs file should be created. This .cs file includes the actual generated code based on your EDMX model and your T4 template. As always with generated code don’t attempt to modify it directly, since the next time you (or someone else) saves the edmx file it will overwrite any changes you made.

Lastly, one final benefit of all of this is that you can make any changes in the T4 template to fully customize how your entities are generated from now on.

 

Technorati Tags: ,

Update

I have published the instructions and provided a template that can be used to properly suppress code analysis.

 

Starting a new project opens the doors for some great things. One of those things for me, was adherence to code analysis from the get-go. Visual Studio 2010 in particular has great Code Analysis Rule Set support allowing teams to carefully dictate which rules they wish to apply and suppress.

Unfortunately, it wasn’t long before the decision to use Entity Framework 4 put a nice little wrench in my code analysis plan. (As an aside, I will blog more about my decision to use EF4 at a later date -- but long story short, it had to do with the large legacy database that we would be working with).

Shortly after loading the existing database into the EDMX and compiling, I was greeted by nearly 1300 code analysis warnings, ranging from naming of properties to “members should be marked read-only”, etc, etc, etc. I assumed that surely this was either an oversight in the beta that would be corrected before release -- unfortunately, my hopes were not realized.

Microsoft Connect response to the issue: (emphasis mine)

The generated code can not follow all the fxcop guidelines because of other requirements( mainly around Serialization). The guidance here is to put GeneratedCode attribute on the members of the generated code so that FXCop does not flag these errors. In .Net 4.0( which is our next release and Beta 1 of which is available now), we moved to use T4 templates for code generation. So it will be easier to modify the templates that we ship so that these attributes are produced in the generated code. The reason we did not add these attributes in the templates we ship is because we did not want to clutter the templates.

Really? Clutter the templates? I normally try to give teams the benefit of the doubt regarding decisions they make, given that I naturally don’t have all the intell that went into the decision, but I simply cannot defend this one. What is especially upsetting to me is that the EF4 team has made great strides in making their designs and development open and transparent, specifically in taking community feedback to heart. This decision surely adds more fuel to the fire on why some members of the community suggest EF should be avoided by quality teams.

Needless to say, I am pretty disappointed with this decision.

In the next few days I plan on publishing a workaround using their T4 templates. I will provide the template and detailed instructions on how to take advantage of it if you plan on using EF4 anytime soon.

CropperCapture[3]

 

A very welcomed addition to the all-too-common File In Use dialog when trying to delete a file that a process has locked.

As you can see from the screenshot, the dialog in Windows 7 finally tells the user exactly which process is preventing the deletion. No longer do I need Process Monitor from SysInternals for such a simple need.

file-locked-dialog

 

Technorati Tags: