Showing posts with label asp.net. Show all posts
Showing posts with label asp.net. Show all posts

Thursday, July 31, 2014

How to generate strongly typed C# client for ASP.NET Web API

Recently, I was looking out for ways to consume the ASP.NET Web API via strongly typed C# client (i.e. a client similar to C# Web Service Client).

Initially I thought, Microsoft would have a utility to generate the client but, I was wrong, they don't have any such utility.  Why would they not provide such a utility is beyond me, I really don't understand why would they not expose such a utility, it would have benefited everyone who wants to consume Web API using strongly typed classes.

None the less, After a bit of googling, I found this awesome open-source project which does exactly what I needed.

The detailed instruction on how to use it can be found here.  In summary you need to do the following steps to generate the strongly typed C# client for ASP.NET Web API


How do they do it!

Setting up the Server
  • Install the NuGet package "WebApiProxy" into the project that hosts the Web API.  This package will host a proxy endpoint for your service.  This proxy endpoint can be used as the JavaScript client to invoke the Web API via JavaScript.  The endpoint will be hosted at URL "/api/proxies"
  • Once you have this installed in your Web API, if you browse the URL "/api/proxies" you should see a JavaScript client already generated!
  • This package also exposes the metadata necessary to automatically generate the C# client.
Creating the client
  • Create a Client project which will be used to invoke the Web API via C#.
  • Install the NuGet package "WebApiProxy.CSharp" into this project.  This package seamlessly integrates the proxy generation build task with the project build step.  
  • Every time you rebuild the project it will try and generate the C# client for the desired Web API.
  • The configuration required to generate the C# client is placed in a file called "WebApiProxy.config"
  • This is the simplest XML file I have ever seen.  It only expects you to provide the 
    • endpoint - The location of the Web API where it will be hosted.
    • namespace - The namespace in which the C# client will be generated.
  • That's about all the setup that is needed to generate the strongly typed C# client for a given Web API
Example
  • Imagine you have an EmployeeController on the Service side. 
  • We can invoke this Web API via our generated client as follows
  • As you can see its very straightforward and intuitive to invoke the Web API with strongly typed C# client.
Further Reading
  •  I went ahead and modified the source code to generate not just the Async method but also the Sync version of the Web API.  
  • This is done so that anyone who wants to invoke the Web API in a Sync manner does not have to deal with the Async behaviour.
  • The above code for Sync invocation can be reduced to the following
  • Updated source can be found here
  • TIP: In case if you are trying to modify the source to suite your needs, make sure that you kill the MSBuild process before you rebuild the Task and the Client.
Thats all folks!  

Wednesday, September 21, 2011

Strongly typed Session with MVC3 and Spring.NET - Part - 1

In every Web project I have worked so far, always there is a need to store some or the other information in HTTP Session.

I am very finicky about putting things in the HTTP Session.  IMHO HTTP Session should be kept as light as possible.  There should be a very very strong and compelling reason to put a certain value in the HTTP Session.  Having said that, I do agree that there are times when we want to put certain information in the HTTP Session like user name, user id, etc.

With me so far?  Till now we understand that, we do not like to put things in HTTP Session, however, we understand that there is a definite need to put certain things in HTTP Session for the app to work correctly.

Question is, Is there an alternate to putting things in HTTP Session?

In this series of three posts we will try to answer this question.  We will try to use MVC3 and Spring.NET to eliminate the need of putting stuff in HTTP Session.

But wait a minute, let's first answer this question,

Why is putting things in HTTP Session is such a bad idea?  

Lets start by looking at the code that will put UserName into the HTTP Session.
Does it remind you of code that you have seen in one of your applicatoin? It certainly reminds me of code that is used all over the place in one of the projects that I had worked.

I totally hate to see code like this.  Why whats wrong with such code?

Session is used like a Hash Table:

In our example, key of the hash table would be UserName and value will be Git Shah.  Imagine while putting/retrieving values to/from the HTTP Session, if incorrect keys are used, results could be catastrophic.  Even a small typo like one shown in the example below would yield incorrect results
Ofcourse there are ways to get around this problem. Simplest of them is to use a Static Class that holds all the keys as constants.

However, you can still not gaurentee that every programmer on your team will always always use constant keys from the static class.  Believe me, because of human error or some other unexplainable reason, someone would use hardcoded inline key to put value in the Session and rest of the team will curse him/her for eternity! 

Session values are not strongly typed:

We have inserted a string value Git Shah in the HTTP Session against the key UserName but when we want to retrieve the value from the session we will have to typecast to its correct type.  In our example to retrieve the value of UserName key in HTTP Session code would look like
I have a name for code like that, I call it A Time Bomb!

Its just a matter of time before which you start getting a class cast exception.

Dude, whats in my Session? Where are these values used?

Can we say for sure what all values are stored in our session?  

Another important question to answer is, Can we say for sure, from what all places in the code are these values accessed?

These are a very important questions.  Answers to these questions are absolutely vital for the health of your application.

In one of the projects that I had worked, we were extremely confused for a very long period of time.  The question that was bothering us was, who was setting a specific value in the session and in what condition?

Consider an example

UserName key is populated in the LoginController.Login method. Lets look at another place where UserName is used.
AccoutController.UpdateUser updates the value of the UserName key in the HTTP Session to the new value passed as argument and AccountController.GetUserDetails method fetches the value of the UserName key from the HTTP Session and sets the ViewBag.UserName property.

As you can see in our simplistic example UserName key of the HTTP Session is used at three places.  In real life, it would be used in many more places than this.  The code that accesses the UserName key from the HTTP Session would be littered all over the place!

How will we find the exact places where UserName key is populated/fetched into/from the HTTP Session?

There is no easy way to find the exact places where UserName key of the HTTP Session is used.  We can extract a constant for the UserName and then search for its usages, but still this is not a full proof way, as I mentioned earlier, there are many fools out there who will not bother to use the constant and use an Hardcoded string key instead.

These are few of the problems that are a big concern to me.  Question to be answered is,
  • How can we avoid such code?  
  • How can we achieve an alternate option that will discourage people from writing such code?
Before we dig deeper into the solution, lets first focus on some of the design goals that this new solution should have.
  • Things that we put into and fetch from the session should be strongly typed objects.  There should not be any cast of any sort.  This will avoid Time Bomb like code.
  • Session should not be used as a Hash Table.  Whatever we put into the session should become a property of the session which can be accessed from anywhere in the code.  Moreover, because it becomes a property of the HTTP Session, we would get all sorts of intelli-sense on it.  There is no chance of any typo in this case.  For e.g. the existing code
Should no longer be required instead we should have code that looks like
  • At any point in time, it should be easy enough to find the exact places where a certain property of HTTP Session is used. In some ways this point is related to the previous point. If we are able to convert Keys of session into strongly typed Properties then we can just search for the usages of those properties and we know exactly where those properties were used!
Enough goals to start with.  Question is, Can these goals be implemented in real life? 

Well, the good news is, these goals are definitely implementable.  In fact its not too difficult to implement these goals when we use Spring.NET with MVC3. 


What is the bad news?  You will have to wait for my next posts to see how exactly we could implement these goals :)

Stay tuned folks in the next couple of posts we are going to have some fun with HTTP Session Management!

Saturday, August 6, 2011

Asp.Net MVC3 and Asp.Net Web Forms Side-By-Side in One Project - With Razor Views

In The previous post, I explained how we could use MVC3 and Asp.Net Web Forms Side-By-Side in One Project.  In that post, we were rendering MVC3 pages using the ASPX View Engine.  ASPX View Engine is the legacy view engine, Razor View Engine has significant advantages over the ASPX View Engine.  In this post we will see how we could use the Razor View Engine instead of the ASPX View Engine. 

The Asp.Net MVC 3 has always supported the concept of view engines – which are the pluggable modules that implement different template syntax options.  Razor view engine is optimized around HTML generation using a code-focused templating approach.

Why Razor View engine?

