Sorry for a very simple question, I can't seem to find an answer. I'm trying to write a datacontract for a WCF service to receive the following xml:
<?xml version="1.0"?>
<CachedAwiData QReference="3" QAttempt="0" QReservation="{D6154D1C-6D42-4AA5-9FAC-217B2F9FE096}">
<CachedAwiDataRecord>
<CustRef><![CDATA[1]]></CustRef>
<Details><![CDATA[Hello World]]></Details>
<PrefDay><![CDATA[Monday]]></PrefDay>
<PrefTime><![CDATA[8.00am - 9.00am]]></PrefTime>
<Priority><![CDATA[Urgent]]></Priority>
<Trade><![CDATA[Plasterer]]></Trade>
</CachedAwiDataRecord>
</CachedAwiData>
so far I have tried a couple of things and got as far as:
[DataContract(Namespace = "")]
public class CachedAwiData
{
}
[DataContract(Namespace = "")]
public class CachedAwiDataRecord : CachedAwiData
{
[DataMember]
public string CustRef { get; set; }
}
I've got as far as getting a response that seems to get a null value for CustRef:
<ResponseData xmlns="http://schemas.datacontract.org/2004/07/RestService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><CustRef i:nil="true" /></ResponseData>
I'm assuming its to do with my DataContract but perhaps I'm missing something here. Any clues greatly appreciated or am I best just going back to XML Serializer?
I don't think the inheritance is right. I don't use DataContracts much but I think you need something like
[DataContract(Namespace = "")]
public class CachedAwiData
{
[DataMember]
public CachedAwiDataRecord DataRecord;
}
[DataContract(Namespace = "")]
public class CachedAwiDataRecord
{
[DataMember]
public string CustRef { get; set; }
}
Related
I am not sure did anyone had this type of problem. Can you please give some clues with the approach i am trying in WCF.
I have say 100 dlls registered in server GAC. When my WCF client invokes with the name of the dll, WCF service should look in to the GAC using reflection and create instance for that and send it back to the client. I dont know anything about 100 dlls and all those are POCO objets.
I tried and and was getting errors at serialization of datacotract. Below is my datacontract.
[DataContract]
public class RDSContract
{
private Type _oType;
private Object _oObject;
private string _strOutput;
[DataMember]
public Type TypeProp { get; set; }
[DataMember]
public Object ObjectProp { get; set; }
[DataMember]
public string StrOutput { get { return _strOutput + " test"; } set { _strOutput = value; } }
}
I am learning wcf, and I am seeing this opt in and opt out serialization. I am still scratching my head. I have already seen this SO post. But it didn't help. Can someone explain me succinctly what it is?
actually its so simple:
Opt-In approach says properties that are considered to be part of DataContract must be explicitly marked othewise will be ignore, while Opt-Out means all of the properties will be assumed to be part of the DataContract unless marked explicitly.
namespace MySchoolService
{
[DataContract]
public class Student
{
[DataMember]
public string StudentNumber;
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
public string MarksObtained;
}
[ServiceContract]
public interface IStudentService
{
//Service Code Here.
}
}
In above code StudentNumber, FirstName, LastName properties of Student class are explicitly marked with DataMember attribute as oppose to MarksObtained, so MarksObtained will be ignored.
Below code represents an example of Opt-Out approach.
namespace MySchoolService
{
[Serializable()]
public class Student
{
public string StudentNumber;
public string FirstName;
public string LastName;
[NonSerialized()]
public string marksObtained;
}
[ServiceContract]
public interface IStudentService
{
//Service Code Here.
}
}
In above example, we explicitly marked MarksObtained property as [NonSerialized()] attribute, so it will be ignored except the others.
hope could help you.
I have the following class I'd like to send from my WCF (C#) service to my client (WPF):
[DataContract]
public class OutputAvailableEventArgs
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Message { get; private set; }
[DataMember]
public bool IsError { get; private set; }
public OutputAvailableEventArgs(int id) : this(id, false, "") { }
public OutputAvailableEventArgs(int id, string output) : this(id, false, output) { }
public OutputAvailableEventArgs(int id, bool isError, string output)
{
ID = id;
IsError = isError;
Message = output;
}
}
It's used by the service as follows:
var channel = OperationContext.Current.GetCallbackChannel<IClientCallback>();
channel.OutputAvailable(new OutputAvailableEventArgs(1, false, "some message"));
At the client side, the members get their default values.
I tried marking them with IsRequired attribute but now the OutputAvailable at the client is not called. The code at the service side seems to run smoothly (I didn't notice anything with the debugger).
How can I transfer a DataContract class with WCF while maintaining the members' values?
(I saw solutions that suggested to use OnSerialized and OnDeserialized but I don't need just a default constructor.)
I saw many different solutions for this problem. For other people's sake I'll write some of them down + what worked for me:
It seems that in some cases specifying the items' order solves the problem. Please see this SO question for full details.
If it's some default initialization you're after, you can use OnSerialized and OnDeserialized methods to call your initialization methods.
I also tried using the IsRequired attribute on my DataMembers but still didn't get my objects.
What worked for me was adding NameSpace property in the DataContract attribute. Apparently, In order to have the contracts be considered equal, you must set the Namespace property on the DataContract to the same value on both sides.
I'm trying to create a WCF SOAP service that has a service method that accepts bare parameters in the body but I just cant make it happen. At the moment, the method name element is being created under the body. I'm trying to use ws-addressing so that the method name is part of the header and the parameters are the direct children of the body.
Here's my service implementation:
[SoapDocumentService(Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Bare)]
public class Service1 : IService1
{
[SoapDocumentMethod(Use=SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Bare)]
public void DoWork([XmlElement(Namespace = "http://www.contoso.com",
IsNullable = true)] MyClass wrapper)
{
}
}
[XmlRoot(Namespace = "http://www.contoso.com")]
public class MyClass
{
public int Value { get; set; }
public string MyProperty { get; set; }
}
[ServiceContract]
public interface IService1
{
[OperationContract]
void DoWork(MyClass wrapper);
}
The above implementation generates the soap client below. But I'm trying to have the wrapper element as the direct child on body (trying to remove DoWork). From what I've read, decorating the svc method to use bare parameters should remove the service method name (DoWork) and use ws-addressing.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/" xmlns:web="http://schemas.datacontract.org/2004/07/WebApplication2">
<soap:Header/>
<soap:Body>
<tem:DoWork> <!-- I want to remove this svc method name element -- >
<tem:wrapper> <!-- I want this to be under the body -->
<!--Optional:-->
<web:MyProperty>?</web:MyProperty>
<!--Optional:-->
<web:Value>?</web:Value>
</tem:wrapper>
</tem:DoWork>
</soap:Body>
</soap:Envelope>
I've followed the guide from msdn to decorate the service method. MSDN Link
I think you should drop the wrapper. in .net 2 this would work, wcf should be similar:
[WebMethod]
[SoapDocumentMethod(ParameterStyle=SoapParameterStyle.Bare)]
public String EchoString(String s, String s1)
{
return s;
}
I had to create message contracts wrapper for the MyClass and specify the message body.
[MessageContract]
public class MyWrapper
{
[MessageBodyMember]
public int Value { get; set; }
[MessageBodyMember]
public string MyProperty { get; set; }
}
[DataContract]
Base
{
[DataMember]
public int Id {get;set;}
}
[DataContract]
A : Base
{
[DataMember]
public string Value {get;set;}
}
[ServiceContract]
interface IService
{
[OperationContract]
void SetValue (Base base);
}
is there a way to use the service like the following style:
new Service ().SetValue (new A ());
You tagged this WCF so I assume you want to use it.
You need to connect to the endpoint using the ChannelFactory and then open the channel.
This will not work:
new Service ().SetValue (new A ());
You need to do smth. like this:
using (var scf = new ChannelFactory< IService >(<Binding>,<EndpointAddress>)
{
IService proxy = scf.CreateChannel();
proxy.SetValue(new (A));
}
This will return you a proxy object that implements the IService interface. You can call the SetValue on this object.
As well as changing the way you're calling the service as indicated by #Flo, you'll also need to make a small change to prepare the Data Contract Serializer to deal with the inheritance hierarchy.
The easiest way of doing this is decorating Base with the KnownTypeAttribute. Like this,
[DataContract]
[KnownType(typeof(A))]
Base
{
[DataMember]
public int Id {get;set;}
}
[DataContract]
A : Base
{
[DataMember]
public string Value {get;set;}
}