Thursday, May 28, 2009

Silverlight 3 Beta and ChildWindow

The Silverlight 3 beta introduces the concept of the ChildWindow as noted in the following blog posts:

http://www.wintellect.com/CS/blogs/jprosise/archive/2009/04/29/silverlight-3-s-new-child-windows.aspx
http://timheuer.com/blog/archive/2009/05/10/silverlight-childwindow-non-modal-refactor.aspx

It does return a "DialogResult", however unlike other modals in the .NET paradigm the "DialogResult" is a nullable bool (bool?) value. What happened to the standard "DialogResult" enumerations?

Hopefully this will be rectified in the RTM release of Silverlight 3, but in the mean time a simple expanded class can be used that returns the Dialog result.



using System;
using System.Windows;

namespace System.Windows.Controls
{
public class ChildWindowEx : ChildWindow
{
public DialogResults DialogResultEx
{
get { return _result; }
protected set
{
_result = value;
SetDialogResult();
}
}

#region Protected Methods
protected virtual void SetDialogResult()
{
switch (_result)
{
case DialogResults.OK:
case DialogResults.Yes:
DialogResult = true;
break;
default:
DialogResult = false;
break;
}
}
#endregion

#region Fields
private DialogResults _result;
#endregion

public enum DialogResults
{
None,
OK,
Cancel,
Abort,
Retry,
Ignore,
Yes,
No
}
}
}



The ChildWindowEx should be put in an utility Silverlight assembly such as "MySilverlightControls" although it can be defined in your Silverlight application's assembly.

The above class can be used to create a control by first creating a new ChildWindow, then changing the parent. The class defintion should look like the following:


namespace Sivlerlight1
{
public partial class ChildWindow1 : ChildWindowEx
{
...
}
}


And the XAML should have the following definition:


xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myControls="clr-namespace:System.Windows.Controls;assembly=MySilverlightControls">



It is important to note that both the parent of the class and the XAML use the ChildWindowsEx otherwise the ChildWindow1.g.cs (or .vb) class that gets generated will have compile errors.

In the XAML example above, we have delcared a new namespace via the 'xmlns:myControls="clr-namespace:System.Windows.Controls;assembly=MySilverlightControls"' declaration. This declaration allows us to use any controls (or other UI elements) that are included in the System.Windows.Controls namespace and declared in the "MySilverlightControls" assembly.

Monday, April 6, 2009

VirtualPathProvider and Routing

I was implementing some configuration and service (.svc) files as VirtualFiles under a ASP.NET MVC application and was always getting 404 errors when attempting to request my virtual file. Essentially I was doing the following:
  • Register routes.
  • Register VirtualPathProviders

If used the IgnoreRoute registration, it would relieve my 404 errors. However I didn't necessarily want to have to do an IgnoreRoute for every possible file type I might serve up as a virtual file. I noticed that if I flipped the order and did the following:

  • Register VirtualPathProviders
  • Register routes.

That my 404 errors went away without needing to use the IgnoreRoutes registration.

Saturday, March 21, 2009

Silverlight, WCF and Secure communication

Silverlight only supports the "basicHttpBinding" WCF binding which sends all messages in the clear, unlike the "wsHttpBinding" binding.

How can we overcome this limitation? Peter Bromberg wrote about it here. However his suggest uses reflection and changes the actual object data when it does the encryption. Because the data in your object is changed that could cause unwanted changes to propogate. To avoid this you could use wrapper objects or even do a deep-level clone (using reflection, il emit, etc.) to create a copy of the object, encrypt its data, then allow it to be transmitted.

Also his example only deals with string data, but numeric and other types of basic data are also important. Encrypting string data doesn't do much good if your package is mostly numeric, say financial information, that could potentially be exploited too.

Perhaps another way of approaching the situation is to use a message package that contains encrypted data objects. Either the package could be at a high level that contains many objects or on a per object basis. Obviously when using a message package at a high level you lose fidelity and the client does not have a hard contract with the server concerning the contents of the service call. Rather all he has is a soft contract based on documentation. An psuedo-code example of this would be.

MessagePackage
{
string data;
string type;
}

Data: List

Step 1: Serialize data.
Step 2: Encrypt data.
Step 3: Create message package with the type name and the data.

The client would then

Step 1: Decrypt data in package.
Step 2: Deserialize data.

Again, we don't have a hard contract to know exactly what data has been stored in the package, only what we've been told it should be.

Another way of approach it would be a per object message package as above. Using the same data from before, our new process would look like the following:

MessageElementPackage
{
string data;
Type type;
}

Step 1: Serialize individual data elements.
Step 2: Encrypt individual data elements.
Step 3: Create individual message element packages for each data data element.
Step 4: Send message package elements as a List.

The client would then

Step 1: Decrypt data for each message element package.
Step 2: Deserialize each data element.
Step 3: Create a List of deserialized data.

The package would at least contain the a semi-hard contract in the Type property that could be checked and verified. However its still a soft contract as opposed to hard contract.

Neither of these options are really all that attractive as they lose a lot of what is benefitial about WCF, the hard contracts for data that is transmitted between server and client.

Of course, if you are using SSL then this is a moot point and would add additional, and unncessary, overhead.

ASP.NET MVC and JSON

ASP.NET MVC 1.0 RTM was released with reference to obsolete code as follows. This code snippet can be found in the JsonResult object's ExecuteResult method.


#pragma warning disable 0618
JavaScriptSerializer serializer = new JavaScriptSerializer();
response.Write(serializer.Serialize(Data));
#pragma warning restore 0618



Why is this important?

Well the JavaScriptSerializer has been marked as obsolete for one. Also it does not correctly handle objects trees, especially when they are dynamic. There are other blogs on this subject.

This is fairly easily to work-around, although hopefully MS will fix this in the next release. To rectify the situation, use the following derivative JsonResult class that uses the
DataContractJsonSerializer serializer. The important part of the class is the ExecuteResult method which with the serializer is as simple as


public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");

HttpResponseBase response = context.HttpContext.Response;

if (!String.IsNullOrEmpty(ContentType))
response.ContentType = ContentType;
else
response.ContentType = "application/json";

if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;

if (Data != null)
{
string output = string.Empty;
DataContractJsonSerializer serializer = new DataContractJsonSerializer(Data.GetType());
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
output = Encoding.Default.GetString(ms.ToArray());

byte[] bytes = Encoding.Unicode.GetBytes(output);
output = encoding.GetString(Encoding.Convert(Encoding.Default, encoding, bytes));
}
response.Write(output);
}
}


Now you have the basics to use the more powerful DataContract serializers to serializer your object into Json.

WCF, Silverlight and Known Types

The need was to be able to communicate between a Silverlight client and a backend server ASP.NET application (actually using MVC). There are two key aspects that I wanted to have in a data exchange mechanism:


  • Ability to handle derived types that were not known during compilation but rather at run-time (basically IoC style). So the KnownTypeAttribute could not be used in these cases as the base class would not know of the dervived types. This also applies to the scenario where you are derviving from a closed package.
  • Ability to encrypt the data being exchanged.


As a first draft and to explore the updated DataContractSerializers, I built a data exchange provider using the DataContractJsonSerializer and DataContractSerializer serializers. As part of the provider I also encrypted the package after it was serialized (see my blog post entitled Silverlight Encryption). This worked well as you are directly accessing the serializers and can easily pass in an IEnumerable list of known types during serializer construction. This actually works very well, especially with ASP.NET MVC (see my blog post entitled ASP.NET MVC and JSON for a slight issue) and REST style pages.

The code handles fetching data, requesting commands be executed, etc. on the server including encrypting the data. But how does the server send messages back to the Silverlight? With my data exchange provider, I would need to setup a thread in the Silverlight client that sent a command to the server to check for incoming messages. Not really an issue and works fairly well as you can specify how often you want messages checked.

However, I also needed to have messages sent and dealt with immediately (a good example is hooking into a phone exchange system and signalling the Silverlight client that a new call has been received). I could do this with my system by polling with a fine grain invertal (say 5 to 15 seconds instead of 30 to 60 seconds as an example). Or I could use either PollingDuplexHttpBinding with WCF. There is also the possibility of using an asynchronous TCP/IP connection.