Razor View engine is build with the following design goals (read the detail design goals here)
  • Compact, Expressive, and Fluid: Razor minimizes the number of characters and keystrokes required in a file, and enables a fast, fluid coding workflow. Unlike most template syntax's, you do not need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is smart enough to infer this from your code. This enables a really compact and expressive syntax which is clean, fast and fun to type.
  • Easy to Learn: Razor is easy to learn and enables you to quickly be productive. You use all your existing language and HTML skills.
  • Is not a new language: Razor enables developers to use their existing C#/VB (or other) language skills and deliver a template markup syntax that enables an awesome HTML construction workflow with language of our choice.
  • Works with any Text Editor: Razor doesn’t require a specific tool and enables you to be productive in any plain old text editor (notepad works great).  That said, I have to mention this, Resharper 6.0 has one of the best support for Razor Syntax.  Its a paid tool but its definitely worth the price.
  • Has great Intellisense: While Razor has been designed to not require a specific tool or code editor, it will have awesome statement completion support within Visual Studio.
  • Unit Testable: This is one of the most important Design Goal.  Razor implementation supports the ability to unit test views (without requiring a controller or web-server and can be hosted in any unit test project – no special app-domain required).
If you want to see a detailed reasoning of why Razor is better then ASPX View Engine, I strongly recommend vising this link

Now that we are convinced that, Razor View Engine is better than ASPX View Engine, lets integrate the Razor views in our Asp.Net Web Forms application with MVC3 integrated in it.

How Do they do it?

Initially, I though there must be setting somewhere in the project properties which will enable us to use the Razor View Engine, however, after several wasteful minutes of searching and researching in the project properties I found that, there is no such setting, we can directly go ahead and create the Razor view in the project.

Razor views have an extension of cshtml.  Lets create our first Razor view called RazorIndex.cshtml right next to the Index.aspx that we had created in the previous post.  This view will have nothing special, it will display one message that we set in the ViewBag.

Notice that we are displaying the UserName from the ViewBag.  Notice that, in the new Razor syntax, we have to use the @ sign to access any objects and properties.

Let's add one more method in our HomeController which will render the RazorIndex view and set the UserName in the ViewBag.  The controller code will look no different from how it looked for rendering ASPX pages.

This is a very good example of showing, how well the Seperation of Concerns Design Pattern has been implemented in MVC3.  Even though we want to use a different View Engine, controller code remains unchanged.  In fact, Controller has no idea about which View Engine will be used to render the view.  This is an excellent example of why things should be loosely coupled to achieve modular and clean code!

Before we can see if our Razor view is rendered correctly or not let's not forget to add one more route to our routes collection in Global.asax.cs file

We have just added one route called RazorHome. All set! Lets build the project and access the URL /home/razorindex and see whats the outcome.
First attempt to render Razor View results in an compilation error
OK does not look too good.  The error states that The type or namespace name 'Helpers' does not exist in the namespace 'System.Web'  To fix this we will have to do a change in the web.config.  We will need to add a few assemblies in the  <system.web><compilation> section.  The updated web.config would look like

After this lets build and access the URL /home/razorindex and les see what happens
Second attempt at rendering the Razor view also results in compilation error, this time it cribs for ViewBag
Still not quite there, but getting closer.  This time the error says that The name 'ViewBag' does not exist in the current context.  The problem is that the compiled class RazorIndex_cshtml is extending System.Web.WebPages.WebPage class.  As we had seen in the previous post, MVC views needs to extend from System.Web.Mvc.WebViewPage and not System.Web.WebPages.WebPage. 

How do we fix this issue?

We need to some how tell the framework that the Razor pages should extend System.Web.Mvc.WebViewPage class.  This is done by adding another web.config in the Views directory.  The project structure would now look like this
Project Structure with two web.config's
The content of this new web.config should look like

The element <pages pageBaseType="System.Web.Mvc.WebViewPage"> tells that, the Razor views will have base class of System.Web.Mvc.WebViewPage.

Lets Rebuild the app and browse the URL /home/razorindex and see what happens.
Success! Razor view renders correctly
Bingo!  We have an Asp.Net Web Forms application with MVC3 Razor views integrated in it!

PS: Now you have no reason to not move to ASP.NET MVC3 from Web Forms, we have proved that MVC3 can co-exist with a Web Forms in the same project!

Sunday, July 31, 2011

Asp.Net MVC3 and Asp.Net Web Forms Side-By-Side in One Project.

You must have known from my previous post that, we have moved to MVC3 instead of the Web Forms approach.

While I was suggesting the clients to adopt the new MVC3 framework, the obvious question from their side was, Can the Web Forms and MVC3 co-exist?  Can the new MVC code reside in the Web Forms project?

