Tuesday, 6 December 2011

T4 template solves Linq-to-SQL and String or binary data would be truncated error.

Recently we developed a project using Linq-to-SQL, but we encountered an issue when trying to save data. SQL Server returned an error message “String or binary data would be truncated”. The error message simply means the string we try to insert into database is too long. 
We have a few options to fix the issue, but we created a T4 template that would automatically truncate the string if it is too long. Here is the code.

Sunday, 2 October 2011

Abusing TeamCity

JetBrains’ TeamCity is really a great product and it helps us a lot. In a recent project, we need to run a task and the task needs to

  • Create a report and FTP to a site every day
  • If it fails, then try again
  • If it fails, sends notification email to us

We have a few options to complete the task, such as Windows Service, Console Application with Windows Scheduler and Custom Application. But there is another option, that’s TeamCity! TeamCity has built in flexible scheduler, and it has a feature to re-run the test if it fails and it also can notify us when the test passed or failed. In the end, we created a test and the test is not a real test in this case, it simple create the report and FTP to the site. We just insert assert statement after each step. We then create a Build Configuration in TeamCity and ask it to run the test at a specified time every day. We also setup notification rule for the building configuration when it fails. That’s it! It works like a charm.

Thursday, 16 December 2010

Dive deep into ASP.NET MVC Razor view rendering process

Introduction
These few days I spent some time studied the inner rendering process of the new Razor view engine for ASP.NET MVC 3. I would like to share my finds with you here.

Background
ASP.NET MVC executing starts with MvcHandler.ProcessRequest() and it follows the following path if the controller is returning a ViewResult,

RazorView.RenderView() View rendering starts from ViewEngine specific view's RenderView() method. For Razor ViewEngine, that is RazorView's RenderView(). The following is the code.

It first casts the instance object to WebViewPage. The instance object is an instance of class compiled from our view code. Then it sets some properties, looks for StartPage (if it is a normal view, the RunViewStartPages is true, if it is a partial view, RunViewStartPages is false) and calls webViewPage.ExecutePageHierarchy(). ExecutePageHierarchy is defined in System.Web.WebPages.WebPageBase class and is not overridden by any sub classes. And there are two versions, one is virtual and without any parameter, while the other one is non-virtual and with a bunch of parameters.

Non Virtual WebPageBase.ExecutePageHierarchy()
RenderView() is calling the non-virtual one. The following is the code,


It first calls PushContext to save current context information, then checks whether there is a start page (defined by _ViewStart.cshtml file). If yes, then calls start page's ExecutePageHierarchy(), otherwise calls the ExecutePageHierarchy() virtual function. And finally calls PopContext() to clean up.

PushContext() and Preparation for Rendering


  1. It firstly saves parameter "writer" to _currentWriter and also the context information. The parameter "writer" is HttpContext.Response.Output object from ViewResultBase.ExecuteResult()
  2. It then creates a TextWriter (_tempWriter) object and pushes it to the OutputStack.
  3. It then pushes a new Dictionary object to SectionWritersStack
  4. It then assigns the BodyAction to _body variable if it is not null

We need to pay particular attention to the step 2 & 3. OutputStack is defined in PageContext, it is a stack of TextWriter


If you check Write() and WriteLiteral() methods defined in WebPageBase, you will notice that they all write to Output object which is the top object from OutputStack. So the purpose of the step2 is to write all contents to _tempWriter, not to the "writer" parameter. This is because if the view has a Layout, it needs to "fit" the content into Layout.

Next, SectionWritersStack is also defined in PageContext, and it is a stack of Dictionary of SectionWriter,


In Razor View Engine, you can create different sections in Layout page, for example,

@DefineSection("header" required:false)

And in corresponding view,

@section header {
This is content for section header
}

