Add DataMemberAttribute "on the fly" - c#

I have some types which are generated by a web service reference. I want to serialize these objects using the DataContractJsonSerializer, so I need to add DataContract and DataMember attributes. Adding DataContract is no problem using partial classes. But the properties have no DataMember attributes, so I only get empty objects. Is there a way to get this to work in case one cannot modify the serialized types?

Unlike XmlSerializer, I don't think (from memory) that there is a ctor for passing in this extra metadata at runtime. Perhaps another viable option is to have a twin DTO class that is attributed, and shuffle the data into there? You can add a conversion method / operator (between the two) in the partial class. Not ideal maybe, but it'll work.

Related

Possible to add a property to a JSON version of my class without it existing in the class?

I have a List<> of objects. Their class doesn't have a 'colour' property (String) - but I can derive the value of this property for each list element right before serializing.
Is the only way to include this property in the JSON object to add it to the class and then serialize the whole thing?
Or is there a way/approach to adding a property that needs to appear in a JSON object that would otherwise be pretty useless in my class?
I know it's possible with all sorts of string manipulation methods but it doesn't feel right doing that.
I'm using DataContractJsonSerializer.
You can create a data contract surrogate that transparently substitutes instances of your class with instances of another class. This new class can look like anything, but in your case it would simply have the additional Colour property.
The benefit here is that you keep the original type of the list items; the surrogates get created during the serialization process and your existing code will not need to touch them at all.
I supose you can create a new class that inherits from your List of objects and adds the string that's unuseful on the principal class.
When creating the JSON just use the derived class, which will contain the added string value and inherits all the rest data from the original object.

Can't clone object. Serialization issue

I have a class generated by Linq2Sql:
public partial class BuyerOrder : INotifyPropertyChanging, INotifyPropertyChanged
I want to clone object of this class, like it's done in this post. For this purpose I define the partial class in not generated file, which I mark as serializable:
[Serializable]
public partial class BuyerOrder
But when I'm calling
formatter.Serialize(stream, source);
I'm getting an exception, saying that this class is not marked as serializable. What am I doing wrong?
If you want to serialize a LINQ-to-SQL type, then tell the code-gen to emit serializable data. You can do this in the DBML, or more simply in the designer - just set the serialization mode to unidirectional (this is the #Serialization attribute on the root <Database> element in the DBML).
This will generate attribute markers suitable for use with DataContractSerializer; LINQ-to-SQL is designed to be serializable with DataContractSerializer. It is not designed to be serializable with BinaryFormatter.
Every class derived from BuyerOrder must also be decorated as [Serializable], as well as all objects that the serializing instance holds a reference to (unless decorated as NonSerializable).
The exception should tell you the type that is missing the serializable attribute. If you can not or do not want to decorate all the classes you will need to get a little more creative.
-- The other possibility --
One option is to use the technique described in Implementing a generic deep-clone for C# objects. Since this can be done entirely in memory and without a binary formatter it will perform many times faster than serialization based cloning.
The source code is located at http://csharptest.net/browse/src/Library/Cloning
It only takes two lines of code:
using (ObjectCloner cloner = new SerializerClone())
fooCopy = cloner.Clone(foo);

JSON.NET - exclude properties of a specific type at runtime

I'm wondering how to exclude/strip certain properties of given type(s) (or collections of those) from being serialized using Json.NET library?
I tried to write my own contract resolver (inheriting from DefaultContractResolver) with no luck.
I know that I could be done using DataAnnotations, decorating the excluded properties with ScriptIgnoreAttribute, but it's not applicable in my scenario. The objects serialized can be virtually anything, so I don't know which properties to exclude at design-time. I know only the types of properties that should not be serialized.
It looks like a rather simple task, but unfortunately I couldn't find a decent solution anywhere...
BTW - I'm not bound to Json.NET library - if it can easily be done with default/other .NET JSON serializers it'd be an equally good solution for me.
UPDATE
The properties has to be excluded before trying to serialize them. Why?
Basically, the types of objects I'm receiving and serializing can have dynamic properties of type inheriting from IDynamicMetaObjectProvider. I'm not going to describe all the details, but the DynamicMetaObject returned from GetMetaObject method of these objects doesn't have DynamicMetaObject.GetDynamicMemberNames method implemented (throws NotImplementedException...). Summarizing - the problem is those objects (I need to exclude) doesn't allow to enumerate their properties, what Json.NET serializer tries to do behind the scenes. I always end up with NotImplementedException being thrown.
I have tried both the WCF JSON serialization as well as the System.Web.Script.Serialization.JavaScriptSerializer. I have found if you want solid control of the serialization process and do not want to be bound by attributes and hacks to make things work, the JavaScriptSerializer is the way to go. It is included in the .NET stack and allows you to create and register JavaScriptConverter subclasses to perform custom serialization of types.
The only restriction I have found that may cause you a problem is that you cannot easily register a converter to convert all subclasses of Object (aka, one converter to rule them all). You really need to have knowledge of common base classes or preregister the set of types up front by scanning an assembly. However, property serialization is entirely left up to you, so you can decide using simple reflection which properties to serialize and how.
Plus, the default serialization is much much much better for JSON than the WCF approach. By default, all types are serializable without attributes, enums serialize by name, string-key dictionaries serialize as JSON objects, lists serialize as arrays, etc. But for obvious reasons, such as circular trees, even the default behavior needs assistance from time to time.
In my case, I was supporting a client-API that did not exactly match the server class structure, and we wanted a much simpler JSON syntax that was easy on the eyes, and the JavaScriptSerializer did the trick every time. Just let me know if you need some code samples to get started.
Create your own contract resolver, override the method that creates the properties for an object and then filter the results to only include those that you want.
Have you considered using the ShouldSerialize prefix property to exclude the property of your specific type at runtime?
public class Employee
{
public string Name { get; set; }
public Employee Manager { get; set; }
public bool ShouldSerializeManager()
{
return (Manager != this);
}
}

Defining the fields to be exposed (serialized) not via DataMemberAttribute

I have an autogenerated class, which I want to partially reuse as DataContract. Since the class is periodically auto-regenerated, I wouldn't like to add DataMemberAttribute to its properties, because it will be lost. What are the alternatives? Can I define which properties are going to be serialized programmatically or, may be, via a partial class?
Thanks!
You can add XmlAttributes at runtime with the XmlAttributeOverrides class but I'm not sure if you can do the same with DataMemberAttribute, have not come across an equivalent of XmlAttributeOverrides..

Why can't I serialize an object using DataContractSerializer?

I'm trying to serialize a type using the DataContractSerializer and am getting the exception below. This isn't for an SOA service, but I would still like to use the DataContractSerializer if possible. I am using .Net 3.5 SP1.
Type
'System.DelegateSerializationHolder+DelegateEntry'
with data contract name
'DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System'
is not expected. 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.
Can you post your class definition?
It seems like you are trying to serialize a class which has a field of type delegate, which I'm pretty sure will make the serializer choke on.
Did you decorate your class with the DataContract / DataMember attributes? In 3.5 SP1 there is a default behavior for the serializer that serializes everything public in a class by default if it is not marked with those attributes. Maybe you should explicitely mark each property that needs to be serialized with a DataMember attribute and leave out those that should not be.
Other than that, we would need to see your class definition for more help.
There are 3 possible approaches to avoid the error described in http://blogs.microsoft.co.il/blogs/oshvartz/archive/2009/10/10/passing-event-handlers-over-wcf.aspx

Categories

Resources