[ServiceContract]
[ServiceKnownType(typeof(DBReq))]
public interface IDAService
{
[DataContract]
[KnownType(typeof(IDataParameterCollection))]
public class DBReq : DBAccess
{
[DataMember]
public IDataParameterCollection DataParams
{
...
Why does DataParams deserialize to type of Object on my client side?
Your [KnownType(typeof(IDataParameterCollection))] is not correct. You should pass the implementing types to the KnownType attribute.
For example
public class MyType : IDataParameterCollection {...}
[DataContract]
[KnownType(typeof(MyType))]
public class DBReq : DBAccess
{
[DataMember]
public IDataParameterCollection DataParams
{
...
Related
In WCF I have a nullable int property on person object. What i want to do is that when the client explicitly passes NULL then i should update the database table to null, if they do NOT send this optional parameter then ignore.
Example code below. What i have foind is that there seems to be no easy way to do this.
[ServiceContract]
public interface IPersonRepository
{
[OperationContract]
string UpdatePerson(Person person);
}
public class PersonRepository : IPersonRepository
{
public string UpdatePerson(Person person)
{
return person.ToString();
}
}
[DataContract]
public class Person
{
[DataMember(IsRequired = false)]
public int? Age{get;set;}
}
I am using interface as input parameter in OperationContract. But when i generate proxy class at client side. I am not able to access the members of interface or class implemeting the ITransaction interface. I am only geeting is object
Service Interface
[ServiceContract]
public interface IServiceInterface
{
[OperationContract]
string SyncDatabase(ITransaction TransactionObject);
}
Service class
class SyncService:IServiceInterface
{
public string SyncDatabase(ITransaction TransactionObject)
{
return "Hello There!!";
}
}
Interface
public interface ITransaction
{
ExpenseData ExpData { get; set; }
void Add(ITransaction transactionObject);
}
Data Contract
[DataContract]
public class Transaction:ITransaction
{
[DataMember]
public ExpenseData ExpData
{
get;
set;
}
public void Add(ITransaction transactionObject)
{
}
}
In above case should i also copy the iTransaction class and interface on client
You actually need to make your ServiceContract aware of the implementation of the interface you pass as a parameter, so WCF will include it in the WSDL.
This should work:
[ServiceContract]
[ServiceKnownType(typeof(Transaction))]
public interface IServiceInterface
{
[OperationContract]
string SyncDatabase(ITransaction TransactionObject);
}
Use [KnownType(typeof(testClass))].
Refer these links:
msdn.microsoft.com/en-us/library/ms730167.aspx
www.codeproject.com/Tips/108807/Implementing-KnownType-Attribute
Try making your interface the [DataContract] and use the [KnownType] attribute to tell WCF what the known implementations of that interface are.
[DataContract]
[KnownType(typeof(Transaction))]
public interface ITransaction
{
[DataMember]
ExpenseData ExpData { get; set; }
void Add(ITransaction transactionObject);
}
Im trying to create a WCF which consumes a List
public class myClass {
public int ID { get;set;}
}
In my service i write
[DataContract]
public class myClass
{
public int ID { get; set; }
}
And my client nows the entity
ServiceReference2.myClass[] sendData = new ServiceReference2.myClass[2];
but when i would add a new myClass to the array like
ServiceReference2.myClass add1= new ServiceReference2.myClass();
the entity only exposes the field 'ExtensionData' and not the field ID
What am i doing wrong
You forgot to decorate the ID property with the DataMember attribute:
[DataContract]
public class myClass
{
[DataMember]
public int ID { get; set; }
}
I have following code
[ServiceContract(Namespace = "http://www.myweb.com/prod")]
public interface IBaseService
{
[OperationContract]
public string GetName(IDMessageContract ID)
}
[ServiceContract(Namespace = "http://www.myweb.com/prod/child")]
public interface IChildService : IBaseService
{}
public class BaseService
{ public string GetName(IDMessageContract ID)}
public class ChildService: IChildService
{}
[MessageContract]
public class IDMessageContract
{
public string ID{get;set;}
}
In above scenario I need the GetName method SOAP header containing the namespace "http://www.myweb.com/prod/child"
If you need SOAP header with specified namespace you must specify that header in message contract and use its Namespace property. Something like:
[MessageContract]
public class IDMessageContract
{
[MessageHeader(Namespace="http://www.myweb.com/prod/child")]
public string MyHeader { get; set;}
[MessageBodyMember]
public string ID{get;set;}
}
I have classes in my service defined as
[DataContract]
[KnownType(typeof(MyConcrete1)) ]
[KnownType(typeof(MyConcrete2)) ]
public abstract class MyAbstract
{
[DataMember]
public int AbsInt { get; set; }
}
[DataContract]
public class MyConcrete1 : MyAbstract
{
[DataMember]
public int Concrete1Int { get; set; }
}
[DataContract]
public class MyConcrete2 : MyAbstract
{
[DataMember]
public int Concrete2Int { get; set; }
}
and in my Service, I use it as
[ServiceContract]
public interface IService1
{
[OperationContract]
MyAbstract TestAbstract(MyAbstract value);
}
As you can see, the method TestAbstract takes and returns the abstract parameter MyAbstract, however in the client proxy generated by SvcUtil, the type "MyAbstract" is not abstract! It generated a concrete class.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name = "MyAbstract", Namespace = "http://schemas.datacontract.org/2004/07/WcfService")]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(WcfService.MyConcrete1))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(WcfService.MyConcrete2))]
public partial class MyAbstract : object, System.Runtime.Serialization.IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private int AbsIntField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public int AbsInt
{
get
{
return this.AbsIntField;
}
set
{
this.AbsIntField = value;
}
}
}
How can I force svcUtil to generate MyAbstract as an abstract class? I'm stuck, please help...
You cannot - svcutil cannot know that MyAbstract class is abstract. The metadata that's being exchanged between server and client just doesn't support such a concept. The SOA world doesn't always support everything the OO world has in store.
The service metadata only knows about things like services, method calls, and data contracts - anything else is not part of the service metadata.
You will need to add some extra logic and tweaking to the client code, once it's been creating, if that's a real requirement on your side.
Marc