Rockford Lhotka's Blog

Home | Lhotka.net | CSLA .NET

 Sunday, June 24, 2007

Just a quick reminder that the official 3 day CSLA .NET training roadshow continues through the summer. You can still attend in one of these cities:

  • Orlando
  • Chicago
  • Washington, DC
  • Dallas

The feedback from the classes so far has been excellent! I sat in on part of the class last week in Minneapolis, and I can see why. Miguel is a very good teacher, and his hands-on, continual lab style is a refreshing change from traditional powerpoint-heavy training.

Sunday, June 24, 2007 8:14:13 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, June 22, 2007

CSLA .NET Version 3.0 Beta 2 is now available for download.

This is the final test release of version 3.0. Any changes between now and release will be bug fixes.

If you plan to upgrade please consider helping yourself and the community at large by downloading this version and testing it before July 5. Let me know about any issues through the forum.

CSLA .NET 3.0 provides support for Microsoft .NET 2.0 and 3.0.

If you want to build CSLA .NET 3.0 without .NET 3.0, you must define the NET20 symbol in the project properties.

CSLA .NET 3.0 includes enhancements useful to all 2.1.4 users, including these highlights:

Validation rules

·         PropertyFriendlyName – specify a friendly name to use when displaying broken rule text

·         Format – specify a format mask to use when displaying broken rule numeric values

·         StringMinLength – new validation rule method

·         DecoratedRuleArgs – useful for code generation of AddBusinessRules() methods

·         Fix bug with stopProcessing and rule priorities

·         RegEx – rule method now supports options for dealing with null values

Authorization

·         New CanExecuteMethod() functionality, similar to CanReadProperty() and CanWriteProperty()

Undo and Data binding

·         If edit levels get out of sync an exception is thrown, making debugging of Windows Forms data binding much easier

Interfaces

·         Cleaned up and rearranged interfaces to provide more consistency – making it easier to create UI frameworks on top of CSLA business layers

SmartDate

·         Added TryParse() method

·         Fix bug with CompareTo() method

SortedBindingList and FilteredBindingList

·         Allow access to underlying source list

ProjectTracker\PTWin

·         Reworked data binding code to address all known issues

See the change log for a complete list of changes.

Of course the primary focus of CSLA .NET 3.0 is support for Microsoft .NET 3.0. Highlights include:

·         WcfProxy – a data portal channel that uses WCF. You can transparently move from any existing data portal channel to WCF by using this new proxy.

·         DataContract – support for using the WCF DataContract and DataMember attributes in your business classes

·         WPF

o   CslaDataProvider – a data provider control that can create, fetch, save and cancel edits on a CSLA .NET business object. In some cases this can lead to code-less data entry forms!

o   Validator – a control that provides Windows Forms ErrorProvider-like behavior to WPF forms that are data bound to CSLA .NET objects.

o   Authorizer – a control that provides Windows Forms AuthorizeReadWrite-like behaviors to WPF forms that are data bound to CSLA .NET objects.

o   ObjectStatus – a control that exposes IsValid, IsSavable and other properties from a CSLA .NET business object so they can be used by XAML data binding.

o   IdentityConverter – a value converter that can be used to work around an issue with data binding and refreshing the UI.

ProjectTracker\PTWpf

·         Added new WPF UI with equivalent functionality to PTWin.

ProjectTracker\PTWorkflow

·         Added new Workflow UI to illustrate how a workflow can use CSLA .NET business objects

ProjectTracker\PTWcfClient and PTWcfService

·         Added a WCF service illustrating how to expose CSLA .NET objects through WCF/SOA

·         Added a WCF client app illustrating how to call a WCF service

ProjectTracker\WcfHost

·         Added a WCF host for the data portal

Friday, June 22, 2007 3:30:47 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, June 20, 2007

A CSLA .NET user, Aaron Nottestad, has been helping test 3.0 and ran into some issues when using the new WPF CslaDataProvider with editable objects. Thanks Aaron!