I Googled a little, found that it was very much possible, however we needed to spike it out to be completely sure.  After some trial and errors, we were able to make the Web Forms and MVC3 code co-exist in one project.  The entire process was not very straight forward hence, I decided to write a post on how to do it.

Let's first create a bare bone ASP.NET Web Forms application.  This can be done by using the Create New Project Wizard of the Visual Studio 2010

Create new Asp.Net Web Forms Project

The Wizard generates the web.config file, master page and two pages About.aspx and Default.aspx.  Running the app at this stage should open up a page like this

Asp.Net Web Forms Default Page

Now we have an asp.net web forms application up and running.  Lets try and add the MVC3 code in the existing project and lets get it running.  This would effectively prove that Web Forms and MVC3 can co-exist.

Integrating MVC3 into the Web Forms application - How Do They Do It!

MVC3 is build on Convention Over Configuration.  Controllers in MVC3 are put in a special directory called Controllers, the views go into the Views directory.  Lets create these two directories at the root level.

Adding Directories Controllers and View

Let's add a very simple controller class called HomeController to the project.  All MVC3 Controllers need to extend the System.Web.Mvc.Controller class.  To do this, you will need to add the reference of the System.Web.Mvc.dll into the project.

Lets look at the code that goes into the HomeController

The HomeController has a very simple Index Action method.  This Index action is simply going to render the Index view.  The Action method also adds a property to the ViewBag called UserName.  We will use the UserName Property in the view.

The Index view needs to be created.  Let's create a file called Index.aspx in the Views/Home/ directory.  The Index.aspx file looks like

Notice that, the aspx page inherits the class System.Web.Mvc.ViewPage and not System.Web.Page. All MVC3 views must extend the ViewPage class.

Also Notice, how we are showing the UserName from the ViewBag using the <%= %> Syntax.  Unlike traditional ASPX pages there is no code behind for this ASPX file.  

Curious thing about Index.aspx file is that, it does not inherit from the HomeController class.  Then how can the view access the ViewBag property UserName which was set in the Controller? 

Well, the MVC3 framework implements Separation of Concerns between the View and the Controller.  But it surely needs to pass information between the Controller and View, ViewBag is just one way of doing this.  Whatever we set in the ViewBag from the Controller is available in the Views!  This is just one of the way in which you can pass information between Controller and View.

The project structure at this stage looks like

Project Structure after adding the HomeController and Index.aspx page

At this stage, if we could open up the URL http://<host name>:<port>/<your application name>/home/index then we can be sure that we have successfully integrated MVC3 in a Web Forms Project.  Lets try and browse the URL and see what we get.

404 Error When we try to browse /home/index URL

We get a The resource cannot be found (404) error.  

Why?  

This is because, we have not yet informed the framework that, when someone hits the URL /home/index then how should it be served.  This can be done by registering a new route in the Global.ascx.cs file.

This file has an Application_Start method.  This method is called when the application is started.  In this method we have to inform the framework that, when someone sends a request for the URL /home/index then, route that URL to the HomeController.  This is done using the following code

The complete code of Global.ascx.cs file looks like

Lets run the application and browse the URL /home/index lets see what happens now?

Parser Error - Could not load type 'System.Web.ViewPage'
Nope, not there yet.

Turns out that for the page to get compiled and render correctly we need to add the System.Web.Mvc in the system.web/compilation/assemblies section in the web.config. The updated web.config looks like 

The only change here was to add the assembly System.Web.Mvc to the list of assemblies under the compilation section. This will make sure that this assembly is available to the aspx view when its compiled.

After making this change lets run the app and browse the URL /home/index and lets see what happens.

Index.aspx is rendered Successfully using MVC3

Success!  We are able to render the page using MVC3 in a Web Forms application!

Notice that, currently we are using the aspx rendering engine for rending MVC3 views, in the next post I will explain how we could take advantage of the new Razor Rendering Engine in a Web Forms application.

Sunday, July 17, 2011

Asp.Net MVC vs Asp.Net Web Forms

We were working on this project which was build using C#, .Net 4.0 and Asp.NET Web Forms.

