Saturday, 27 June 2009

YUI DataTable with ADO.NET Data Services

The Yahoo User Interface library (YUI) is an awesome client-side UI library, and ADO.NET Data Services is an equally awesome server-side framework for exposing a service layer for your data.

However, there is little documentation on how to get the 2 technologies to talk to one-another. Microsoft are pitching ADO.NET Data Services to marry up with Sliverlight - and rightly so, but like a lot of people, my skills are firmly grounded in AJAX.

Searching around, Jim Fiorato has written a great article on integrating a data service with a YUI chart but that's about it at this stage.

So far I've managed to get a YUI DataTable to display data from an ADO.NET Data Service, along with paging and sorting.

ADO.NET Data Services v1.5 CTP1

I need to highlight a shortfall in the current version of ADO.NET Data Services (1.0) - it does not return a count of all rows. Without this, displaying pages of data is nigh impossible as we simply don't know how many pages to display.

Thankfully, the issue has been resolved in the v1.5 CTP, you can download it here. Note that this is a pre-release version so I'm really hanging out for the final release.

Sample Project on CodePlex

I've created a sample project that contains a simple ADO.NET Data Service, and a sample page that implements a YUI DataTable. Note: You must first install the v1.5 CTP for it to compile.

I'm hoping to add more samples of other YUI components down the track.

Instead of writing a huge blog post explaining all the steps, I've added detailed code comments in the sample project.

Anthony.

Thursday, 7 May 2009

Strip Formatting on Paste using YUI Rich Text Editor

I’ve been using the Yahoo User Interface Library (YUI) in my web app, and one particularly cool component is the YUI Rich Text Editor: its cross-browser compatible, fully extensible, and best of all it’s free :)

For all its greatness, one thing I’ve struggled with is that if you copy & paste stuff from another app into the YUI Editor, all of the original formatting is maintained. Most of the time for us, the “other app” is Microsoft Word, which does a particularly heinous job of generating HTML from a formatted document. This almost always wreaks havoc if the user subsequently tries to change text styles in the editor, as the underlying HTML is a total mess.

So, the solution for us was to try and strip out all of the formatting when somebody pastes stuff into the Editor, resulting in nice clean HTML that plays well with the YUI Editor formatting functions. Now, unfortunately no such feature exists in the YUI Editor, and Googling around just led to dead ends, so I was left to build my own.

CleanPaste for YUI Rich Text Editor

Download from CodePlex

For information on what’s supported, please read the notes on CodePlex, as I will keep this updated as I make bug fixes etc.

To use the CleanPaste script, follow these steps:

  1. Ensure you’ve already installed the YUI components & created a Yahoo Editor on your page.
  2. Place the CleanPaste.js file somewhere in your project.
  3. Include the script in your page using the following code:

    <script type="text/javascript" src="CleanPaste.js"></script>

    Ensure the src attribute points to the directory where the CleanPaste.js script is located.
  4. In the Javascript where you create your Yahoo Editor object, create an instance of the CleanPaste object, passing in the editor as the parameter:

    var myEditor = new YAHOO.widget.Editor('editor', myConfig); myEditor.render();

    var cleanPaste = new CleanPaste(myEditor);

That’s it, the editor should now strip the formatting out of pasted text.

Of course this is still under development, so if you have any problems or feedback please post on CodePlex and I will get back to you.

Cheers, Anthony.

Monday, 9 March 2009

Nested Mail Merge Regions using Aspose.Words

I've been looking into various solutions for merging Word documents server-side, without resorting to Microsoft Word Automation as it is apparently the devil.

After trialing a handful of solutions on the web, I've concluded that Aspose.Words has some killer features, such as doc and docx support, and PDF file export. Furthermore, unlike competing products, I won't have to sell a kidney to pay for it. Perfect!

That said, once getting into the nuts and bolts of things I discovered one shortfall that is thoroughly discussed in their forums: No support for nested mail merge regions. A region is something Aspose created to allow a portion of a Word document to grow dynamically based on a set of data, e.g. a Table.

Compared to what Microsoft Word can do, a region is pretty powerful stuff. However, not powerful enough for what I need as our app has lots of hierarchical data. For example, imagine a food order that has multiple delivery times:

10.30am
Bagels
Fruit Juice

12.30pm
Sandwiches
Tea & Coffee

If I wanted to define this in a Word template, my regions would look like this:

{TableStart:DeliveryTimes}
{TableStart:Items}
{TableEnd:Items}
{TableEnd:DeliveryTimes}

Now, for anyone who's tried, Aspose.Words will simply throw an exception: Nested mail merge regions are not yet supported.

I figured that since Aspose.Words provides a full Document Object Model for a document, I could write my own class. A bit of looping here and there... easy!

Hardly. I can now see why Aspose has been holding out on such a function. It actually turned out to be a right nightmare to write the class. That said, I got there in the end so I thought I'd share it with the rest of you so that you too don't need to toil over this for days on end.

Introducing AdvancedMailMerge

You may need to add a reference to your copy of Aspose.Words in the WordsExtensions project in order for it to compile.

In terms of how to set up your Word document regions, I've used the same syntax as Aspose.Words. Create merge fields called TableStart:TableName and TableEnd:TableName.

To perform the merge, it's pretty straightforward:

  1. Load your Word file into an Aspose.Words Document object.
  2. Create an instance of the AdvancedMailMerge object.
  3. Pass the Document into the Load method of AdvancedMailMerge. The Load method will validate the regions in the document.
  4. Check the Errors property to ensure there are no structural errors in the document.
  5. Call AddRegionData to add as many data sources as you require. There are special overloads of this function for defining child/parent relationships so that your data is filtered as per your data relationships.
  6. Call the Merge function. This will do it's magic and merge the nested regions with your data sources.
  7. You can then call the Save method of the Document object, outputting a PDF or whatever you like.

User data filtering

There is also a groovy filtering feature that allows users to filter region data by adding syntax to a TableStart merge field. If you add the \b switch to a field, followed by a standard ADO select query, the data will be filtered in the document, e.g.:

{MERGEFIELD TableStart:Items \b Title = 'Bagel' }

Switch support

Since I can't use the standard Aspose.Words MailMerge class, I'm left to support Mail Merge switches myself (e.g. \* Upper to make the result uppercase etc). I've created a MergeFieldSwitch class to handle this. However there are too many switches for me to support. I've added the basics, however they haven't really been tested. Be prepared for bugs if you want to use these.

Please Contribute

I have a lot of testing still to do on this, and I know there will be some issues. If you find any problems, please post them on the CodePlex site and I will look into it.

I'll post my own bug fixes to CodePlex as I come across them.

Cheers,
Anthony.

Sunday, 8 March 2009

Obfuscating .NET code on the cheap

I recently needed to obfuscate a .NET component I wrote, and never having done this before I started looking into the various options available. Being a small side project I really didn't want to spend big bucks.

The obvious first choice was to try out the Dotfuscator Community Edition that ships with Visual Studio as it's free. I obfuscated my component, and then disassembled it using Red Gate's Reflector.

It turned out that all it did was obfuscate my namespaces & method names, however it didn't touch the control flow of the methods, meaning that all of my logic source code was still clearly visible.

These features are available in their professional edition which is way out my budget.

Googling around, I stumbled across Eazfuscator.NET, a free .NET obfuscator written by Oleksiy Gapotchenko. Installing the app was a breeze, it even integrated with the Visual Studio tools menu.

It has some very powerful features, including control flow obfuscation, assembly merging, and re-signing strongly named assemblies. For a free app this is very impressive, as you would pay thousands for this elsewhere.

Upon running my obfuscated component through Reflector, my source code had been completely obfuscated, making me a very happy man.

So far I'm wrapped in what this app can do, and I'll keep you posted as I discover more.