[DataMember]
public int? NumberOfPages; //////////// Is this supported????
[DataMember]
public bool? Color; //////////// Is this supported????
[DataMember]
public int? BulkQuantity;
[DataMember]
Yes, of course!
You should have no trouble whatsoever to create nullable data members, they'll be handled in the resulting WSDL/XSD as "xs:nillable=true" members. No problem at all.
Yes, please see Types Supported by the Data Contract Serializer:
Nullable types are fully supported by the data contract serializer.
#Kahoon and Batwad:
We solved this problem by using the nullable<> or ? type in two steps:
In the class containing the generic field, define the field as follows:
nullable<GenType> MyField {get; set;}
In the data contract that uses this baseclass, you can define which elements are known to the serializer/deserializer using some annotation-like tags. Here, we defined for example:
[Serializable]
[DataContract]
[KnownType(typeof(BaseClass<nullable<DateTime>>))]
Instead of BaseClass<nullable<DateTime>> you can use BaseClass<DateTime?>, I think.
After this, the serialization of generic null values worked for us.
In my case It looks like that the Nullable Integer passed in is treated as Empty String and NOT Null Value
So here is how I handle the nullable in the code
[XmlIgnore]
public int? NumberOfPagesCount{ get; set; }
[XmlElement("NumberOfPages")]
public string NumberOfPagesText
{
get { return this.NumberOfPagesCount.HasValue ? this.NumberOfPagesCount.Value.ToString("F2") : string.Empty; }
set
{
if (!string.IsNullOrEmpty(value))
{
this.NumberOfPagesCount= Convert.ToInt32(value);
}
else
{
this.NumberOfPagesCount= null;
}
}
}
Related
In Salesforce/Apex how can i serialize an Apex Class to Json/String with a change of variable names mapping ? like in java we can use #SerializedName annotation.
So far, Apex does not support annotation for serialization. The supported annotations are
here
But, in this type of scenario, I always follows
public class TestClass
{
public string oldA { get; set; }
public string oldB { get; set; }
public string oldC { get; set; }
}
String jsonStr = JSON.serialize(objectTestClass);
jsonStr = jsonStr.replaceAll('"oldA":','"newA":');
You can use JSONGenerator to create the output yourself
There's no out of the box way for remapping variables via an annotation or a similar facility. To remap a variable you'd have to roll your own parser via JSONParser or use untyped deserialization and encapsulate it into your own Apex class.
I've recently upgraded to build 2230, and things are working just fine. However, I just updated the RavenDB .NET client assemblies and now I'm having this issue.
This code has been in place for a year or so. This is how I'm saving:
public void Save(EntityBase objectToSave)
{
using (IDocumentSession session = GetOptimisticSession())
{
session.Store(objectToSave, objectToSave.Etag);
session.SaveChanges();
}
}
And this is the object I'm saving.
public class InstallationEnvironment : EntityBase
{
public string Name { get; set; }
public int LogicalOrder { get; set; }
}
Now the base class:
public class EntityBase : NotifyPropertyChangedBase
{
public string Id { get; set; } // Required field for all objects with RavenDB.
}
The problem is that the base class property (Id) is getting persisted in RavenDB, but the derived properties (Name, LogicalOrder) are not.
Why would only the base class properties be saved in RavenDB?
Got it. Through trial and error, I noticed that one derived property was being saved (on a different class than the one shown in my question), and that property was decorated with the [DataMember] attribute. I just recently added it because I'm creating a WCF service for my app, and I started by using that attribute on one property for testing.
As Ayende states here, you have to use [DataMember] on all properties, or on none of them. If [DataMember] exists on a property, all others will be ignored.
Note: This was a problem for me even though [DataMember] was specified on a property in a different class. It seems like if I use [DataMember] anywhere, I have to use it for everything.
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 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'm trying to save a mapped entity using NHibernate but my insert to the database fails because the underlying table has a column that does not allow nulls and IS NOT mapped in my domain object. The reason it isn't mapped is because the column in question supports a legacy application and has no relevance to my application - so I'd like to not pollute my entity with the legacy property.
I know I could use a private field inside my class - but this still feels nasty to me. I've read that I can use an NHibernate interceptor and override the OnSave() method to add in the new column right before my entity is saved. This is proving difficult since I can't work out how to add an instance of Nhibernate.type.IType to the types parameter of my interceptor's OnSave.
My Entity roughly looks like this:
public class Client
{
public virtual int Id { get; set; }
public virtual int ParentId { get; set; }
public virtual string Name { get; set; }
public virtual string Phone { get; set; }
public virtual string Email { get; set; }
public virtual string Url { get; set; }
}
And my interceptor
public class ClientInterceptor : EmptyInterceptor
{
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
{
if (entity is Client)
{
/*
manually add the COM_HOLD column to the Client entity
*/
List<string> pn_list = propertyNames.ToList();
pn_list.Add("COM_HOLD");
propertyNames = pn_list.ToArray();
List<Object> _state = state.ToList();
_state.Add(false);
state = _state.ToArray();
//somehow add an IType to types param ??
}
return base.OnSave(entity, id, state, propertyNames, types);
}
}
Does anyone have any ideas on how to do this properly?
I can't say for sure since I've never actually done this (like Stefan, I also prefer to just add a private property), but can you just add a NHibernate.Type.BooleanType to the types array?
List<IType> typeList = types.ToList();
typeList.Add(new BooleanType());
types = typesList.ToArray();
EDIT
Yes, it looks like you are right; the types have an internal constructor. I did some digging and found TypeFactory:
Applications should use static
methods and constants on
NHibernate.NHibernateUtil if the
default IType is good enough. For example, the TypeFactory should only
be used when the String needs to have a length of 300 instead of 255. At this point
NHibernate.String does not get you thecorrect IType. Instead use TypeFactory.GetString(300) and keep a
local variable that holds a reference to the IType.
So it looks like what you want is NHibernateUtil:
Provides access to the full range of
NHibernate built-in types. IType
instances may be used to bind values
to query parameters. Also a factory
for new Blobs and Clobs.
typeList.Add(NHibernateUtil.Boolean);
Personally I wouldn't do it so complicated. I would add the private property and assign it a default value - finished. You could also consider a default value in the database, then you don't need to do anything else.
private virtual bool COM_HOLD
{
get { return false; }
set { /* make NH happy */ }
}
Before writing a interceptor for that I would consider to write a database trigger. Because with the Interceptor you are "polluting" your data access layer. It could make it unstable and you could have strange problems.