CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Csla light and enum serialization

rated by 0 users
This post has 23 Replies | 5 Followers

Not Ranked
Posts 6
kboutsen Posted: Tue, Apr 14 2009 6:41 AM
Hello all,

I have a CSLA object library that I also want to use in a Silverlight application. I created a CSLA Silverlight object library and it works. Except for the enums in this library. They don't get serialized.

I read about a solution somewhere, in which you create a new class that inherits from NameValueListBase<,,> and where you use the enum to fill this NameValueListBase<,,> with data.
In this solution the attribute 'RunLocal' is used (not available in the Silverlight CSLA dll), and reflection to get all values from an enum (also not available for Silverlight libraries).

What workaround is there to still be able to use enums in the Silverlight application?

A sample enum/class are:

public enum EnumSample
{
    ENUM_VALUE_1 = 0,
    ENUM_VALUE_2 = 1,
}

[Serializable]
public class ClassSample
{
    // ...

    private static PropertyInfo<EnumSample> EnumSampleProperty =
            RegisterProperty<EnumSample>(typeof(ClassSample), new PropertyInfo<EnumSample>("EnumSample"));
    public EnumSample EnumSample
    {
        get { return GetProperty(EnumSampleProperty); }
        set { SetProperty<EnumSample>(EnumSampleProperty, value); }
    }

   //...
}


The error message that I get is:
Type '***.EnumSample' with data contract name 'EnumSample:http://schemas.datacontract.org/2004/07/***' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

I have a Windows service that's running the 'Csla.Server.Hosts.IWcfPortal' (for applications that use the regular CSLA .NET objects) and 'Csla.Server.Hosts.Silverlight.IWcfPortal' (for applications that use the Silverlight CSLA .NET objects) services. The Silverlight application uses this service to get the objects.
Top 500 Contributor
Posts 21
IanK replied on Tue, Apr 14 2009 7:08 AM

Review post below.

http://forums.lhotka.net/forums/thread/24774.aspx

It may assist you. Its using NVL objects not new class, but does use different code in DataPortal_Fetch

 

Regards

 

Not Ranked
Posts 6
kboutsen replied on Tue, Apr 14 2009 7:12 AM
The problem is that the code in that thread also uses the System.Enum.GetValues() function to populate the NVL object. This function is not available in the Silverlight libraries. Maybe there is a workaround?

Kind regards
Top 100 Contributor
Posts 77
Peran replied on Tue, Apr 14 2009 11:24 AM
I adapted the code here for the missing System.Enum.GetValues() function in Silverlight

http://dolittle.com/blogs/einar/archive/2008/01/13/missing-enum-getvalues-when-doing-silverlight-for-instance.aspx
Top 10 Contributor
Posts 9,270
There is a RunLocal equivalent in CSLA .NET for Silverlight. When you create the DataPortal<T> instance, you can specify that it should ignore configuration and run in local-only mode for that request.

Rocky

Not Ranked
Posts 6
kboutsen replied on Wed, Apr 15 2009 3:26 AM
Dear Rocky,

is it possible to give a small code example on this.

What we still don't understand when we are fetching the object at the server side, that we use the enums to fill up the object. Then it gets serialized and at the client side we need to deserialize.
Can it deserialize correctly with your solution?

We also get the errors when we serialize from client side to server side....

Thanks already for  your feedback!

Koen
Top 10 Contributor
Posts 9,270

I don't know. I don't think we specifically tested using enum values through the MobileFormatter. I've entered a bug so this question/issue doesn't get lost.

http://www.lhotka.net/cslabugs/edit_bug.aspx?id=388

Rocky

Top 10 Contributor
Posts 9,270

I guess I should ask a clarifying question though.

Are you saying

  1. A property value of type enum doesn't serialize properly?
  2. A NVL populated with values from an enum doesn't serialize properly?
  3. A custom object of your creation doesn't serialize properly?

