views:

1575

answers:

6

Has anybody got this to actually work? Documentation is non existent on how to enable this feature and I get missing attribute exceptions despite having a 3.5 SP1 project.

A: 

There are several serialization options in WCF: Data contract, XML Serialization and and raw data payload. Which of these are you trying to use? From the question, it seems you are trying to use something other than objects decorated with datacontact attributes. Is that what you are asking?

Doanair
A: 

Yes, I am attempting to use the attribute free serialization that was announced as part of SP1 (http://www.pluralsight.com/community/blogs/aaron/archive/2008/05/13/50934.aspx). Damned if I can get it to work and there's no documentation for it.

+1  A: 

I got this to work on a test app just fine...

Service Definition:

[ServiceContract]
public interface IService1
{

    [OperationContract]
    CompositeType GetData(int value);

}


public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";

    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}

Service Implementation:

public class Service1 : IService1
{
    public CompositeType GetData(int value)
    {
        return new CompositeType()
        {
            BoolValue = true,
            StringValue = value.ToString()
        };
    }

}
Doanair
Did the client actually get the data back?
Jonathan Parker
A: 

Possibly my use of abstract base classes is confusing the matter, though I am adding everything into the known types list.

A: 

Yes, it could have to do with abstract classes and inheritance. It sometimes can mess with serialization. Also, it could be visibility of the classes and class hierarchy as well if everything is not public.

Doanair
+1  A: 

I found that it doesn't work with internal/private types, but making my type public it worked fine. This means no anonymous types either :(

Using reflector I found the method ClassDataContract.IsNonAttributedTypeValidForSerialization(Type) that seems to make the decision. It's the last line that seems to be the killer, the type must be visible, so no internal/private types allowed :(

internal static bool IsNonAttributedTypeValidForSerialization(Type type)
{
    if (type.IsArray)
    {
         return false;
    }
    if (type.IsEnum)
    {
        return false;
    }
    if (type.IsGenericParameter)
    {
        return false;
    }
    if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type))
    {
        return false;
    }
    if (type.IsPointer)
    {
        return false;
    }
    if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false))
    {
        return false;
    }
    foreach (Type type2 in type.GetInterfaces())
    {
        if (CollectionDataContract.IsCollectionInterface(type2))
        {
            return false;
        }
    }
    if (type.IsSerializable)
    {
        return false;
    }
    if (Globals.TypeOfISerializable.IsAssignableFrom(type))
    {
        return false;
    }
    if (type.IsDefined(Globals.TypeOfDataContractAttribute, false))
    {
        return false;
    }
    if (type == Globals.TypeOfExtensionDataObject)
    {
        return false;
    }
    if (type.IsValueType)
    {
        return type.IsVisible;
    }
    return (type.IsVisible && (type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, Globals.EmptyTypeArray, null) != null));

}