I come from a Java background where MVC pattern has been around since ever.  There are tons of Java based web frameworks out there that implement the MVC pattern.  It looked quite surprising to me that, till very recently there was no equivalent of MVC pattern in the .Net world.  But, recently the things have changed, Microsoft has come up with its own implementation of the MVC pattern called Asp.NET MVC3.

I certainly like the MVC approach over the Web Forms approach for multiple reasons, I had to present these reasons to the client and convince them to move to Asp.Net MVC3 instead of the current Asp.Net Web Forms approach.  Finally, after quite some talking and presenting and discussions we managed to convenience the client to adaopt the Asp.Net MVC 3 approach over the Web Forms approach.

This blog post highlights the points why I think, MVC makes a better choice as the presentation framework over Web Forms.

Separation of Concerns (SoC) And Single Responsibility Principle

If you ask me, what are the two most important principles which helps in keeping the code clean, modular, readable and maintainable?

My Answer would be, Separation of Concerns (SoC) and Single Responsibility Principle. 

Its extremely important that every class in the system has a well defined job for itself.  No class should try and do too many things, in fact it should do only *one* thing and do it well (Single Responsibility Principle).  If one class tries to do too many things, then the code of the class would be messy, difficult to understand and maintain.

The code behind classes of the Web Forms approach are victim of this problem.  Lot of times, I have seen the code behind classes are bloated and are longer than 2000 lines.  Such classes are difficult to maintain and understand.  The code looks convoluted.

Why does this happen?  

Because, code behind classes have lots of responsibility.  They deal with
  • Showing the view
  • Dynamically rendering JavaScript
  • Updating the model
  • Validating the values entered by the user
  • Implementing some business logic
  • Making a call to the service
  • Differentiate the Post and Get requests etc.  
End result is a truly complex and gumped up code behind.
MVC on the other hand, implements these principle very well.
  • Controller classes are only responsible to update the model, decided which view to render and that's about it.
  • Views only responsibility is to use the model to render itself.  
  • Model just holds the business realted information.  
End result of all this is clean, modular, readable and maintainable code.

MVC gives full control over the rendered HTML

In the Web Forms approach, we were using third part controls called Telerik controls.  At times its really difficult to control the HTML that gets rendered from these controls.  Many times the HTML that is rendered is more complex than what would be required.  Because of this, designers find it difficult to style it the way they want it.

With MVC, you get full control of the exact HTML that gets rendered.  This is an absolute boon for the designers and developers

Unit Testing

I don't want to talk about how difficult it is to unit-test web forms code behind classes.  The web form code behind classes are tightly coupled with things like Session, ViewState Request, Response etc.  This makes them extremely bad candidates for unit testing.  To unit test web forms code behind classes one needs a very strong will and extremely good mocking and Unit testing skills.

On the other hand, MVC has been build with Unit Testing in mind.  One can easily do Test Driven Development with MVC controllers.  Controllers are not coupled with Session or Request or Response object which makes them easily unit testable.

Search Engine Optimizations and RESTful URL's

Web Forms application URL's end with .aspx extension.  They represent a physical file in the file system.  The MVC URL's do not have any extensions.  They do not logically map to a file on the file system.  Instead they map to a controller and an action method inside the controller.  The URL of MVC application look like
  • http://localhost:8080/appname/customer/create
  • http://localhost:8080/appname/customer/1
  • http://localhost:8080/appname/customer/list
  • http://localhost:8080/appname/customer/edit
Integration with Third Party JavaScript libraries

Its difficult to integrate the web forms application seamlessly with a JavaScript library.  For e.g. If you wanted to do Ajax with jQuery in a web forms application, imagine how much code you will have to write.  How will you render the dynamic HTML in this case.  How will you preserve the view state?  Its all very messy.

With MVC, we do not have a problem like this ever.  By default, MVC application comes integrated with jQuery.  However, you could go ahead and integrate any other JavaScript library of your choice.  Since view is not tightly coupled with controller integrating any JavaScript library is extremely easy.

No IsPostBack

I think there is no Asp.Net application in the world that does not have code which looks like

One class/method to handle both the get and post requests. At every step we have to decide whether its a get request or a post request and change the business processing.

This is infrastructure code. We should not be bothering about checking whether the request is a get request or a post request. Framework should do this for me.

With MVC, we do not have to keep checking whether its a get request or a post request.  We can simply put an attribute to a method marking it only accessible via the GET request or only accessible via the POST requests.  With MVC the above code would look like

