Producing Reports with .Net and Telerik


“Nothing can be said to be certain, except death, taxes, and having to write reports.”

No matter what kind of application you dream of creating, your boss will eventually and very heartlessly kill your dreams by asking you to waste your life programming some kind of report so that some suit somewhere can kill a rainforest with their limitless need to print pretty tables and charts and show them off to their manager friends.

Ah! I feel much better now that’s off my chest.

I’m no stranger to the world of reporting. One of my very first developer jobs was to create a report-generator for a bank. As everyone seems to do, we started off using Crystal Reports. I soon got sick of that, so I wrote one using Delphi and XML-FO (don’t ask!) . I’ve used many other tools, such as SQL Server Reporting Services (SSRS) and DataDynamics (now Grapecity) ActiveReports, but recently I found Telerik Reports to be quite a good option. And as I get so many lovely comments on my blog from DotNet newbies, I thought I’d write a quick review of it here and it just might help someone.

The 3 Principles of Good Reports

Every reporting tool needs to fulfill 3 requirements, based on the people you’ll have to make happy with your reports. For the corporate design people, you’ll need good design tools so that every positioned element can be pixel perfect (it won’t get past them otherwise). For the users, it needs to run fast and produce a document in their favourite formats – usually either Excel or PDF. (You’ll find that they generally prefer Excel so they can fudge the figures and pretend it was your tool which did it!). And for developers, it needs to be easy to program and fit well with your processes.

So how does Telerik Reporting do in all these areas?

Design Tool

Like most tools nowadays, Telerik Reports provides you with a designer which is integrated with Visual Studio, and a variety of controls to use on that designer (just like you do with Windows Forms). It comes with the standard TextBoxes, PictureBoxes, Shapes and Panels, which are all very important (don’t underestimate the need for something as simple as a line in a report).

Other reporting tools I’ve used came with a RichTextBox control for producing formatted text. I guess that Telerik thought that the Rich Text Format was out-of-date now though, because they give you an HtmlTextBox instead. In many ways that’s a good step, because the HTML they allow in that control has many more options for styling than Rich Text does, such as background colors, borders, and padding. I’ve managed to produce quite good looking documents with the HtmlTextBox.

Another benefit to this control is that you can let a user control what goes in it. You could, for example, allow a user to enter HTML in a Wysiwig control in a web form and load that HTML into the report itself. That would be great for dynamic creation of letters, for example.

On the downside, I’ve found that you don’t always need HTML-styling for a report, due to the lack of control in how the styling renders with fluid text, but I’m sure it has uses sometimes. I also miss the lack of a justified text option, which is a big problem if you want to use it for producing letters, as that’s how most letters are formatted.

A typical mistake when creating reports is that your output gets slightly cut-off due to margin errors. Telerik has a nice way of handling this by adding a warning sign to the designer to alert you to the potential problem before you waste all your energy walking back-and-forwards to the printer.

Like most other tools, Telerik has good support for Sections and Groups, which means you can easily apply headers, footers and subtitles to your pages. The flow of text between sections is also important, and Telerik does a good job there too.

There are plenty of other controls too, such as barcodes and checkboxes. And of course, at some point you’ll need to use charts, which Telerik has extremely good support for. Thinking about it, I suppose the charting tool is really one of the biggest reasons to consider Telerik Reports in the first place.

Runtime Integration

One of my biggest pet peeves with reporting tools is that they can often be too restrictive. Crystal Reports and SSRS, for example, were very closely tied to a particular kind of data source when I used them. That meant you frequently couldn’t use them with your own particular architecture, and you all-too-often had to rely on database queries to populate your report. While that might be good for some people, it was never right for me.

On the other hand, while it does have good integration with particular types of data source – such as SQL databases – Telerik Reports allows you to bind your reports to any kind of data. You can then write code-behind for the report which will do exactly what you want with the data at runtime. For me, that means I can keep all the view-logic separate from the data-logic, meaning I can utilise the same data for different “views” of the data, i.e. in a web page, a PDF document, or whatever else I choose. The data stays the same and the views of that data change around it.

Another benefit that brings is with testing. If you want to be able to test your reports, you’ll be at pains to have to run it against a database all the time. Using the approach of multiple views, you can mock out the data passed to the report and make sure it appears just right. You can even build it into your build server tests.

A nice feature I’ve seen with the latest version of Telerik Reports is an Entity Framework data-source. I haven’t used it yet, but I have used Entity Framework a lot, and I can see how it might be helpful. (Let me know what your experience is with it if you use this feature.)

Another plus-point for Telerik is the ability to control what data gets put into a control at runtime. You can use simple expressions to match up field contents, but you can also write complete functions in your code-behind which will be integrated into the report at runtime, giving you complete control of formatting – anything you can do in code can appear on your report. That also means you could supply XML, JSON or any other data format to the report and write code to get the exact data out which you need to display on your report.