As a result, I had to do some work with CslaDataProvider, so it can manage the object’s entire lifetime from create/fetch through to save/cancel. If it can’t manage the lifetime, especially the save, then it can’t get the new object that comes back as a result of save. And if it doesn’t get that new object, then neither does data binding, so the UI controls end up editing an old instance of the object.

So the CslaDataProvider now has Save() and Cancel() methods that you can call to trigger saving or canceling of the business object. Also, as the object is created/fetched CslaDataProvider automatically calls BeginEdit() on the object.

This behavior is all optional, and is controlled by the ManageObjectLifetime property of the CslaDataProvider control. So if you want this behavior, you have to set that property to True. If you leave it at False (the default), then you must manage everything through code – though honestly you can’t manage editable objects through code while using CslaDataProvider. So maybe I should make the default be True? Hmm.

Anyway, this was easy enough to do and worked great. The resulting forms had exactly 4 lines of code – 2 to call Save() and 2 to call Cancel(). It occurred to me that there must be a way to avoid writing those 4 lines of boring code, and Aaron put me onto the RoutedCommand concept in XAML.

A RoutedCommand allows a control like a button or menu item to invoke a method on another control – purely through XAML. There are many examples out there about how this works to create standard Copy/Paste menu items that run against the current TextBox control, and that sort of thing. But none that I found which routed a command to a data provider control.

The reason turns out to be that the target of a command must be a UIElement, and data providers don’t inherit from that base class. Oops…

I thought I was stuck, because I really do want to route the command to CslaDataProvider in this case. However, I figured out a solution.

CslaDataProvider now has a read-only CommandManager property. This property exposes a “command manager” object which does inherit from UIElement and which does handle the Save and Undo routed commands. When it is created by CslaDataProvider, it is given a reference to the CslaDataProvider control, so it simply delegates all Save commands to the CslaDataProvider.Save() method and all Undo commands to CslaDataProvider.Cancel().

With that done, you can route a command from a button or menu item (or any other valid command source) to this CommandManager object, which effectively means you’ve routed the command to the CslaDataProvider control.

The CslaDataProvider gets declared like this:

    <csla:CslaDataProvider x:Key="ChildList"

                           ObjectType="{x:Type this:ChildList}"

                           FactoryMethod="GetList"

                           IsAsynchronous="False"

                           ManageObjectLifetime="True">

    </csla:CslaDataProvider>

 

Then the button controls get declared like this:

            <Button

              Command="ApplicationCommands.Save"

              CommandTarget="{Binding Source={StaticResource ChildList},

                              Path=CommandManager, BindsDirectlyToSource=True}"

              HorizontalAlignment="Left" IsDefault="True">Save</Button>

            <Button

              Command="ApplicationCommands.Undo"

              CommandTarget="{Binding Source={StaticResource ChildList},

                              Path=CommandManager, BindsDirectlyToSource=True}"

              HorizontalAlignment="Left" IsCancel="True">Cancel</Button>

 

The result is very cool: a form that can edit an object without the need to write any C# or VB code at all. Coupled with the CSLA .NET ValidationPanel to display validation results, you can create a highly interactive data edit form purely with XAML – and of course a CSLA .NET style business object doing all the work behind the scenes.

These new capabilities will appear in CSLA .NET 3.0 Beta 2 - hopefully later this week.

Wednesday, June 20, 2007 10:14:03 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

I’ve been spending some quality time with WPF and Visual Studio 2008 Beta 1 (Orcas) over the past few months. A couple observations I’ve made:

Observation ichi:

Putting code in a Page/Window constructor is bad. Yes, I know it is the “C# way”, but it is bad. The “VB way” of putting code in the Loaded event handler is better.

Why?

Because any exceptions thrown in the constructor prevent the page/window from loading at all, and you have to catch those exceptions in the code that is creating the page/window. In many navigation scenarios you can’t catch them, so the user gets an ugly WPF exception dialog.

However, if you do all your init work in the Loaded event handler, the page/window instance already exists. Navigation has already happened, so the “calling code” is no longer responsible for your page/window going haywire. Instead, you can actually handle the exception and show a nice dialog, explaining to the user what happened, and you can (if desired) navigate somewhere else or whatever.

