14 February 2010

Some SharePoint 2010 Articles

Few months ago I have installed the beta version of the SharePoint 2010. The product looks really cool, although some of the requirements like: “must have Windows 2008 64bit” are really annoying.

In the past few weeks I have published some articles in one new site dedicated to SharePoint technologies called SharepointMonitor.com. If somebody is interested, here is the list:

I have plans for several other articles, so stay tuned. I will update this post when something new comes out.

17 January 2010

NHibernate: Display executed SQL at the bottom of an ASP.NET page (MVC or WebForms)

Almost every modern application that uses relational database is build on top of ORM tool. The ORM tools can significantly decrease the efforts for interacting with the database, but unfortunately most of the developers are not familiar with the SQL code that is produced by the ORM tools. I’m not hiding that my favorite ORM is NHibernate. I’m using it since early beta, but from time to time even I’m surprised by the produced SQL. So, you need to monitor closely what SQL is executed. This blog post will describe one not widely used but very useful approach – the executed SQL will be displayed as a footer on any ASP.NET web page. It does not matter if the web page is using MVC or WebForms. Interested? Then continue reading.

Currently, there are several ways to display the SQL produced by NHibernate:

  • Database profiler tool – some of the modern RDBMS systems are coming with a profiler tool that can hook to the database engine and display the executed SQL. For example SQL Server comes with SQL Server Profiler. Unfortunately the SQL Server Express edition is missing this tool.
  • NHibernate Profiler – this is a third party tool that hooks to your application and monitors the NHibernate. Comes with cool WPF UI interface and lots of other features. Unfortunately at the time of writing you will need to purchase a license to use it. As well you will need to switch from your application to the tool after each action to monitor the produced SQL.
  • Log4Net – you can configure the log4net library to save the produced SQL to a file for example. Unfortunately reading long files with SQL statements is too boring. Sometimes it is tricky to figure out the SQL executed as a result of single action.
  • Display the executed SQL at the bottom of an ASP.NET web page. The idea is to have an IHttpModule module that will inject the SQL code at the end of each request. This approach saves time, because the SQL is visible instantaneously after the action is executed. Unfortunately this trick works only for web applications.

There are several ways to access the SQL that has been executed by NHibernate. I will use a NHibernate interceptor. The code for the interceptor looks like this:

public class NHibernateSQLMonitor : EmptyInterceptor
{
public static void Init(Configuration config)
{
config.SetInterceptor(new NHibernateSQLMonitor());
}

private static StringBuilder mExecutedSQL = new StringBuilder();

public static string ExecutedSQL
{
get
{
return mExecutedSQL.ToString();
}
}

public static void ClearExecutedSQL()
{
mExecutedSQL = new StringBuilder();
}

public override NHibernate.SqlCommand.SqlString OnPrepareStatement(
NHibernate.SqlCommand.SqlString sql)
{
mExecutedSQL.AppendLine(sql.ToString());

return base.OnPrepareStatement(sql);
}
}



The important method is OnPrepareStatement. This method is invoked every time NHibernate executes SQL statement. The sql parameter holds the SQL that will be executed.


Before using it, the interceptor must be registered. One possible way to do it is like this:

NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
NHibernateSQLMonitor.Init(cfg);

ISessionFactory sessionFactory = cfg.BuildSessionFactory();



Now everything is ready for our IHttpModule that will inject the executed SQL at the bottom of a web page. Here is the implementation:

public class NHibernateSQLMonitorModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += new EventHandler(
PostRequestHandlerExecute);
}

void PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpContext httpContext = ((HttpApplication)sender).Context;
HttpResponse response = httpContext.Response;

if (response.StatusCode == 302)
{
//Browser performs redirect. Do nothing.
//The executed SQL will be shown on the next page
}
else if (response.ContentType == "text/html")
{
response.Write("<hr>");
response.Write("<b>SQL Executed by NHibernate</b>");
response.Write("<br>");

string executedSQL = NHibernateSQLMonitor.ExecutedSQL.Replace(
"\n", "<br>");
response.Write(executedSQL);

NHibernateSQLMonitor.ClearExecutedSQL();
}
}

public void Dispose()
{
//Not required
}
}



Now there is one final step that should be done – the HttpModule needs to be registered in the config file of the application. To do it open the web.config file, find the <httpModules> section (<modules> if you are running IIS7) and place the following line there:

<add name="NHibernateSQLMonitor"
type="Data.NHibernateSQLMonitorModule, Data"/>