Notice that we simply have to mark which methods are invokable over which protocol using either the HttpGet or HttpPost attributes. End result, simplified and easy to understand code.

No View State 

Web Forms provides a wrapper over the stateless HTTP protocol to make it state-full.  It achieves this by adding a hidden field called __VIEWSTATE__ to the rendered page.  If not handled correctly and especially when you are using some third party control library like Telerik controls ViewState can easily get out of hands.  I have see pages that have ViewState that goes in MB's.  This ViewState will be sent/received to/from the server for every Post requests.  Its sent/received to/from the server even when you do a Ajax request.  The performance of such pages goes for a toss!

MVC has no concept of ViewState.  MVC does not add a wrapper over the stateless HTTP Protocol.  In fact it harnesses the HTTP protocol.  Hence, MVC pages are much faster and they can easily out perform the Web Forms counter parts on any day. 


These are some of the points why I think, MVC is definitely a better choice over Web Forms for building Customer Facing, fast Web 2.0 applications.  

This list is by not means an extensive comparision of Web Forms vs the MVC appraoches.  Just some little peaces which I though were really important.

We have made our choice to move to MVC, have you?

Saturday, May 28, 2011

How to build the web project on the CI server without Visual Studio 2010

On one of the ASP.Net project, we were using Visual Studio 2010 IDE and MSBuild, to compile and build the application.  Pretty standard setup for a web project right?.  On developer machine all worked very smoothly, since each developer had Visual Studio 2010 installed locally on their machines.

We setup a continuous integration (CI) server Jenkins (formally Hudson) for this project.  Naturally, we didn't wanted to install Visual Studio 2010 on the CI server.  But we still wanted to build our app on the CI server.  Hence, we installed Microsoft Windows SDK 7.1 and all its components on the CI server.  After installing the SDK, we were able to build all projects except the web project on the CI server.

The error that we were getting was

Obviously, since the Visual Studio 2010 was not installed on the CI server, the path mentioned in the error didn't exist and that's why the web project was not able to build.

I opened the csproj file in Notepad++, to find the reference of "Microsoft.WebApplication.targets".  I found a reference of "Microsoft.WebApplication.targets" in the csproj which looked liked 

Indeed the web csproj file had an import statement, which added the reference to "Microsoft.WebApplication.targets". But I was not sure why this reference was needed in the first place.

My first attempt at fixing the CI server:

I removed the reference of "Microsoft.WebApplication.targets" from the web csproj file and tried building the application using MSBuild.  To my surprise, the app build fine, it ran all the tests without any issue.  My confidence grew a little, I thought I had the solution.  I thought the reference was added to the csproj by Visual Studio 2010, but was never used.

I committed the fix, build went green on the CI Server as well!

After a few hours, some developers complained that, when they now open up the web project, Visual Studio 2010 prompted for converting the project into a Visual Studio 2010.  Certainly, this behaviour was triggered after I removed the import statement from the web csproj file.

Its pretty clear now, why the import was required.  Visual Studio 2010 identifies that, the project is a Visual Studio 2010 Web project using the import of "Microsoft.WebApplication.targets".  Hence, although the build run's fine using MSbuild on developer machine as well as on CI server this is not the right fix!

My second attempt at fixing the CI server:

Googling a little I found that, there are only two options to fix this particular issue.
  • Install Visual Studio 2010 on the CI server
  • Copy the "Microsoft.WebApplication.targets" file manually from any developer machine to the CI server
It was sad to see that there was no standalone installer that installed the "Microsoft.WebApplication.targets" at the desired location.  We had to either install the full Visual Studio 2010 or copy the file manually.


I decided to chose the lesser evil of the two.  We copied the file "Microsoft.WebApplication.targets" from my machine (located at path C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications on a Windows 7 64 Bit installation) onto the CI server (at the path C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications.  CI server has Windows 2003 OS installed on it.) and then ran the build.  Yep! It worked!  The build went green on the CI server.

I know, its just an hack, but for now I had no other option!

Saturday, April 30, 2011

How to fix the “circular file references are not allowed” Error in ASP.Net


On one of my .Net projects, I came across an interesting issue.  I wasted couple of hours fixing it.  Hence, I decided to share my findings, so that others do not have to waste their time fixing the same issue. 