Razor view rendering process starts from the View first, then the Layout. SectionWritersStack is used to track sections and their corresponding content defined in View. For the example above, the SectionWriterStack will contain a dictionary object with one element (key = "header" and the corresponding content = "
This is content for section header
").

ExecutePageHierarchy() virtual function and View rendering


This function is very simple. If you ignore the first bit relating to falcon debugging, it is only a call to Execute(). Now is the fun part, Execute() is defined in System.Web.WebPages.WebPageExecutingBase class, but it is never overridden in MVC framework, in fact, it is written by us (developers), that is the view file (cshtml). ASP.NET runtime will compile our view code into a class. If you go to C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\ folder, you will be able to see code generated by ASP.NET runtime.

PopContext() and Layout Rendering
Ok, so it executed our code, next is the PopContext().


  1. It first reads the content from _tempWriter, when executing Execute() method, our View writes to _tempWriter.
  2. Then it checks whether the View has a Layout
  3. If yes, it pushes _currentWriter to OutputStack. So all Layout content will be rendered to _currentWriter. And it then calls RenderSurronding() to render the Layout, one of its parameter is the a delegate to write current View's content to a TextWriter. Layout rendering process is exact same as View's rendering process. View file and Layout file are inheriting from the same base class System.Web.UI.WebPageBase<T>.
  4. If no, it simply writes the View's content to _currentWriter.
  5. It calls VerifyRenderedBodyOrSections() to make sure
    1. RenderBody() is called
    2. If a section is required in Layout (@RenderSection("sectionName", required:true)), it makes sure that there is a corresponding section defined in View (@section SectionName { })
    3. If a section is defined by view(@section sectionName { }), it makes sure that the section name is rendered in Layout.
    If any of the above criteria is not met, it will throw an Exception.
  6. Balance SectionWritersStack and WebPageContextStack.

Summary
To recap, the following is the method executing sequence

Tuesday, 30 November 2010

@Html.RenderAction caused StackOverflowException

Background

_Layout.cshtml file uses @Html.RenderAction(“Menu”, “Nav”) to render the menu.


And the NavController has the following code

By doing so, we can generate menu dynamically. But the above code throws an exception: StackOverflowException, the code is working perfectly using WebFormViewEngine, but is not working for RazorViewEngine.

Cause

The cause of the above exception is the newly introduced "_ViewStart.cshtml" file. The code inside "_ViewStart.cshtml" will run before rendering any view, and currently the content of _ViewStart.cshtml is very simple,

It just set the current layout. As NavController's Menu() action simply returns View(), it causes "_ViewStart.cshtml" to kick in, which in turn renders _Layout.cshtml again, which call Html.RenderAction("Menu", "Nav") again, thus causes infinite loop and eventually throws StackOverflowException.

Fix

The fix to the above error is very simple, just change the NavController's Menu() action as follows will fix the issue, because PartialView() will not execute "_ViewStart.cshtml" file, hence avoids the infinite loop.

Wednesday, 10 November 2010

ASP.NET MVC3 Release Candidate

Today, ASP.NET team just announced the ASP.NET MVC 3 Release Candidate, you can download it from Microsoft download center.

It includes a bunch of new features and makes ASP.NET MVC development much easier. The main change compare to Beta version is the Razor Intellisense within Visual Studio. The RC support colorization and intellisense for the new Razor view engine. Intellisense works with HTML, C#, VB, Javascript and CSS. 

Thursday, 21 October 2010

Windows Live Writer

Just installed Windows Live Writer on my machine and I am so excited to test it out. The Writer makes creating blog post so easy!

You can download it from the following site
http://windowslivewriter.spaces.live.com/

Enjoy!

Wednesday, 6 October 2010

Applying Generic Repository and Unit of Work Pattern to Entity Framework

There is a very good article (Testability and Entity Framework 4.0) talking about the Repository and Unit of Work pattern and how we can do that using Entity Framework. However, I don't like the way the IRepository and IUnitOfWork were designed. Firstly the IRepository interface has too many unnecessary methods and some are based on assumption, for example FindById(int id), what if an entity uses GUID as primary key? Also the FindAll() and FindBy() methods are returning IEnumerable which will cause the lambda expression to be evaluated when returned from these methods. Secondly the IUnitOfWork has reference to all repositories, what if we add a new repository, do we have to update the IUnitOfWork interface? I think this is a bad design.

I have re-structured the IRepository and IUnitOfWork interfaces as follows,




The IRepository interface will have Add(), Delete() and Attach() method to track entities, it also has a readonly reference to IUnitOfWork to Commit(), and there is another readonly properties "Entities" which is of type IQueryable, so that it can be queried using LINQ. We don't really need methods like FindById() defined in the interface as they be easily added using extension methods.

Two concrete implementation for Entity Framework,


Using the EFRepository and EFUnitOfWork in MVC



To save a new event,


Simple and elegant.