App fails with exception when it calls method Save(A a);
{"The formatter threw an exception while trying to deserialize the message: Error deserializing parameter http://tempuri.org/:infs. InnerException message was \" type Collection Api.BrainDictionary.Editor.DataTrasferObjects, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]] \ ", intended only for the return, would return null. Input stream includes elements of the collection that can not be added if the value of the instance is null . Try to initialize a collection in a method getter. \ ". For details, see InnerException. "}
but my collection "IFNLs" is not readonly
[DataContract]
public class A
{
[DataMember]
public List<B> GVs{get; set ;}
[DataMember]
public List<C> SREs{get;set;}
[DataMember]
public List<D> TEs{get;set;}
[DataMember]
public List<E> INFLs{get;set;}
}
[DataContract]
public class E
{
[DataMember]
public long Id {get;set;}
[DataMember]
public string Description{get;set;}
}
This bug does not appear if
1. Property "Infls" is empty, but not null; Other Properties are not empty.
2. Property "Infls" is not empty. Other Properties are empty.
Classes B,C,D,E do not refer to each other.
I think, may be, binding quotes are limited. But increasing binding quotes does not help me. I add to DataContractSerializerOperationBehaviour, and set maxItemsInObjectGraph, this solution does not help me too....
Related
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.
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 am programming a Azure WCF application.
A datacontract defined as below:
[DataContract]
public class UserInfo
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public int UserID { get; set; }
[DataMember]
public bool IsOnline { get; set; }
}
then I define a datacontract in my WCF service:
[DataContract(Name="UserInfo")]
public class ServiceUserInfo : UserInfo
{
[IgnoreDataMember]
public ICallback Callback { get; set; }
}
Then in the service contract, it will callback to client, the method as below
private void NoticeUsers(UserInfo currentuser)
{
var users = UserManager.GetAllActiveUsers();
foreach (var user in users)
{
if (user.UserName == currentuser.UserName)
continue;
user.Callback.UpdateUserList(currentuser);
}
}
Actually I pass a ServiceUserInfo object as parameter to the NoticeUsers method. Then an error will occurs as below:
There was an error while trying to serialize parameter http://tempuri.org/:user. The InnerException message was 'Type 'WCFServiceWebRole.ServiceUserInfo' with data contract name 'UserInfo:http://schemas.datacontract.org/2004/07/WCFServiceWebRole' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
I am not able to find solution for this issue.Please help.
I think I have found the root cause of the issue, however I do not know why.
The problem is caused by the Namespace attribute of the Service contract.
I didn't set the namespace of my service contract interface and data contract interface. I thought it would be set by default and it won't cause any problem. But actually the issue of this thread is caused by the Namespace attribute. I set a Namespace attribute for both service contract and data contract, of course the same namespace, then it worked. The problem never happens again.
However, I do not know why it caused this issue. If I do not set Namespace, it will be a default value of "http://tempuri.org", isn't it?
I am having problem transfering my object from WCF to SL3.
interface IComposite {
ICollection<Child_A> Children{ get; set; }
}
[DataContract]
[knownType(typeof(ChildCollection))]
[knownType(typeof(ICollection<Child_A>))]
class Composite : IComposite {
ChildCollection c = null;
[DataMember]
public string Name { get;set;}
[DataMember]
public ICollection<Child_A> Children { get {
return c??(c=new ChildCollection());
} set;}
}
[CollectionDataContract]
class ChildCollection : List<Child_A> {
}
[DataContract]
class Child_A {
[DataMember]
string Name { get;set; }
}
[OperationContract]
Composite GetData(){
var data = new Composite();
data.Children.Add( new Child_A() { Name = "child_a_1" } );
return data;
}
When I call the service from SL3, I get the Composite object but no item in the list. There are other collection in Composite. When I set [DataMember(Order=0/1)] I get error nullreference error on client. And if I remove it, I get error Not Found. I tried KnowType and ServiceKnownType but did not work. I checked svcTrace, it simply says Serialization Error. Where I am doing wrong.
SVC TRACE
The InnerException message was 'Type 'xxxCoverageEntity' with data contract name 'xxxCoverageEntity : http://schemas.datacontract.org/2004/07/xxxBusinessEntities' is not expected. Add any types not known statically to the list of known types
Here xxxCoverageEntity is Child_A in sample
You need to annotate the collection with DataMember or it will not get serialized at all. You will also need to annotate the DataContract with KnownType(typeof(ChildCollection)) as otherwise it doesn't know what type of "thing" the ICollection is and therefore how to serialize it
Similarly you will need to add [DataMember] to Child_A Name property or it will not get serialized
I would like to use a base message class like:
[Serializable]
public abstract class MessageBase : IMessage
{
public Guid MessageID { get; private set; }
public DateTime UtcDateTime { get; private set; }
protected MessageBase()
{
UtcDateTime = DateTime.UtcNow;
MessageID = Guid.NewGuid();
}
public override string ToString()
{
return string.Format("{0} MessageID={1}, UtcDate={2}", GetType().FullName, MessageID, UtcDateTime);
}
}
New messages will be created by subclassing from this base class. Here is the problem I observed. When I publish a message, I see that the message id and datetime is different when it is handled.
What am I missing?
I know you want to declare MessageID and UtcDateTime with private setters so that someone down the line can't change it, but in doing so, you prevent the serializer from re-applying those values when the message is reconstructed at the receiver.
What is happening is that the serializer instantiates a new instance of your message type, and your two properties are initialized to UtcNow and NewGuid(), and then aren't overridden from the message. This is why they appear different.
If you remove the private keyword from the property declaration, you should get the behavior you are expecting.
However, instead of baking your own tracking mechanisms like this, you should at least (assuming you have injected an IBus into your handler) take a look at Bus.CurrentMessageContext, which contains an "Id" property for the message being handled (string, not Guid) and a Headers collection. I'm not 100% certain, but if you inspect the headers there is probably some indication of the original send time in there.