Speaking of code-behind, I think that this feature is one of the best things Telerik Reports has to offer. For example, in one job it was important that I controlled the name of the file as it was created, which I wanted to do before sending it back to the client from a web page. Telerik lets you do that when you initialise the report in the code-behind, meaning I had full control of the naming at the time it was rendered. Splendid!

Output

At the end of the day, what really matters is what you get out of your reporting tool, and how fast it does it. Telerik Reports is especially good in this area, as it produces such a wide variety of formats. The standards are there – PDFs and spreadsheets – with support for PDFs (version 7.0 and higher), and for both the old and new Excel formats. It also supports Word documents very well. And now it even has Powerpoint support - I’d better not tell that to the business guys or their tiny little heads might explode with excitement!

Another feature you might like is the report viewer, which allows you to embed your report in a Windows form, a WPF form, a Silverlight control or even a web page. I don’t use that feature very often, but I have used it once or twice to allow a user to see a report before they print or save it, and it seemed very competent. The output was produced in a second or two, and looked just like the printed output would have done.

Conclusion

Generally it isn’t an understatement to say that reporting tools aren’t always that great. In fact, they can be generally quite rubbish. But I must say, I’ve had some good success with Telerik Reports, and am not planning to use anything else any time soon.

I just hope they add support for justified text. :-)

For more info, check the Telerik website: http://www.telerik.com/products/reporting.aspx

Orchard Creates Hidden Content Parts When Adding Fields to Your Types


I just discovered how Orchard CMS adds Content Fields to Content Types from the admin interface, even though it isn’t possible to do that with Migrations.

When you add a Field, Orchard secretly adds a new ContentPart to your ContentType with the same name as the type. It then attaches your Fields to that part and treats them as Fields of that Type in the Dashboard.

It might seem okay, but for some reason a ContentType of mine lost its connection to the generated Part of the same name, and even when I added a Field to that Type, in the Dashboard, it never showed up. (It gave me a Notification to indicate the field had been added, but it would never show.) To fix it I just added a line to my Migrations.cs script to add the secret Part back to the Type.

Connecting to Azure Table Storage


After you finally manage to get Table Storage working (see nice tutorial here) you’ll try to deploy it to your staging environment. That means you need to change the configuration.

There are three settings to use: AccountName, AccountSharedKey and TableStorageEndpoint.

Unfortunately, the values you need for them aren’t what you would naturally expect.

AccountName: This isn’t your account name, but the name of your storage account. (I guess that’s why it has to be a unique name at the time you create it.) On the summary page of your storage project you will only see the value you need in the list of endpoints. It’s the first part of each of the three domain names.

AccountSharedKey: This is the Primary Access Key as found in the summary page of your storage project in the developer portal.

TableStorageEndpoint: This isn’t the endpoint as described in the summary page, but rather a shortened version. Just lop off the AccountName part of the endpoint you use as described in the summary page. That should give you something like http://table.core.windows.net.

For more information see this article on MSDN.

It is so time-consuming to get right, that it really makes sense to follow the advice in the documentation. First, test locally. Then test your local hosted app using the live Storage account. Finally, load your app and test that in the staging environment.

Saying that, I haven’t yet managed to get the second scenario to work. It just crashes on start-up. (Help!)

Learning Windows Azure


I started to learn how to use the Azure Cloud Service from Microsoft this week. Currently it’s still in Tech Preview stage. Unfortunately you can tell that from the SDK documentation.

Here’s some useful links to get you going:

  1. Screencasts: http://msdn.microsoft.com/en-us/azure/dd439432.aspx
    These are quite basic, but trust me, you need them to be basic to get you started.
  2. SDK: http://www.microsoft.com/downloads/details.aspx?FamilyID=80e3eabf-0507-4560-aeb6-d31e9a70a0a6&displaylang=en
    Contains CHTM-style documentation, tools and samples. Don’t expect too much from the docs; they explain enough to get you confused, and then have an API reference. You need to unzip the samples and get into them to start understanding how everything fits together.
  3. Visual Studio Templates: http://www.microsoft.com/downloads/details.aspx?FamilyID=8e90b639-1ef0-4e21-bb73-fc22662911bc&displaylang=en
    This gives you a set of project and item templates which you can use to create and publish Azure applications. Don’t worry about the extra projects it adds to a solution, or the config files. You will learn more about them later.
  4. The Azure developer center on MSDN: http://msdn.microsoft.com/en-us/azure/default.aspx

Assuming you already registered for Azure, that’s all you really need to get started.

The biggest problem I found at first was deploying an app. Once you have generated an Azure project in Visual Studio, you expect to be able to publish it from Visual Studio too. Unfortunately you can’t, and it takes a little more effort. I’ll write more about that in another post.