I could see 1, as that's what we didn't test (I don't think).

If the problem is 2, then that's almost certainly a bug in your code, because I know NVL objects serialize just fine - I use them all the time.

If the problem is 3, then we need to talk about how you created the custom object. The MobileFormatter has very strict requirements around what objects it will and won't serialize, and if you want to pass any custom object through the data portal you have to create the object exactly right. CSLA has base classes you should inherit from, but the easiest solution, by far, is to use one of the normal business object base classes with managed backing fields - otherwise you'll have to do some extra work.

Rocky

Not Ranked
Posts 6
kboutsen replied on Wed, Apr 15 2009 5:38 AM
It's problem 1. A property value of type enum doesn't serialize.

The sample code that I posted was:
public enum EnumSample
{
    ENUM_VALUE_1 = 0,
    ENUM_VALUE_2 = 1,
}

[Serializable]
public class ClassSample
{
    // ...

    private static PropertyInfo<EnumSample> EnumSampleProperty =
            RegisterProperty<EnumSample>(typeof(ClassSample), new PropertyInfo<EnumSample>("EnumSample"));
    public EnumSample EnumSample
    {
        get { return GetProperty(EnumSampleProperty); }
        set { SetProperty<EnumSample>(EnumSampleProperty, value); }
    }

   //...
}

I had a managed backing field of type enum. I re-wrote it now, so I have a regular property of type enum and a managed backing field of type int. The enum property gets and sets it's value according to the int backing field. This field can be serialized and on the client we can re-construct the enum using this int. By marking this int managed backing field 'private', the user of this code doesn't see this field and uses the regular enum property.

The new code for the class becomes:

[Serializable]
public class ClassSample
{
    // ...

    /* This property is used on client side, it is constructed by using the
     * int property below
     */
    public EnumSample EnumSample
    {
        get { return (EnumSample)EnumSampleInt; }
        set
        {
            EnumSampleInt = (int)value;
        }
    }

    private static PropertyInfo<int> EnumSampleIntProperty= RegisterProperty<int>(typeof(ClassSample), new PropertyInfo<int>("EnumSampleInt"));
    /* This property is used for serializing
     * This property is also used for constructing the enum property above
     */
    private int EnumSampleInt
    {
        get { return GetProperty(EnumSampleIntProperty); }
        set { SetProperty<int>(EnumSampleIntProperty, value); }
    }

    // ...
}


Thanks a lot for your feedback. I hope my solution can be a solution for others too (until there is a better one).

Kind regards,
Koen
Top 10 Contributor
Posts 9,270

Thanks for the detailed explanation, that helps a lot.

Hopefully we can figure out a solution. The process of serializing values to/from Silverlight and .NET is complex because they are two different platforms, so there are no common types between them. Even what we see as the "same type" is actually not the same type at all...

Rocky

Not Ranked
Posts 13

Hi,

I'm just wondering what the final outcome of this was?

I see the 'bug' is closed as resolved, however when I try and use enums in a Silverlight/.Net mixed environment, I still receive the serialize error.

Is there an attribute i need to set on the enum to make this work???

Stuart

 

 

Top 10 Contributor
Posts 9,270

It sure looks like the fix was applied in April 2009:

http://www.lhotka.net/cslacvs/viewvc.cgi/core/trunk/Source/Csla.core/Serialization/Mobile/MobileFormatter.cs?r1=3787&r2=3934

Based on the code, I can't see how a special attribute or anything would be required - the serializer is just locating anything of type enum and is converting it to the underlying type.

Rocky

Not Ranked
Posts 13

Hi Rocky,

Thanks for the awesomely quick reply!

I've looked through all your CSLA light samples, and I can't see anywhere at all that you have ever used an enum as property type.

I've already converted all my PropertyInfo to now use <int>, but I'll make up a quick project later today to get the exact error that occurs.  (It was a few hours ago, and my memory doesn't span that far back ;-).)

Will post here later today.

Stuart

Top 10 Contributor
Posts 9,270

There's a unit test for this: BusinessObjectWithEnum() in the Silverlight serialization tests.

Rocky

Top 10 Contributor
Posts 628
skagen00 replied on Mon, Mar 15 2010 11:46 AM

Just wanted to mention that I am using the latest and I seem to be having an issue with enums as well. Using the very latest CSLA.

Type '<mytype>' with data contract name '<enumtype>:http://schemas.datacontract.org/2004/07/<ns>' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

I'm just going to use an integer for the property as I know that works, but just thought I'd mention this too.

 

Page 1 of 2 (24 items) 1 2 Next > | RSS

Copyright (c) 2006-2010 Marimer LLC. All rights reserved.
Email admin@lhotka.net for support.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems