Why can I not use the KnownType attribute in my WCF class? - wcf

I am using WCF to retrieve a collection of objects. The objects are all of type ProcedureText but may be of child classes SuspensionText or ResumptionText, both of which inherit from ProcedureText.
public class ProcedureText { }
public class SuspensionText : ProcedureText { }
public class ResumptionText : ProcedureText { }
My OperationContract specifies a method returning an array of ProcedureText objects:
[OperationContract]
[WebGet(UriTemplate = "procedureTexts")]
ProcedureText[] GetProcedureTexts();
This works if I cast all my objects to ProcedureText but I want to keep the distinction of using the sub-types. I had hoped to use the KnownType attribute to do this and had expected to be able to do it by adding it to my ProcedureText class:
[System.Runtime.Serialization.KnownType(typeof(SuspensionTextDto))]
[System.Runtime.Serialization.KnownType(typeof(ResumptionTextDto))]
public class ProcedureText { }
This doesn't work because the compiler cannot resolve System.Runtime.Serialization.KnownType. I know from the document that the attribute is part of .NET Framework 4, but I am using .NET Framework 4 and that is the Target Frameweork for my project.
Why do I need to set to be able to use the attribute?

The relevant DLL containing that type is not added by default. You need to add a reference to:
System.Runtime.Serialization
The usage is described in the documentation:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx
Basically it is so that the serializer recognises the type. Your service contract returns an array of the base class, however the types in that array could be more derived. If the serializer is not told this, the serialization will fail I think.

Without explicitly adding the reference to the project, I was able to use " I was able to use "using System.Runtime.Serialization" in my code but when I used attributes like "KnownType" or "DataMember" the compiler gave an error.
I was able to overcome this issue by explicitly adding the reference. Go to "Add References" in your project and search for "System.Runtime.Serialization" under Assemblies and add the dll to the project.
Works in .net 4.5 and 4.5.1 so I assume this will work in 4.0 as well.

Related

WCF - Serialize abstact class and keep it abstract

I am new to WCF; I have an abstract class that in my WCF service.
I am referencing that WCF service from another application that invokes it: I have it added as a Service Reference in my Visual Studio project.
I managed to serialize the derived classes using the ServiceKnownType attribute, but I cannot manage to make the base class automatically abstract in the service reference code.
Any ideas?
I'm not sure whether this is something that will work in your case, but you can't (with the normal Add Service Reference tool) directly generate abstract classes.
However, all generated classes are partial, so if you know the namespace, all that's required to make it abstract is a new file with;
namespace whatever.the.service.reference.namespace.is {
abstract partial class MyClass { }
}
...and the class will be marked abstract.

You must implement a default accessor on System.Configuration.ConfigurationLockCollection because it inherits from ICollection

I have been looking online for quite some time about this error. I cannot seem to be able to figure this one out.
I have a web service created with vb.net in vs 2010. Here is a look at my property
Public Class MyClass
Inherits ConfigurationSection
Protected _score As Integer
<ConfigurationProperty("score", DefaultValue:="12", IsRequired:=False), _
IntegerValidator(ExcludeRange:=False, MinValue:=6, MaxValue:=24)>
Property gt_score() As Integer
Get
Return CType(Me("score"), Integer)
End Get
Set(ByVal value As Integer)
Me("score") = value
End Set
End Property
End Class
When I try to add this as a service to a web app, also done in vs2010 with vb.net, I get the error in the title. Please help with this. I am not sure what is needed in order to implement a default accessor.
I have been struggling with a similar problem myself. I have a class that inherits from ConfigurationSection but I get the same error message when I try to use it in conjunction with XMLSerializer.
I believe this issue cannot be addressed within your class. The problem lies with the properties of the ancestor (ConfigurationSection). It has 4 public properties of type ConfigurationLockCollection (namely LockAllAttributesExcept, LockAllElementsExcept, LockAttributes and LockElements). During serialisation, the serializer finds that these properties implement ICollection but do not have the required default accessors, hence the exception.
For my part I have tried shadowing these 4 properties and decorating them with the XMLIgnore() but still get the same problem. AFAIK it will not be possible to serialize any class that inherits from ConfigurationSection until MS adds the default accessor to ConfigurationLockCollection.
For now I will be implementing my own methods that serialize just the properties I need from my customised configuration section.
I haven't worked with VB.net, but in general, ICollection is an interface class.
An interface describes the methods and properties that classes inheriting from the interface need to define. In your case, your derrived class MyClass needs to define a default accessor.
What if you try:
get
{
return this;
}
I encountered the same problem. I resolved it by creating an XML wrapper object that just contains the properties I want to serialize and create two methods that map from the the unserializable object (a custom configuration element derived from ConfigurationElement) to the Attribute object and back.
I can then serialize/deserialize a collection of the simple objects.
See My Answer To This Question

DataContract attribute -WCF

Is DataContract attribute is deprecated in ASP.NET 4.0 WCF ? I can see only DataContractFormat attribute.
I can't apply DataContractFormat attribute over struct.
example
[DataContractFormat]
public struct Contact
{
public string firstName;
public string lastName;
}
It throws an error saying that DataContractFormat artribute can only be used on class, interface and methods.
No, the .NET 4 still contains the DataContractAttribute:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute%28v=VS.100%29.aspx
and it should be able to be applied to class or struct.
You have to add a reference to the System.Runtime.Serialization assembly (right click References, add ref...)
DataContract is not deprecated - where the heck did you get that idea from?
DataCOntractFORMAT is something totally different. I suggest you please read the documentation ;) Helps a lot. Will also explain what DataContractFormat is for.
http://msdn.microsoft.com/en-us/library/system.servicemodel.datacontractformatattribute.aspx
As you can see in the example this attribute goes on the class/interface that defines the SERVICE CONTRACT. It controls how for that service data serializaton is (guess what) formatted.

BlazeDS - Conversion from ArrayList <BaseClass> on java side to Actionscript

So we have a java class with two ArrayLists of generics. It looks like
public class Blah
{
public ArrayList<ConcreteClass> a;
public ArrayList<BaseClass> b;
}
by using [ArrayElementType('ConcreteClass')] in the actionscript class, we are able to get all the "a"s converted fine. However with "b", since the actual class coming across the line is a heterogeneous mix of classes like BaseClassImplementation1, BaseClassImplementation2 etc, it gets typed as an object. Is there a way to convert it to the specific concrete class assuming that a strongly typed AS version of the java class exists on the client side
thanks for your help!
Regis
To ensure that all of your DTO classes are marshalled across AS and Java, you need to define each remote class as a "remote class" in AS by using the "RemoteClass" attribute pointing to the java class definition like this [RemoteClass(alias="com.myco.class")].
BlazeDS will perform introspection on the class as it is being serialized/de-serialized and convert it appropriately (see doc below). It doesn't matter how the classes are packed or nested in an array, as long as it can be introspected it should work.
If you need special serialization for a class you can create your own serialization proxys (called beanproxy) by extending "AbastractProxy" and loading them into blazeds using the PropertyProxyRegistry register method on startup.
You will find most of this in the Blaze developers guide http://livedocs.adobe.com/blazeds/1/blazeds_devguide/.
Creating your own beanproxy class look here: //livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/BeanProxy.html

No parameterless constructer defined for this object when putting EnabledDelete=true on LinqDataSource

If I have a LinqDataSource without EnabledDelete, EnabledUpdate, EnabledInsert, it works fine, but as soon as I add those properties to the data source, I get the error:
No parameterless constructor defined for this object.
Here is an answer that helped me solve the issue from the MSDN forums:
LinqDataSource requires a default constructor on the DataContext. If you are working in a web application or website project, the Linq to SQL designer should have created a default constructor and connection string for you when you dragged tables from the database onto the design surface.
Did you create your DataContext and drag tables onto the design surface from a webapp or website project? Open the Lib.NorthwindDataContext class that was generated and see if it has the default constructor.
If you really want, you could also use LinqDataSource without the default constructor by handling the ContextCreating event and providing your own context instance.
As the error indicates, you need to provide a parameterless constructor for the class.
public class MyClass
{
public MyClass()
{
// This is the parameterless constructor
}
// rest of the class members goes here.
}
The system requires a parameterless constructor when it is required to create instances of a class automatically. It cannot determine the meaning of the parameters of your other constructors so it depends on this constructor.
Even if your constructor does nothing it will still work, though you may want it to provide useful defaults for your class properties.