Observation ni:

Handing control events with += or AddHandler is superior to using WithEvents/Handles. Yes, I am a strong advocate of WithEvents/Handles, and it is one of the major missing features in C#, but for WPF it turns out to be a negative.

Why?

Because the Handles clause links the name of the control to the code behind. The AddHandler or += approach, while less attractive in many ways, only couples the event name to the code behind.

In other words, when using Handles you get code like:

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
  Handles Button1.Click

While the AddHandler approach results in this code:

Private Sub SaveData(ByVal sender As Object, ByVal e As EventArgs)

The value of the second approach is that any control can route an event to SaveData(). It doesn’t have to be a button, much less Button1. It actually doesn’t even have to be a Click event. It could be almost any event.

The result is that the Presentation (XAML) is less coupled to the UI (VB/C# code) this way than when using Handles.

Unfortunately the Handles approach is more explicit and thus more readable (which is why C# should really get the Handles feature), so we’re left trading readability in order to gain loose coupling…

WPF
Wednesday, June 20, 2007 9:51:35 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, June 11, 2007

I posted previously about an issue where the WCF NetDataContractSerializer was unable to serialize a SecurityException object. Microsoft provided some insight.

It turns out that the constructor of the SerializationException object doesn't set the Action property to anything valid. Before you can serialize a SerializationException with NDCS you must explicitly set the Action property to a valid SecurityAction.

This does mean that NDCS is not compatible with the BinaryFormatter in this case, but at least there's a workaround/solution.

I've now updated CSLA .NET 3.0 to explicitly set the Action property any time a SecurityException is thrown, thus allowing the WCF data portal channel to return valid details about the nature of any exception.

Monday, June 11, 2007 9:07:53 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, June 01, 2007

The WCF NetDataContractSerializer is an almost, but not quite perfect, replacement for the BinaryFormatter.

The NDCS is very important, because without it WCF could never be viewed as a logical upgrade path for either Remoting or Enterprise Services users. Both Remoting and Enterprise Services use the BinaryFormatter to serialize objects and data for movement across AppDomain, process or network boundaries.

Very clearly, since WCF is the upgrade path for these core technologies, it had to include a serialization technology that was functionally equivalent to the BinaryFormatter, and that is the NDCS. The NDCS is very cool, because it honors both the Serializable model and the DataContract model, and even allows you to mix them within a single object graph.

Unfortunately I have run into a serious issue, where the NDCS is not able to serialize the System.Security.SecurityException type, while the BinaryFormatter has no issue with it.

The issue shows up in CSLA in the data portal, because it is quite possible for the server to throw a SecurityException. You'd like to get that detail back on the client so you can tell the user why the server call failed, but instead you get a "connection unexpectedly closed" exception instead. The reason is that WCF itself blew up when trying to serialize the SecurityException to return it to the client. So rather than getting any meaningful result, the client gets this vague and nearly useless exception instead.

By the way, if you want to see the failure, just run this code:

    Dim buffer As New System.IO.MemoryStream
    Dim formatter As New System.Runtime.Serialization.NetDataContractSerializer
    Dim ex As New System.Security.SecurityException("a test")
    formatter.Serialize(buffer, ex)

And if you want to see it not fail run this code:

    Dim buffer As New System.IO.MemoryStream
    Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    Dim ex As New System.Security.SecurityException("a test")
    formatter.Serialize(buffer, ex)

I've been doing a lot of work with the NDCS over the past several months. And this is the first time I've encountered a single case where NDCS didn't mirror the behavior of the BinaryFormatter - which is why I do think this is a WCF bug. Now just to get it acknowledged by someone at Microsoft so it can hopefully get fixed in the future...

The immediate issue I face is that I'm not entirely sure how to resolve this issue in the data portal. One (somewhat ugly) solution is to catch all exceptions (which I actually do anyway), and then scan the object graph that is about to be returned to the client to see if there's a SecurityException in the graph. If so perhaps I could manually invoke the BinaryFormatter and just return a byte array. The problem with that is in the case where the object graph is a mix of Serializable and DataContract objects - in which case the BinaryFormatter won't work because it doesn't understand DataContract...

In the end I may just have to leave it be, and people will need to be aware that they can never throw a SecurityException from the server...

Friday, June 01, 2007 11:34:14 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

A fellow Magenicon has also blogged in response to Fowler's comments about the .NET world.

Friday, June 01, 2007 8:57:49 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

Strangeloop is one of the coolest products I've seen (not as cool as Surface, but that's hard to top :) ).

This product is an ASP.NET-aware device that does intelligent caching for web sites. It can do things that seem virtually impossible - it is that cool! Here's Richard Campbell's blog entry with more background.

If you have the need for a nearly transparent boost in performance for your ASP.NET web site, Strangeloop is something you should look at!

Friday, June 01, 2007 8:41:09 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
On this page....
Search
Archives
Feed your aggregator (RSS 2.0)
July, 2014 (3)
June, 2014 (4)
May, 2014 (2)
April, 2014 (6)
March, 2014 (4)
February, 2014 (4)
January, 2014 (2)
December, 2013 (3)
October, 2013 (3)
August, 2013 (5)
July, 2013 (2)
May, 2013 (3)
April, 2013 (2)
March, 2013 (3)
February, 2013 (7)
January, 2013 (4)
December, 2012 (3)
November, 2012 (3)
October, 2012 (7)
September, 2012 (1)
August, 2012 (4)
July, 2012 (3)
June, 2012 (5)
May, 2012 (4)
April, 2012 (6)
March, 2012 (10)
February, 2012 (2)
January, 2012 (2)
December, 2011 (4)
November, 2011 (6)
October, 2011 (14)
September, 2011 (5)
August, 2011 (3)
June, 2011 (2)
May, 2011 (1)
April, 2011 (3)
March, 2011 (6)
February, 2011 (3)
January, 2011 (6)
December, 2010 (3)
November, 2010 (8)
October, 2010 (6)
September, 2010 (6)
August, 2010 (7)
July, 2010 (8)
June, 2010 (6)
May, 2010 (8)
April, 2010 (13)
March, 2010 (7)
February, 2010 (5)
January, 2010 (9)
December, 2009 (6)
November, 2009 (8)
October, 2009 (11)
September, 2009 (5)
August, 2009 (5)
July, 2009 (10)
June, 2009 (5)
May, 2009 (7)
April, 2009 (7)
March, 2009 (11)
February, 2009 (6)
January, 2009 (9)
December, 2008 (5)
November, 2008 (4)
October, 2008 (7)
September, 2008 (8)
August, 2008 (11)
July, 2008 (11)
June, 2008 (10)
May, 2008 (6)
April, 2008 (8)
March, 2008 (9)
February, 2008 (6)
January, 2008 (6)
December, 2007 (6)
November, 2007 (9)
October, 2007 (7)
September, 2007 (5)
August, 2007 (8)
July, 2007 (6)
June, 2007 (8)
May, 2007 (7)
April, 2007 (9)
March, 2007 (8)
February, 2007 (5)
January, 2007 (9)
December, 2006 (4)
November, 2006 (3)
October, 2006 (4)
September, 2006 (9)
August, 2006 (4)
July, 2006 (9)
June, 2006 (4)
May, 2006 (10)
April, 2006 (4)
March, 2006 (11)
February, 2006 (3)
January, 2006 (13)
December, 2005 (6)
November, 2005 (7)
October, 2005 (4)
September, 2005 (9)
August, 2005 (6)
July, 2005 (7)
June, 2005 (5)
May, 2005 (4)
April, 2005 (7)
March, 2005 (16)
February, 2005 (17)
January, 2005 (17)
December, 2004 (13)
November, 2004 (7)
October, 2004 (14)
September, 2004 (11)
August, 2004 (7)
July, 2004 (3)
June, 2004 (6)
May, 2004 (3)
April, 2004 (2)
March, 2004 (1)
February, 2004 (5)
Categories
About

Powered by: newtelligence dasBlog 2.0.7226.0

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2014, Marimer LLC

Send mail to the author(s) E-mail



Sign In