I also needed help trying to understand what to focus on to get started. So here’s a big tip: Ignore .Net Services, Live Services, and SQL Data Services. They aren’t part of Azure per se. You can come back to them later. First you just need a hosted project and some storage – either blob storage or table storage. (There’s also queue storage, but I bet no one will want to use that straight away – it’s for tying two apps together, which no one will want to do at first.)

I recommend you download the SDK and the Visual Studio templates, create yourself a “Web Role” project (which is really the equivalent of an ASP.Net project), and work on that. Then move onto table and blob storage. You can use the screencasts to help you.

Good luck getting started!

C# Acrobatics : Lambdas and Expression Methods as a replacement for NVelocity


I’ve been very quiet recently. (I’m trying to not be so loud, Scott. :) ) You see, I’ve been writing a lot of ASP.Net code for a site I’m working on. And, to be honest, I’ve been having a lot of trouble. The source code for .Net has been very helpful, and I’ve learnt a lot about what’s going on under the covers of ASP.Net because of it.

(Note: I won’t comment here on the quality of the code I’ve found – I’ll leave that up to you to judge. But in any case, I’ve been trying to build on top of it.)

One thing I’ve found to be important is the reliance on Web Controls. (It’s got something to do with javascript libraries, but that’s another story.) Getting away from the "standard" way to do ASP.Net isn’t easy though. Even the ninjas on the ASP.Net MVC team seem to be having trouble. However, with the magic of lambdas and extension methods in C#, I think I might have just about managed to get something usable. I thought I’d publish my work here, and see what comments I got.

I think it’s best to start with what my ASP.Net code looks like once I’ve got everything working. (Notice I still have some Web Controls in there, but that’s because I’ve not worked out how to do sorting of data without web controls yet.)

The inspiration for this was taken from the improvements made to NVelocity by the gurus on the Castle Project. I thought it looked great, and I’d like something similar, but I didn’t really want to learn a whole new scripting language and integrate it into my working environment just for rendering a bit of HTML. So I built some C# classes to do a similar thing for me instead. It’s not as nice as NVelocity, but it’s okay for now.

Warning: The following code may contain statements of a disturbing nature to more sensitive readers. We cannot be held responsible for any confusion, delusion or mental illness caused by this code.

It starts by taking a collection of Task objects, and calling the extension method "ForEach" on them:

<% Tasks.ForEach(sections => {
   sections.NoData = tasks => {
%>
   <p>
   Hey, you've got nothing to do.</p>
   <p>
<%
   };
   sections.BeforeAll = tasks => {
   %>
  <table class="task-list">
    <tr class="task-list-header">
      <th>
        <asp:LinkButton runat="server" CommandName="Sort" CommandArgument="StartDate"
          Text="Started" />
      </th>
      <th>
        <asp:LinkButton runat="server" CommandName="Sort" CommandArgument="DueOn"
          Text="Due" />
      </th>
      <th>
        <asp:LinkButton runat="server" CommandName="Sort" CommandArgument="Priority"
          Text="Priority" />
      </th>
      <th>
        <asp:LinkButton CssClass="task-description" CommandName="Sort" CommandArgument="Title"
          Text="Description" runat="server" />
      </th>      <th>
      </th>
    </tr>
   <%
   };
     sections.Before = task => {
    %>
    <tr class="<%= this.tableCssClasses.Next() %>">
    <%
   };
   sections.Each = task => {
    %>
    <td>
      <div class='calendar calendar-icon-<%= task.StartMonth %>'>
        <div class="calendar-day">
          <%= task.StartDayOfMonth %></div>
      </div>
    </td>
    <td>
      <div class='calendar calendar-icon-<%= task.DueMonth %>'>
        <div class="calendar-day">
          <%= task.DueDayOfMonth %></div>
      </div>
    </td>
    <td>
      <%= task.Priority %>
    </td>
    <td class="task-title">
      <a href='<%= Href.For("~/Tasks/{0}/Show.aspx", task.ID) %>'><%= task.Title %></a>
    </td>
    <td>
      <asp:Button ID="Button1" runat="server" CssClass="button" CommandName="Delete" Text="Mark Done" />
    </td>
    <%
   };

   sections.After = task => {
    %>
    </tr>
    <%
   };

   sections.AfterAll = task => {
    %>
    </table>
    <%
   };
 });
%>

It might take a while to grasp what’s going on here. The code actually starts using an Extension method to IEnumerable that looks like this:

public static void ForEach<T>(this IEnumerable<T> enumerable, ForeachSectionSetter<T> sectionSetter) {
  if (enumerable != null) {

    if (sectionSetter != null) {
      ForeachSections<T> sections = new ForeachSections<T>();
      sectionSetter(sections);

      if (enumerable.Count() == 0) {
        if (sections.NoData != null)
          sections.NoData(enumerable);
        return;
      }

      if (sections.BeforeAll != null)
        sections.BeforeAll(enumerable);

      int itemIndex = 0;
      T previousItem = default(T);

      foreach (T item in enumerable) {
        if (sections.Before != null)
          sections.Before(item);
        if (itemIndex % 2 == 1 && sections.Odd != null)
          sections.Odd(item);
        if (itemIndex % 2 == 0 && sections.Even != null)
          sections.Even(item);
        if (itemIndex > 0 && sections.Between != null)
          sections.Between(previousItem, item);
        if (sections.Each != null)
          sections.Each(item);
        if (sections.After != null)
          sections.After(item);
        itemIndex++;
        previousItem = item;
      }
      if (sections.AfterAll != null)
        sections.AfterAll(enumerable);
    }
  }
}

The delegate ForEachSectionSetter is used by the calling method with a lambda expression. As a parameter it receives an ForeachSections object, which looks like this:

public class ForeachSections<T> {
  public Action<T> Each { get; set; }
  public Action<IEnumerable<T>> BeforeAll { get; set; }
  public Action<T> Before { get; set; }
  public Action<T,T> Between { get; set; }
  public Action<T> Odd { get; set; }
  public Action<T> Even { get; set; }
  public Action<T> After { get; set; }
  public Action<IEnumerable<T>> AfterAll { get; set; }
  public Action<IEnumerable<T>> NoData { get; set; }
}

The calling method gets the chance to set the properties of this class before it is returned to the constructor of the ForEach method for processing. And because each property is already preset to a default value (Null in this case), the constructor can use the ForeachSections object just like a set of default or optional parameters. The caller can simply set values to the properties it needs, and ignore the rest.

If I had tried this another way, using overloadable constructors, it would have led to multiple constructors with indistinguishable signatures. If I’d have used property initializers, I wouldn’t have been able to run the whole routine without requiring a second call to the object, which actually wasn’t possible.

Basically, I couldn’t think of another way to do it.

The properties of the ForeachSections object are all delegates too. That means that we can use them with lambdas, which gives us lambdas inside of a lambda. (Hmm, very confusing!)

So what do you think? Could you use something like this? Can you make it simpler? Leave me a comment if you can.

The Value of Being Free to See the Source


Since the source code to ASP.Net was made available, I’ve been using it extensively. Here’s a great example of why it’s so valuable.

I’ve been trying to integrate the Enterprise Library 3.1 Exception Handling Block into my application. My application is split into a core and web UI specific components, so I’ve defined errors in my code to be thrown when a resource is not available. The web application configuration file specifies that if a specific exception, e.g. a ResourceNotFoundException, is thrown, the Exception Handling Block should replace that exception with a 404 Resource Not Found error using Http. That should in turn use the CustomErrors feature to redirect to a 404 not found page.

Makes sense, and sounds simple, don’t you think?

Nothing in the docs says that it shouldn’t work.

But it doesn’t. It simply won’t work. Why? Well, there’s nothing on the web. But after spending some serious hours digging through the source code, I can finally see why.

Here’s a lovely little hidden-to-the-world snippet of the code I got inside of Visual Studio:

code = HttpException.GetHttpCodeForException(e);

// Don't raise event for 404.  See VSWhidbey 124147.
if (code != 404) {
  WebBaseEvent.RaiseRuntimeError(e, this);
}

So it would never work!

Nice of them to let me know.

Easy Data-loading with LINQ-to-SQL and LINQ-to-XML


.Net 3.5 had some nice tricks in it. LINQ-to-XML was one of them. With the new "X"-types, you can make working with XML really easy.

VB.Net 9 takes it one step further, and lets you write XML in your code without strings.

"Hey Rich, that’s old news," I hear you say. "And who’s interested in VB today anyway?"

Well, apparently there are a lot of VB-er’s still out there. I am mainly a C# developer myself, but I found that VB was perfect for a problem I had recently -  loading of XML data into a SQL Server table.

More »

Silverlight 2 Poster Available


imageYou’re not a real Silverlight developer until you have the poster stuck up on your wall.

Apparently these were hot at Mix.

Thanks to Brad Abrams for posting it.

Design Guidelines for LINQ


Have you wondered if and when you should use the new LINQ features in .Net 3.5?

Like, where should I put a new extension method? Should I use Func<T> or a custom delegate? How do I best implement a mix-in (extension methods on an interface)?

Well, Mircea Trofin has just published a new draft of some LINQ design guidelines. You might just find your answers there.

Read Word Documents in a Web Browser


image I love this! Not because of the features, but because of the way it works.

Tim Sneath just blogged about TextGlow – an online Word docx file reader. The docx format is XML, and Silverlight 2 apps can use LINQ-to-XML to parse it and format it for display inside the browser.

Amazing!

You can read more about it on Tim’s blog.