WCF uses the DataContractSerializer under the covers, so it supports known types via the KnownTypeAttribute. However, it does not expose the serializers so how do you a list of known types to feed to the service? Well you could use the NetDataContractSerializer which decorates the serialized stream with relavent data. However, the NetDataContractSerializer is not supported by Silverlight. Instead we can use the ServiceKnownType attribute on the service. It can be applied either to the interface or to the concrete class itself. Essentially the ServiceKnownType a method name and a type of class that exposes that method as a static method. The method has the signature of

public static Type[] methodname();

So if you have a Service1, you'd decorate as follows:

ServiceContract(Namespace = "")]
[ServiceKnownType("methodname", typeof(myclass))]
public class MyService

Below is an implementation of a class that can be used with the ServiceKnownType attribute. It is called whenever you create an instance of your MyService service. It will scan through all the assemblies in the domain looking for specific classes to add as known types. You can use the RegisterAssemblyExclusion to exclude certain assemblies from being scanned and you can use the RegisterValidatorType to include concrete IDataContractKnownTypeValidator validators to determine if an object should be included.



public sealed class DataContractKnownTypesRegister
{
public DataContractKnownTypesRegister()
{
_exclusions.Add("mscorlib");
_exclusions.Add("system");
_exclusions.Add("microsoft");

RegisterValidatorType();
}

#region Public Methods

public static Type[] GetKnownTypes(ICustomAttributeProvider provider)
{
try
{
DataContractKnownTypesRegister instance = new DataContractKnownTypesRegister();
return instance.GetKnownTypesEx(provider);
}
catch (Exception ex)
{
throw;
}
}

#region Registration
public static void RegisterAssemblyExclusion(string name)
{
try
{
if (!_exclusions.Contains(name))
_exclusions.Add(name);
}
catch (Exception ex)
{
throw;
}
}

public static void RegisterValidatorType(Type type)
{
try
{
if (!typeof(IDataContractKnownTypeValidator).IsAssignableFrom(type))
return;

if (!_validators.ContainsKey(type))
{
IDataContractKnownTypeValidator validator = (IDataContractKnownTypeValidator)Activator.CreateInstance(type);
_validators.Add(type, validator);
}
}
catch (Exception ex)
{
throw;
}
}

public static void RegisterValidatorType() where T : IDataContractKnownTypeValidator
{
RegisterValidatorType(typeof(T));
}
#endregion

#endregion

#region Internal Methods
internal Type[] GetKnownTypesEx(ICustomAttributeProvider provider)
{
try
{
lock (_synchLock)
{
foreach (Type type in Utilities.DataContractKnownTypes)
ScanType(type);

foreach (Assembly assembly in Utilities.DataContractRegisteredAssemblies)
ScanAssembly(assembly);

return new List(_knownTypes.Values).ToArray();
}
}
catch (Exception ex)
{
throw;
}
}
#endregion

#region Private Methods
private bool IsExcluded(string fullName)
{
if (_exclusionsEx == null)
{
StringBuilder exclusions = new StringBuilder();
foreach (string exclusion in _exclusions)
{
if (exclusions.Length > 0)
exclusions.Append("");
exclusions.Append("^").Append(exclusion);
}
_exclusionsEx = new Regex(exclusions.ToString(),
RegexOptions.CultureInvariant
RegexOptions.IgnoreCase);
}

return _exclusionsEx.IsMatch(fullName);
}

private void ScanAssembly(Assembly assembly)
{
try
{
if (assembly == null)
return;

// If we already scanned the assembly...
if (_assembliesScanned.Contains(assembly.FullName))
return;

// Is this an excluded assembly?
if (IsExcluded(assembly.FullName))
return;

// Scan the types in the assembly...
foreach (Type type in assembly.GetTypes())
ScanType(type);

// Mark the assembly as scanned...
_assembliesScanned.Add(assembly.FullName);
}
catch (Exception ex)
{
throw;
}
}

private void ScanType(Type type)
{
try
{
if (type.GetCustomAttributes(typeof(DataContractAttribute), false).Length <= 0) return; if (_knownTypes.ContainsKey(type.FullName)) return; bool valid = true; foreach (KeyValuePair pair in _validators)
{
valid = pair.Value.IsValid(type);
if (valid == true)
break;
}

_knownTypes[type.FullName] = type;
}
catch (Exception ex)
{
throw;
}
}
#endregion

#region Fields
private IList _assembliesScanned = new List();
private static IList _exclusions = new List();
private Regex _exclusionsEx;
private static IDictionary _knownTypes = new Dictionary();
private static IDictionary _validators = new Dictionary();
private static readonly object _synchLock = new object();
#endregion

#region Constants
public const string MethodName = "GetKnownTypes";
#endregion
}

