WCF object parameter loses values - wcf

I'm passing an object to a WCF service and wasn't getting anything back. I checked the variable as it gets passed to the method that actually does the work and noticed that none of the values are set on the object at that point. Here's the object:
[DataContract]
public class Section {
[DataMember]
public long SectionID { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public string Text { get; set; }
[DataMember]
public int Order { get; set; }
}
Here's the service code for the method:
[OperationContract]
public List<Section> LoadAllSections(Section s) {
return SectionRepository.Instance().LoadAll(s);
}
The code that actually calls this method is this and is located in a Silverlight XAML file:
SectionServiceClient proxy = new SectionServiceClient();
proxy.LoadAllSectionsCompleted += new EventHandler<LoadAllSectionsCompletedEventArgs>(proxy_LoadAllSectionsCompleted);
Section s = new Section();
s.SectionID = 4;
proxy.LoadAllSectionsAsync(s);
When the code finally gets into the method LoadAllSections(Section s), the parameter's SectionID is not set. I stepped through the code and when it goes into the generated code that returns an IAsyncResult object, the object's properties are set. But when it actually calls the method, LoadAllSections, the parameter received is completely blank. Is there something I have to set to make the proeprty stick between method calls?

Works just fine for me - could it be a silly typo??
In your OperationContract, you define LoadAllSections but in your client code, you attach an event handler to the proxy.GetAllSectionsCompleted event - maybe that's just the wrong handler? Shouldn't it be proxy.LoadAllSectionsCompleted ??
Marc

This seems odd, but it's what happens. I had another method on the service that returned a DataTable. Whenever a method tries to return a DataTable, the parameters passed in lose their values. Take out the method, and everything works. Odd.

Related

In WCF Service, I need to send the DataMember based on the condition. How to do that?

For example:
Public class TEST
{
[DataMember]
public string EMPName
{
get; set;
}
}
I need EMPName to be the part of the object which is the output response, but based on some condition and I need to write that condition in the service function I am calling.
e.g: If the EMPName contains 'Jolie' then only keep it the part of the output object otherwise don't send it with the output object.
Use ShouldSerialize property in your TESTclass.
Include the line below in your TESTclass:
public bool ShouldSerializeEMPName() { return EMPName.Contains("Jolie"); }
Hope it helps

How to pass List<ABC> to WCF test client

I have DataContract as below
[DataContract]
public class Test
{
public List<Validation> val { get; set; }
}
and my OperationContract as below
public bool TestValidation(Test t, out string message)
{
return ValidationUtility.ValidateFields(t.val, out message);
}
I am not getting how to set value for Test.val on WCF Test Client
Firstly, it seems like you're missing the DataMember attribute for your list.
[DataContract]
public class Test {
[DataMember]
public List <Validation> val { get; set; }
}
Also, ensure that the DataContract and DataMember attributes for Validation are set up properly as well. Then restart your WCF Test Client and try calling the service again.
Expand the objvalidation part on the Name column. A + sign should appear next to the request parameter name. You can then add elements and fill out their properties (Value column) by expanding each individual element you've added.

mono rises unexpected compiler errors

I have the following class
public class LockRequest
{
public int Id { get; set; }
public string TypeName { get; set; }
public bool Ok { get; set; }
public LockRequest ( int id, string t)
{
Id = id;
TypeName = t;
}
}
Then, it's referenced in a delegate, as follows
private static void ReceiveLockRequest<LockRequest>(PacketHeader header, Connection connection, LockRequest input )
{
LockRequest lr = new LockRequest(1, "SomeTypeName" );
Console.WriteLine( String.Format ( "{0} ", input.TypeName) );
}
When compiling, both lines from the delegate rises compiler errors.
The line with the "new()", produces "Cannot create an instance of the type class 'LockRequest' because it does not have the 'new()' constraint.
The line which would show some of the input data gives "The type 'Lockrequest' does not contains a definition for 'TypeName' and no extension method 'TypeName' ... etc".
Could someone explain why is this behaviour?
My dev environment is Ubuntu 10.04 (64 bits) and Monodevelop 2.8.6.3
TIA
Could add some info.
I changed the name of the class, and the thing compiled. The whole class is to be serialised by ProtoBuf, so it must be decorated with attributes. Here are is a sample
[ProtoContract]
public class Foo
{
[ProtoMember(1)]
public int { get; protected set; }
[ProtoMember(2)]
public string TypeName { get; protected set; }
...
Just after I added the attributes, mono stop compiling. Same erors raise again.
To test it, I commented the attributes, do a Clean All, an recompile. The errors raise again, as if MonoDevelop cached them.
I need some help more than after the initial post.
2013-10-31
Thank you, Jester. It´s an event handler, from NetworkCommDotNet library.
My faults:
1) The first error (members not recognized) raises from the fact that (somewhat astobishing) the "input" argument comes as a plain object. Casting it in another method does the trick.
2) The error regarding the instanciation: the delegate definition in the library have a where clause wich states that T must be class, but no the new() constraint.
That's not a delegate, that's a generic method.
It's not clear what you want to do and why do you need a generic method.
If you really do, then try something along the lines of:
private static void ReceiveLockRequest<T>(PacketHeader header, Connection connection, T input) where T:LockRequest
PS: your development environment is very old, consider upgrading.

DataContract classes uninitialized at client side

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.

access wcf interface method from client

This is one of the classes in Interface file.
[DataContract]
public class ClassX
{
public ClassX()
{
ClassXParameters = new List<ClassXParameter>();
}
public void Add(string name, string value)
{
ClassXParameters.Add(new ClassXParameter() { Name = name, Value = value });
}
[DataMember]
public List<ClassXParameter> ClassXParameters { get; set; }
}
[DataContract]
public class ClassXParameter
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Value { get; set; }
}
on the client I'm trying to do something like this
ClassX classx = new ClassX();
classx.Add("testname", "testvalue");
But this .Add method is not even visible.
currently I'm doing
ClassX classx = new ClassX();
List<ClassXParameter> params = new List<ClassXParameter()>;
params.add(new ClassXParameter() {Name="testname", Value="testvalue"});
classx.ClassXParameters = params;
Is there anyway I can do what I'm trying to do?
Note: I am not sure why some of the text above are in bold.
If you autogenerate the client code from scratch, it will generate a new class, which contains those members and properties that are marked with DataContract.
If you have methods that you want available on the client, you can accomplish this by putting the DataContract types in an own assembly, which you reference from both the server and the client. When you generate the service reference you have to choose the option to reuse existing classes instead of generating new ones.
Often it is suitable to put data validation rules in the data contract classes property setters. Reusing the data contract assembly in the client will cause the data validation to occur directly on the client, without the need for a roundtrip. It also causes the error in a place where it is much easier to spot than if it is reported as deserialization error.
Data Contracts are for data only. Any methods will not be visible on the client.
The bold was because of the "-----".