Data is the assembly name where the NHibernateSQLMonitorModule class is defined. Now everything is ready and if there are no compilation errors you should see something like this:


image


After adding new record, the page will look like this:


image


So, what about improvements:


Instead of using NHibernate interceptor for monitoring the executed SQL it is possible to display the output from the Log4Net. The log4net output contains the SQL parameter values which may be a great benefit. As you may have noticed, the values in the screenshot above are replaced by the ? character.


The current version uses static variable to hold the executed SQL. If there is more than one user interacting with the application, this will lead to some synchronization problems. For example, you can extend the NHibernateSQLMonitor class to use the ASP.NET Session store. This way the user will see only the SQL code executed as a result of his actions.


P.S. This post was inspired long time ago after reading the Steve Sanderson’s Pro ASP.NET MVC Framework. He has a similar application that connects to Linq to SQL and displays the executed SQL.

09 December 2009

eBay Architecture

Recently I was curious to find out how big sites like eBay are build and running. After a quick research I was able to find some quite interesting articles.

I was surprised to find out that eBay doesn't use transactions. As well they do not use foreign keys in their database (the same thing as the SharePoint_AdminContent database). It looks like this is the latest trend ;-)

If you are curious like me, take a look at the following:

Randy Shoup on eBay's Architectural Principles
eBay Architectural Strategies, Patterns, and Forces
Software Engineering Radio: eBay's Architecture Principles with Randy Shoup
Scalability Best Practices: Lessons from eBay
Dan Pritchett on Architecture at eBay
You Scaled Your What?
High Scalability: eBay Architecture

24 August 2009

jQuery FullCalendar and ASP.NET MVC

Recently I had to integrate jQuery FullCalendar into ASP.NET MVC application. Up to now I was not able to find such an example, so I will try to provide one. I assume that you are familiar with ASP.NET MVC, jQuery and FullCalendar component, so I’m not going to introduce each technology.
image I will use the default ASP.NET MVC Web Application template to create new project. Please, note that the jQuery is included by default, so there is no need to download and reference it.
The first step would be to place FullCalendar JavaScript and style-sheet files inside project’s Scripts and Content directory as shown in the picture.
Then we need to reference the files we just added to our project. I will do it by placing the following lines of code inside the <head> section of Site.Master file:
<head runat="server">
   <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
   <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
   <link href="../../Content/fullcalendar.css" rel="stylesheet" type="text/css" />
   <script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
   <script src="../../Scripts/fullcalendar.js" type="text/javascript"></script>
</head>
Now we are ready to use the calendar routines inside our views. How to do it? Just create a div tag and render the calendar’s HTML code inside. Here is how to modify Home’s Index.aspx:
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

   <script type="text/javascript">
       $(document).ready(function() {
           $('#calendar').fullCalendar({
               events: "/Home/CalendarData"
           });
       });  
   </script>

   <div id="calendar">
   </div>
</asp:Content>
The code above will render the calendar’s HTML inside a div with id=”calendar”. The calendar data will be delivered by invoking the following URL: /Home/CalendarData. This corresponds to CalendarData method from the Home controller. This controller is supposed to return the data in Json format. Here is a sample implementation:
    [HandleError]
   public class HomeController : Controller
   {
       public ActionResult CalendarData()
       {
           IList<CalendarDTO> tasksList = new List<CalendarDTO>();

           tasksList.Add(new CalendarDTO
           {
               id = 1,
               title = "Google search",
               start = ToUnixTimespan(DateTime.Now),
               end = ToUnixTimespan(DateTime.Now.AddHours(4)),
               url = "www.google.com"
           });
           tasksList.Add(new CalendarDTO
           {
               id = 1,
               title = "Bing search",
               start = ToUnixTimespan(DateTime.Now.AddDays(1)),
               end = ToUnixTimespan(DateTime.Now.AddDays(1).AddHours(4)),
               url = "www.bing.com"
           });

           return Json(tasksList);
       }

       private long ToUnixTimespan(DateTime date)
       {
           TimeSpan tspan = date.ToUniversalTime().Subtract(
    new DateTime(1970, 1, 1, 0, 0, 0));

           return (long)Math.Truncate(tspan.TotalSeconds);
       }

       public ActionResult Index()
       {
           return View();
       }

       public ActionResult About()
       {
           return View();
       }
   }
The code above creates two calendar entries called “Google search” and “Bing search”. Everything should be pretty simple, except the stuff around ToUnixTimespan routine.
There is well known problem with serialization of dates in Json format. There is no strict standard, so there are several approaches to this problem. For example, take a look here. The implementation adopted by Microsoft was not recognized by FullCalendar, so I had to introduce the ToUnixTimespan routine. Basically, this routine returns the seconds after 1/1/1970.
Because of the above, you should notice that the start and end dates are represented as int:
    public class CalendarDTO
   {
       public int id { get; set; }
       public string title { get; set; }
       public long start { get; set; }
       public long end { get; set; }
       public string url { get; set; }
   }
If you have done everything correct, the final result will be
image

Enjoy!

Edit: Due to the higher interset I have published the source code of this post here. Please note that Visual Studio 2008 is used and you need to convert the project if more recent version is used.

21 June 2007

Anti-development methodologies

Software industry is growing constantly and development methodologies are following the same trend. Internet is full with shiny articles describing each methodology and all the benefit. Most of the people I'm talking are bored when they hear stuff like this. If you are like them, don't miss this article. A friend of mine just send me the link. Also, check out the comments. All of them are about dummy development practices. Some of the titles are cynical, but there is a lot of truth in each line.
Enjoy!

27 April 2007

BrainStorm Rocks

Yesterday was a great day. My team called BrainStorm won the local round of Microsoft's Imagine Cup 2007 competition in the area of software design.
Our project with the code name Bookvar will compete in the finals this year in Seoul, Korea. This was possible, because of the remarkable team I'm part of. Right now I can't find appropriate words to describe them, but as one of the jury said: "I had the chance to watch these young motivated and smart people". It's a great pleasure to work with each one of them.
Although we managed to win the local round, there is still much work to be done. Lucky for us, the finals are after 3 months.
Check out this post from Ruslan Trifonov if you want to see some pictures from the event. Ruslan was member of the jury.

13 March 2007

Grand Prix Racing Online

Last week I was chatting with an old friend of mine - Vladimir Alexandrov. I was surprised to find out that he is driving the Grand Prix Racing Online site. Basically this is a F1 on-line simulator. If you are a F1 fan you will appreciate what Vladimir and his team is doing. The site is completely free and guess what - no advertisements are present.
There are some interesting issues about the implementation and hosting, but because of security I can not share them.
Good luck Vlado, and continue with the great job.

12 March 2007

NHibernate and triggers

Recently I was asked from a college of mine, about the following exception in application based on SQL Server 2005 and NHibernate :
[NHibernate.AdoNet.TooManyRowsAffectedException] {"Unexpected row count: 2; expected: 1"} NHibernate.AdoNet.TooManyRowsAffectedException

After a quick investigation the problem was obvious - the exception raises when a row from a table is updated and the row has fired a trigger which executes an update statement.
I have faced with this problem since early beta of NHibernate (0.8.4 as far as I can remember). Till now the only solution I have found is to use SET NOCOUNT to stop the message that shows the number of rows affected by a Transact-SQL statement from being returned as part of the results.
Just place SET NOCOUNT ON before the UPDATE statement inside the trigger and then after the UPDATE statement place SET NOCOUNT OFF. This will solve the problem.

ASP.NET Web Part editor in pop-up dialog

Last hour I was wondering how to host a ASP.NET Web Part editor control inside a pop-up dialog. I was lucky to find this implementation. It is based on some tricks, but resolves the problem.

20 December 2006

First Bulgarian .NET Book is here

Second volume from the first Bulgarian book about .NET is out. You can download free copy from here. Printed version will be available after a month.

17 November 2006

Windows Forms data binding and notification of changed properties

Yesterday a college of mine asked me a question: "How to refresh TextBox control in Windows forms application binded to a property of object, when the property change its value?". The solution is very simple, but according to me not very well documented (at least in books I read).


Solution: Provide event named PropertyNameChanged, where PropertyName is the name of property binded to the TextBox. During the binding process, the text box inspects binded object for event with the mentioned signature and binds to it. The sample code looks like this:


public class Customer
{
    private string mName;
 
    public string Name
    {
        get { return mName; }
        set
        {
            mName = value;
            if (NameChanged != null)
            {
                NameChanged(this, EventArgs.Empty);
            }
        }
    }
 
    public event EventHandler NameChanged;
}
 
Customer cust = new Customer();
textBox1.DataBindings.Add("Text", cust, "Name");
 
Another possible solution is to remove and add binding of the text box to the object. You can write general routine to loop through each control for a given form and remove-add binding. This is nasty solution of course.