The issue

The issue was pretty simple, the app would not build.  The error that I was getting while building a ASP.Net web project using MSBuild was:

Of course the error said there is some sort of circular reference in my code.  I looked around to check and recheck, if I have created a circular reference by mistake.  However, if there was any circular reference, the code would not compile.  Code was compiling fine but it was failing when we ran aspnet_compiler.exe.


The ASP.Net Compilation tool (aspnet_compiler.exe) enables you to compile an ASP.Net Web application, this helps application performance because end users do not encounter a delay on the first request to the application.

I checked again, but certainly there was no code related circular dependency then why the aspnet_compiler.exe was complaining about the circular file references?

The Explanation

Googling a little, I found that, by default, in a Website Project, ASP.Net creates one DLL per folder. Hence, if you have the following setup:
  • User control ucA.ascx is present in the directory "A".  ucA.ascx refers another user control ucB.ascx
  • User control ucB.ascx is present in the directory "B".  ucB.ascx refers another user control ucC.ascx
  • User control ucC.ascx is present in the directory "A".
The folder A's DLL will reference the folder B's DLL, which will again reference the folder A's DLL, causing a "circular file reference".

This is the reason why the aspnet_compiler.exe fails with the "circular file reference" error.

The Fix

There are two ways this issue could be fixed
  • Rearrange the user controls (or MasterPages) to remove the circular references.  Usually this means moving the user controls in separate directories.  In our example, moving ucC.ascx to a new directory "C" (Preferred Solution).
  • Use batch=”false” in the compilation tag of the web.config file.  This will cause a new DLL to be created for each control/page in the site. This should fix the error but is really lousy for performance, so it should be avoided.
I moved the ucC.ascx in a different directory and yes the error went away!

Wednesday, March 9, 2011

31 reasons to hate IE. Styles not loading up?

Recently, I have been facing quite a few issues with IE.  And believe me all of them are really weird.  My hatred for IE is at all time high :)

I mentioned about a bug in IE8’s Lookahead Downloader in one of my previous post.  This post is dedicated to another such bug in IE.

What was the issue we were facing?

The problem we were facing was weird.  A page would render correctly on all browsers except IE (of course :)).

Yea, I know, nothing new about such behavior right?  But this issue is special in many ways.  Why?

Because:

I have decided to stay away from Telerik controls as much as possible.  If you asked me, I would only suggest to never ever, never ever, never ever, use them in your project.  The more I use them, more I get convinced not to use them ever.  

Why I hate Telerik controls so much?  

May be I will write that in a separate post.  

Why are we using it in our project?  

Client is not yet ready to move on.  

Anyways, Let me stop bitching about Telerik controls and focus on the issue we were facing.

The frameworks that we were using, assure that the site renders correctly on most modern browsers including IE.  Then why would it not render correctly on IE?

What were the rendering issues we were facing?

List box does not have proper styles
Alert box does not have proper style
Menu bar is unaligned and does not have proper styles

Look at the things highlighted in red in the above screenshot.

The issues we were facing were:
  • Sometimes List Box would lose its styles
  • Sometimes Alert box would lose its styles
  • Sometimes Tab Strip would lose its styles

Initially, I was really confused, didn't know what exactly was going on.  

Decided to intercept the HTTP traffic using Fiddler, to find out what is wrong with IE.  Why is it not sending requests for certain styles?

Found out that, IE does send requests for all style sheets.  But, IE just prefers to ignore a few style sheets (of course without showing any error)!  Typical IE, isn't it?

Googling a little we found that:
  • IE will load only the first 31 style sheets and will ignore the rest of the styles for a page request. This includes the <style> attribute tag as well if defined on the page
  • IE load only 4095 CSS selectors for a single request
  • On pages that uses the @import rule to continuously import external style sheets that import other style sheets, style sheets that are more than three levels deep are ignored.

Have a look at this link for more details.

That was it, we discovered another hidden treasure of IE!  Don’t we love IE for such hidden treasures?

The solution was simple enough, we removed few unused CSS references from the page.  Bingo, the page started working!

PS:  Why where unused CSS referred on the page?  Long story.  We will keep that for some other post.  Till then keep having fun with IE.

Have some Fun!