Saturday, October 04, 2008
#
Well done jQuery
As everyone already knows, Microsoft has announced that jQuery will ship in the future with Visual Studio. I think this really is a step forward and will definitely complement all the exciting new developments going on with ASP.NET including the enhancements with ASP.NET Ajax and ASP.NET 3.5 + SP1.
But...
Here’s what I would like to know: Why did Microsoft choose jQuery? The only explanation I can come up with is: Well..why not?
I have ported JavaScript from jQuery to PrototypeJS and visa-versa, even emulated functionality I’ve seen in one with the other. After a while, I ended up settling into PrototypeJS, why? Well, honestly it’s probably not because of PrototypeJS itself, but because of script.aculo.us. Going back 12 months or so, the animations and effects in script.aculo.us to me appeared a little smoother and seemed to have more browser compatibility then the jQuery of the time.
I have recently been writing a client-side control extender using the ASP.NET Ajax libraries then using PrototypeJS+script.aculo.us to basically fill the gaps. And thus far these libraries are an exceptionally powerful and productive combination.
Battle tested
Lets also not forget that PrototypeJS + script.aculo.us are included as part of Ruby-on-rails, which basically means you can be assured that these JavaScript libraries have been deployed in a huge variety of websites in the Ruby community.
Taking a look at the warm-fuzzy real world client list on Prototype’s site and jQuery’s site, its obvious that both libraries are popular, there are a lot of big companies in each list, some are even listed in both. Funnily enough though Microsoft itself is listed only on the Prototype site.. :)
Conclusion?
Not really knowing where to get answers or reasons, I took a long shot and fired a tweet at Scott Hanselman…no pulse, but I didn’t expect anything. I’m just wanting to know what makes jQuery so special? It definitely has a better website then PrototypeJS. I’ve read forum comments that in some cases jQuery is only being used for it’s plugins, which are conveniently accessible from a link on the homepage. How many people even know that Scripteka has a collection of downloadable plug-ins for prototype!? I agree that the guys over at Prototype should look at a website refresh and start pulling the community together a bit.
The future
In any respect I feel this is a step forward for Microsoft actually accepting and using Open Source products for .net instead of replicating them. And you never know, shipping NHibernate with Sql Server would be to me, a whole new level of respekt.
Sunday, August 17, 2008
#
If NHibernate decided to ditch compatibility with plain old .net 2.0 and focus on 3.5 how would the ICriteria interface change? Previously I was throwing around an idea of using a simple lambda expression to resolve the property name. Well, I couldn't help but build on this a little more. The following idea is not supposed to be LINQ, that would be far more complicated and LINQ is essentially its own interface, which is not the point. The point is, if ICriteria was written today in .net 3.5, what could it look like? How could it change?
So just to recap, the original code sample looked like:
ICriteria c = session.CreateCriteria(typeof(Person));
c.Add(Restrictions.Eq(Property.GetFor(() => new Person().FirstName), "John"));
Paul later come back and suggested I try using a slightly different signature so that the "Person" object doesn't need to be instantiated for no reason, this means the we can do this:
ICriteria c = session.CreateCriteria(typeof(Person));
c.Add(Restrictions.Eq(Property.For<Person>(p => p.FirstName), "John"));
I like this a lot more. So this is the point where I started playing around and wanted to try and implement a neater way of integrating this to add Criterion. First off I tried implementing ICriteria.Add(Restrictions.Eq()) as an expression which looked like:
ICriteria c = session.CreateCriteria(typeof(Person));
c.Add(RestrictBy.Eq<Person>(p => p.FirstName == "John" ));
That is where I got up to in the previous post. So after this I started implementing some of the other functions found on the 'Restrictions' class such as:
- .NotNull()
- .IsNotNull()
- .Not()
- .Between()
- .Gt() (Greater than)
Then I realized all of the above functions are able to be figured out using the syntax I already had: 'p.FirstName == "John"', so how about p.FirstName != "John", or p.ID > 0 or p.FirstName != null, you get the idea. This being the case, now there is no need for the Restrictions class at all, nearly everything can be figured out by using Add(). The other problem I wanted to solve was not having to keep passing the generic <Person> class in all the time. So I created a class which wraps ICriteria and keeps track of these few things, so now it looks like:
ICriteria c = session.CreateExpression<Person>()
.Add(p => p.FirstName == "John")
.Criteria;
Most of the other functions on the Restrictions class can be added the same way:
ICriteria c = session.CreateExpression<person>()
.Add(p => p.FirstName == "John") //Restriction.Eq()
.Add(p => p.LastName != null) //Restriction.IsNotNull()
.Add(p => p.ID > 0 && p.ID < 1000) //Restriction.Between()
.Criteria;
There are also other more complex things that the ICriteria interface does such as adding Projections and Joins. So how would the old AddAlias() function work? Like this perhaps:
ICriteria c = session.CreateExpression<Person>()
.Alias<Address>(p => p.Addresses, "addr")
.Add(a => a.Postcode != null)
.AddAndReturn(a => a.Address2 == null)
.Criteria;
Bringing it all together, here's a comparison between the old interface and the expressions version.
Current ICriteria:
ICriteria o = session.CreateCriteria(typeof(Person))
.Add(Restrictions.Eq("FirstName", "John"))
.CreateAlias("Addresses", "addr")
.Add(Restrictions.IsNotNull("addr.Postcode"))
.Add(Restrictions.IsNull("addr.Address2"))
.AddOrder(Order.Asc("ID"));
Same query using Expressions:
ICriteria c = session.CreateExpression<Person>()
.Add(p => p.FirstName == "John")
.Alias<Address>(p => p.Addresses, "addr")
.Add(a => a.Postcode != null)
.AddAndReturn(a => a.Address2 == null)
.OrderAsc(p => p.ID)
.Criteria;
In conclusion, this is probably not going to revolutionize the global economy, but on some levels I think it feels a little more intuitive and a little more modern. In other respects, it's probably not much less typing then the original. Also with the up and coming linq provider, is this a waste of time? or does it complement it?
Feel free to have a poke around the source, and corresponding tests
Friday, August 15, 2008
#
It's been a long time in between updates for subtext, but, has it actually been worth it? Well, kinda. Compared to the 1.9.5 release this one seems a little rough around the edges.
If you're on a shared host WITHOUT full trust, beware! Things will break in multiple places, including:
DTP.aspx (The homepage) (tag "st" undefined, needed to add back 'Register TagPrefix="st" Namespace="Subtext.Web.UI.WebControls"') (My web.config merge error)
- /admin/Posts/ (EnclosureMimetypes config section missing requirePermission="false" attribute)
- /admin/Feedback/ ("FeedbackStatusFlag" undeclared, needed to prefix with the namespace)
- Subtext.Framework.UrlManager.UrlReWriteHandlerFactory.GetHandlerForUrl(string url) also breaks from a security permission when calling UrlAuthorizationModule.CheckUrlAccessForPrincipal(), had to recompile Subtext.Framework to get around this.
EDIT: I don't mean to blast subtext, but I might as well lay a few more issues out there:
- The call to "/Admin/Services/Ajax/AjaxServices.ashx?proxy" throws an "Operation could destabilize the runtime" exception, haha I must say this is the first time I've seen that, fixed by generating the AjaxServicesProxy.js file locally.
- In the Feedback admin area, when hovering the URL icon the "title" tag shows the email address.
- Forgot to add this last night: Had to remove the OpenID stuff from the login page, errors with "Cannot be called from Untrusted assembly".
The problems in this upgrade mostly appear to be stemming from carelessness regarding restrictions in medium trust. I guess the question is - "Is subtext venturing away from medium trust on purpose?"
Looking to the future. From what I recall I don’t think it’s actually possible to run .net 3.5 applications without full trust, features such as anonymous types simply don’t work.
Tuesday, July 22, 2008
#
I can't remember if this has been around before, I do vaguely remember seeing something like it.
However, I just wanted to apply a snippet of code I found on Paul's blog the other day to NHibernate. Of course we will definitely have type safety in queries when Linq-to-NHibernate is completed. But surely linq-to-nhibernate is not going to be the _only_ way of writing queries.
Using the original code snippet 'as is' would look something like this:
ICriteria c = session.CreateCriteria(typeof(Person));
c.Add(Restrictions.Eq(Property.GetFor(() => new Person().FirstName), "John"));
This is ok, but a little long winded, so I implemented another class called RestrictBy which can break down a simple lambda expression. So now I can use:
ICriteria c = session.CreateCriteria(typeof(Person));
c.Add(RestrictBy.Eq(() => new Person().FirstName == "John"));
c.UniqueResult();
This also means you'll get compile time errors for incompatible types such as:

Using the lambda expression we get to evaluate the _actual_ property and that property's type. If you wanted to clean this up some more, its not hard to then go and add some extension methods to ICriteria to produce:
ICriteria c = session.CreateCriteria(typeof(Person));
c.AddEq(() => new Person().FirstName == "John");
c.UniqueResult();
So that's it, a simple example at the moment, but it might be an option to look into a little more because the ICriteria interface is still NHibernate's native querying interface and still provides a lot of power, flexibility and programmatic building of queries.
Sourcecode:
EDIT: For further reading, see the
follow up post.
Thursday, July 17, 2008
#
MindManager is a very slick product, it looks and feel like every other Office application. I've used this product for a few university project management assignments to create things such as work breakdown structures (WBS) as well as just general information organisation.
The version I'm using is the Lite version (heaps cheaper) which still carries a lot of features but lacks the integration to other office products. It also lacks the additional information you are able to attribute to the topic nodes such as start, finish dates, time estimates and resources. Although these would also be nice to have from a project point of view, I guess I can live without doing it directly in MindManager as they sound a lot more like scheduling tasks to me. Which is where MS Project Integration would be awesome.
To bridge this gap for the Lite version I've decided to write a plug-in for Microsoft Project to import the information directly out of MindManager.
Then viola, you can even use the relationship links between the nodes to create task predecessors automatically. As much as I've enjoyed using Mind Manager, re-entering this task information would be a real negative to actually using it productively. So you should be able to use this little plug-in if you're unsure you want to spend the additional $250US right away but still want some form of Project Integration. Oh and its only one way, no pushing information back.
The plug-in can be downloaded here, should work with both MindManager Lite and Pro. Of course, this is a free util, no warrenty or support.
Download
Get the Plugin or Browse the source code
Friday, March 28, 2008
#
NHibernate is a remarkable ORM, however with all the magic comes a few caveats, these being the difficulties running NHibernate apps in a shared hosting environment. I'm still convinced that it's entirely possible, so I've decided to start compiling a list of success and failures that others (and myself) have had in getting things working.
Compatible Shared Hosts
| Host Name |
Comment |
Reference |
| Webhost4life |
Reportedly works with "no hacks" |
[ref] |
| DiscountAsp |
I think this should work with IIS7 / Win 2008 |
[ref] |
| XHostSolutions |
Simply email support and ask to have your application run as Full Trust
|
This is the host I use.
|
Shared Hosts known not to work
Untested / Unknown
Useful References / Alternate Ideas
Thursday, February 21, 2008
#
There are a fair few CMS solutions floating around in .NET at the moment, a good general comparison tool can be found at CmsMatrix.org.
Cuyahoga
In the past, the Cuyahoga Website Framework has looked always fairly interesting, it is also built on NHibernate which to me is a plus. Most things I've done with NHibernate have generally "just worked", maybe it's because NHibernate development is pounded with unit tests, whatever it is, it works.
I haven't had any experience developing any extensions for Cuyahoga, so I don't know exactly how extensible it is yet. In terms of usability, I did find the interface a little confusing at first. The admin section is only used to configure modules/pages..etc.. but to actually edit the content I needed to visit the actual page in admin mode and click edit module (DNN Style).
Graffiti
Graffiti CMS has only recently come to my attention. I remember only in the later half of last year reading about Telligent acquiring Dozing Dogs CMS and wondering at the time, what they were going to do with it, well, now days, there is no sign of Dozing Dogs. Instead, earlier this week Telligent released Graffiti CMS which appears to be completely new as a full version 1.0.
Graffiti supports a variety of databases including VistaDB (default), MS Sql and MySql. Not only that, but they claim its mono-compatible, so it is able to be run on linux and other mono supported platforms.
Test Run of Graffiti
Setup was really simple, xcopy, run. With not much more thought then that, your away.
The dashboard of Graffiti looks fantastic. I've always been a fan of having an area dedicated to admin tasks, as opposed to having admin controls stuffed into a site's design, as done by DNN. The only thing that wasn't obvious in Graffiti is the fact that there are no "pages". All content appears to be considered a "post". The "posts" are configurable in a way that is easy to set them up in a blog style behavior, or leave them detached, essentially making them pages.
Some of the highlights that stood out to me immediately
- Seems to use NVelocity templates to render out HTML, meaning it's lean and clean
- Supports a programmable API -- MetaWeblog
- Supports its own extensibility though Widgets
- Widgets can be installed in literally 2 clicks
- Admin dashboard is slick
- Free express version
Again, from observation, there are a couple of cons too
- "Posts" appear to be rendered out into files on the disk, (like MovableType) this certainly got people that owned large blogs into trouble.
I did get the feeling that I'd seen an admin area that looked similar...Graffiti even has fading panels at the top of the screen when you make a change...
In any case, Graffiti seems like something that should be watched in future. It may already be a great solution for a small - medium site. I do think that a site with a lot of pages may become a little unwieldy in the current interface, especially if changes need to be made across many pages, or you want to switch to a new theme.
Wednesday, December 19, 2007
#
The ADO.NET team blog have posted about a number of vendors who are currently working on Linq-to-sql providers for other databases, some of these include Oracle, Informix, Ingres, Sybase, MySQL, PostgreSQL, DB2, Progress and Microsoft SQL Server databases.
I won't be getting too excited as most of these more due to come within 3 months of the official VS2008 release. Come to think of it, I think this is when most vendors are planning to release new versions, including other cool plug-ins like Resharper.
Every since using NHibernate, the effort required to use Many-to-many and one-to-many joins in business objects is a brainless exercise. When using a lazy loaded property on a business object, it just works, however, what happens when you try to bind this property using an ObjectDataSource hooked up to gridview or formview in asp.net...

As seen above, the GridView works out that it's out of it's depth with all the complex properties and only defines the simple text/int/boolean columns. The only alternative for the complex properties is to define your own template columns.
To display the value of a complex property you are still able to access the sub-properties using the Eval() command. So in the example below, I can use Eval() to display the name of the 'parent location' that is currently selected. To actually select the location, I can bind it the a custom user control using the Bind() method, this will pass in the entire lazy loaded 'Location' object. The user control must then pass back out a Location object when the ObjectDataSource needs to do an update.
After making this change my grid now has the lazy loaded 'Parent Location' property:
When the grid is in action, view mode:
Edit mode:
Although this is a relatively simple example, it does show how much code you don't need to write to do a one-to-many join using binding in asp.net 2.0.
Thursday, November 08, 2007
#
As far as I'm aware ASP.NET doesn't support IDataErrorInfo, I've asked about this in many places, including Tech.Ed '07 with no success. The closest things I've seen in terms of Business Object level validation is from Enterprise Library validation block (which is attribute based and can render out with custom EntLib web controls) and another example in the Futures Dynamic Data Controls using Linq (I have no idea how this magic validation magically appears).
It all just seems overly complicated, so, have a look at the IDataErrorInfo interface the methods are:
string this [ string columnName ] { get; }
string Error { get; }
Simple and generic. I've been playing around with an idea about how to get this into a generic web control, introducing:
WebValidationControlExtender
Here is an example of the control in design mode:
Here is an example of the control in action using an ObjectDataSource and a plain old DetailsView:
Here's what's going on under the hood.
All you need to do is tell WebValidationControlExtender what ObjectDataSource to hook in to.
When the page is executing and the user tries to insert a record, the DetailsView control builds up an object and sends it into the ObjectDataSource.
WebValidationControlExtender is already listening for Insert and Update events, all it does is check if the object being passed through implements IDataErrorInfo.
If it does, WebValidationControlExtender interrogates the object's columns/properties for errors.
If errors are found, it adds CustomValidators back to the page then goes searching for controls that are using that object datasource (in this case the DetailsView).
When it finds the details view it searches for BoundFields that are bound to the properties with the error, then inserts the red * like in the picture above.
The point is, you could go an implement whatever validation library suites your needs, as long as the object implements IDataErrorInfo the validation works. I just don't understand why ASP.NET doesn't already use something like this, there are so many complicated implementations for validation, I hope this brings some fresh light.