public interface IDataContractKnownTypeValidator
{
bool IsValid(Type type);
}


Our Silverlight version follows the same basic concept as our normal .NET version, but it does not explicitly scan assemblies in the domain. Rather it works on an externally registered lists of types (List) and assemblies (List) as represented by the Utilities.DataContractKnownTypes and Utilities.DataContractRegisteredAssemblies respectively.



public sealed class DataContractKnownTypesRegister
{
public DataContractKnownTypesRegister()
{
_exclusions.Add("mscorlib");
_exclusions.Add("system");
_exclusions.Add("microsoft");

RegisterValidatorType();
}

#region Public Methods

public static Type[] GetKnownTypes(ICustomAttributeProvider provider)
{
try
{
DataContractKnownTypesRegister instance = new DataContractKnownTypesRegister();
return instance.GetKnownTypesEx(provider);
}
catch (Exception ex)
{
throw;
}
}

#region Registration
public static void RegisterAssemblyExclusion(string name)
{
try
{
if (!_exclusions.Contains(name))
_exclusions.Add(name);
}
catch (Exception ex)
{
throw;
}
}

public static void RegisterValidatorType(Type type)
{
try
{
if (!typeof(IDataContractKnownTypeValidator).IsAssignableFrom(type))
return;

if (!_validators.ContainsKey(type))
{
IDataContractKnownTypeValidator validator = (IDataContractKnownTypeValidator)Activator.CreateInstance(type);
_validators.Add(type, validator);
}
}
catch (Exception ex)
{
throw;
}
}

public static void RegisterValidatorType() where T : IDataContractKnownTypeValidator
{
RegisterValidatorType(typeof(T));
}
#endregion

#endregion

#region Internal Methods
internal Type[] GetKnownTypesEx(ICustomAttributeProvider provider)
{
try
{
lock (_synchLock)
{
foreach (Type type in Utilities.DataContractKnownTypes)
ScanType(type);

foreach (Assembly assembly in Utilities.DataContractRegisteredAssemblies)
ScanAssembly(assembly);

return new List(_knownTypes.Values).ToArray();
}
}
catch (Exception ex)
{
throw;
}
}
#endregion

#region Private Methods
private bool IsExcluded(string fullName)
{
if (_exclusionsEx == null)
{
StringBuilder exclusions = new StringBuilder();
foreach (string exclusion in _exclusions)
{
if (exclusions.Length > 0)
exclusions.Append("");
exclusions.Append("^").Append(exclusion);
}
_exclusionsEx = new Regex(exclusions.ToString(),
RegexOptions.CultureInvariant
RegexOptions.IgnoreCase);
}

return _exclusionsEx.IsMatch(fullName);
}

private void ScanAssembly(Assembly assembly)
{
try
{
if (assembly == null)
return;

// If we already scanned the assembly...
if (_assembliesScanned.Contains(assembly.FullName))
return;

// Is this an excluded assembly?
if (IsExcluded(assembly.FullName))
return;

// Scan the types in the assembly...
foreach (Type type in assembly.GetTypes())
ScanType(type);

// Mark the assembly as scanned...
_assembliesScanned.Add(assembly.FullName);
}
catch (Exception ex)
{
throw;
}
}

private void ScanType(Type type)
{
try
{
if (type.GetCustomAttributes(typeof(DataContractAttribute), false).Length <= 0) return; if (_knownTypes.ContainsKey(type.FullName)) return; bool valid = true; foreach (KeyValuePair pair in _validators)
{
valid = pair.Value.IsValid(type);
if (valid == true)
break;
}

_knownTypes[type.FullName] = type;
}
catch (Exception ex)
{
throw;
}
}
#endregion

#region Fields
private IList _assembliesScanned = new List();
private static IList _exclusions = new List();
private Regex _exclusionsEx;
private static IDictionary _knownTypes = new Dictionary();
private static IDictionary _validators = new Dictionary();
private static readonly object _synchLock = new object();
#endregion

#region Constants
public const string MethodName = "GetKnownTypes";
#endregion
}

public interface IDataContractKnownTypeValidator
{
bool IsValid(Type type);
}


Unfortunately there is no easy way to attach the ServiceKnownType except to open up the
reference.cs class for the service reference and decorate the class with the ServiceKnownTypeAttribute. However once that has been done and the appropriate assemblies and/or types registered, then whenver you create a new instance of the service a list of known types will be generated and now your data exchange will work.

One interesting point is that you can not get an assembly by a name in Silverlight, so how do you do it? Use can do it once or two ways, depending on whether you have an instance of an object:


Object Instance:
instance.GetType().Assembly;
By Type:
typeof(AppUtilities).Assembly;


Sunday, August 10, 2008

Tidbits on development with Yahoo Use Interface AJAX components.

Form Component

I am using the Yahoo User Intrace (YUI), but wanted to have the ability to do client side validation along with server side validation and submission of form data via ajax. YUI has some of that with the Dialog component, but it has a couple of short comings:

  • Only available within a dialog
  • Can not be used with inline forms
  • Has no support for client or server validation
So I ended up writting a Form component that was based on the guts of the Dialog component. It has no user interface, but rather focuses on the behind the scenes items for the following:
  • Submission of form data; standard and AJAX as per the Dialog component
  • Client side validation; does basic standard validations for required fields, max lengths of strings, email addresses, etc. This also support the use of tooltips to display errors inline with the form controls.
  • Server side validation using AJAX; client and server validation work inconjunction validation.

The Form component is made up of the following files:

Requires the following YUI (only tested with 2.4.1):

  • yahoo-dom-events.js
  • yahoo-min.js
  • json-beta-min.js
  • utilities.js
  • container-min.js

Also makes use of the following if available:

  • button-min.js

Examples of the use of the Form component can be seen in the screenshots for the RLM web application alpha.

Using the Form component is relatively straight foward:

  • Setup a normal <form> tag with an ID and ACTION attributes. You may also specify the ACTIONVALIDATE attribute with a url for doing server validation, i.e.
    <form id="test" action="submit.php" actionvalidate="validate.php" method="POST">
  • You will also need an element to contain the button, i.e.

    <div id="test_buttons"></div>
  • Create the Form component object.
    var form_test = new YAHOO.thZero.Form("form_test",
    imageError: "error.gif",
    imageRequired: "required.gif",
    successReload: true,
    buttonSubmit: true,
    buttonCancel: true,
    buttonDelete: false,
    buttonReset: true,
    buttonsEl: "test_buttons"
    form_test.render(false);
  • Call the render method on the Form component object; this takes a boolean value to determine whether to focus on the first control or not.
        form_test.render(false);
The Form component has quite a few configuration options; see the source.

Subclasses and NHibernate

NHibernate (well really Hibernate) has three strategies of inheritance. The one I was most interested in was the 'table per class hierarchy' as I had a User class and an expanded UserEx sub class. Which UserEx is used in the system is dependent on configuration of the application; in my case I am loading different user sub classes depending on which forum that my application is establishing a bridge with.

Both classes map to the same table. Each UserEx class has it's own full mapping and only the appropriate mapping depending on the bridge chosen is loaded.

This seemed to be perfect for the 'table per class hierarchy' strategy. Only one problem, I had no discriminator columns nor any need for one as I was only going to have one sub class.

I got around this by declaring my classes as such:


class User
{
// user properties
}

class UserEx: User
{
// expanded user properties
}


And my mappings as such:


<class table="appr. table" name="User" value="null">
<id ... >
<discriminator-value formula="">"/>
// property mappings
</class>

<subclass name="UserEx" extends="User" value="">">
// property mappings
</subclass>


While this works like a charm, it would be nice if Hibernate/NHibernate would expand the 'table per class hierarchy' strategy to handle more gracefully this scenario.