DataContractSerializer using default properties - c#

Recently when I read the default behavior of DataContractSerializer, I get the rules from MSDN, however I do not understand the first rule which I extracted as below:
The DataContractSerializer infers a data contract from types without attributes using the default properties of the newly created types.
How do I interpret this statement, if some one has clear idea, could you help, I know that "without attributes", the attribute means DataContract attribute, however what does that "default properties" refer to. Is there something called "default properties" in a custom type?

If you a have type referenced within another class that has [DataContract] attribute, then DataContractSerializer will serialize the referenced type even if it is not attributed with [DataContract]. Serialization will happen on all public properties, unless the property is attributed with [IgnoreDataMember].
For example:
[DataContract]
public class ClassA
{
public ClassB MyData { get; set; }
public string SomeString { get; set; }
public int SomeNumber { get; set; }
}
public class ClassB
{
public string SomeOtherInfo { get; set; }
public int SomeOtherNumber { get; set; }
}
In the above code, ClassB will be serialized based on its default properties, which in this case are all the public properties: "SomeOtherInfo" and "SomeOtherNumber".

Related

System.Json - custom rules for property serialization skipping

I am trying to migrate from Newtonsoft.Json to System.Text.Json
However, I ran into a problem since I was using DefaultContractResolver.
My "custom" behaviour have these rules for property serialization:
Skip property serialization if it is marked with ReadOnly attribute
Skip property serialization in case of null (this is supported)
Skip property serialization which would serialize into an empty object
Example:
class Car
{
[ReadOnly]
public string Id { get; set; }
public string Name { get; set; }
public Person Owner { get; set; }
}
class Person
{
[ReadOnly]
public string Id { get; set; }
public string Name { get; set; }
}
Now, imagine, we have this data if no rules would apply.
{
"Id":"1234",
"Name":"Skoda",
"Owner":{
"Id":"abcd",
"Name":null
}
}
Now, if I serialize the object, I would like to get this instead.
{
"Name":"Skoda"
}
In order to ignore individual properties, you need to use the [JsonIgnore] attribute along with one of these conditions:
Always;
Never;
WhenWritingDefault;
WhenWritingNull.
You can also define a default ignore condition through the JsonSerializerOptions type.
If additional behavior is needed, you should write a custom converter.
Example:
class Person
{
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
public string Id { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Name { get; set; }
}
More information:
How to ignore properties with System.Text.Json
How to write custom converters for JSON serialization (marshalling) in .NET

Ignore Non Serialized property in BinaryFormatter Serialization

I have a class called Userand it is [Serializable] and inherited from base class IdentityUser an Entity Framework class and Non Serializable.
I have a property in Booking class with type User and Booking class is Serializable I am trying to serialize the booking object using BinaryFormatter but I can't because of IdentityUser class and I get this error :
'Type 'Microsoft.AspNet.Identity.EntityFramework.IdentityUser' in
Assembly 'Microsoft.AspNet.Identity.EntityFramework, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not marked as
serializable.'
Is there a way to ignore this property because I don't think there is away to make 'IdentityUser' as Serializable.
[Serializable]
public class User : IdentityUser
{
public String FirstName { get; set; }
}
[Serializable]
public class Booking
{
[ForeignKey("Guest")]
public string GuestId { set; get; }
public virtual User Guest { set; get; }
}
BinaryFormatter serializes the public and private fields of a object -- not the properties. For an auto-implemented property the secret backing field is what is actually serialized.
Normally, if you do not want a field to be serialized, you can apply the [NonSerialized] attribute, and BinaryFormatter will skip it. In c# 7.3 and later, it's possible to do this to the secret backing field of an auto-implemented property by using a field-targeted attribute:
[field: NonSerialized]
public virtual User Guest { set; get; }
See: Auto-Implemented Property Field-Targeted Attributes and What's new in C# 7.3.
Prior to c# 7.3 there is no way to apply an attribute to the backing field of an auto-implemented property. Thus you need to make the backing field be explicit:
[Serializable]
public class Booking
{
[ForeignKey("Guest")]
public string GuestId { set; get; }
[NonSerialized]
User guest;
public virtual User Guest { set { guest = value; } get { return guest; } }
}
Incidentally, if you need to serialize some of the information in User, you could consider implementing ISerializable, or replacing instances of User with serialization surrogates.

Scaffolding Not Detecting Complext Type Property in an Entity

I am using MVC Scaffolding + EF6 in a Web applicatioon project in VS 2013.
Domain classes (Entites) and the context (DbContext) are in two separate projects referenced by the Web project.
I have a Patient class which has a complex property like follows.
public class Patient
{
public int PatientId { get; set; }
// Some properties
// Complex property
public MyComplexType Complex { get; set; }
}
public class MyComplexType
{
public SomeType Property1 { get; set; }
public SomeOtherType Property2 { get; set; }
}
Problem:
MVC scaffolding engine does not detect the complex property in Patient class and generated views don't contain fields to show or edit that property. I tried decorating MyComplexType class with ComplexType attribute but it didn't work.
What can be done?
According to this post and Julie Lerman's book Programming Entity Framework: Code First, complex types can only contain primitive properties.
Conventional Complex Type Rules
Complex types have no key property.
Complex types can only contain primitive properties.
When used as a property in another class, the property must represent a single
instance. It cannot be a collection type.
In my case I am using an unconventional complex type so I should have decorated MyComplexType class with ComplexType attribute too.
public class Patient
{
public int PatientId { get; set; }
// Some properties
// Complex property
public MyComplexType Complex { get; set; }
}
[ComplexType]
public class MyComplexType
{
public SomeType Property1 { get; set; }
public SomeOtherType Property2 { get; set; }
}
public class SomeType
{
// primitive properties here
}
public class SomeOtherType
{
// primitive properties here
}
HTH

Using Datacontract: WCF

How should i be declaring the datacontracts
My Operation contract has a Method:
Apple GetApples()
My data Contract Apple looks Like
[DataContract]
public class Apple
{
[DataMember]
public int Id { get; set; }
[DataMember]
public FruitType type { get; set; }
}
As there is another member of type FruitType.
[DataContract]
public class FruitType
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string type { get; set; }
}
OR
as a simple class
public class FruitType
{
public int Id { get; set; }
public string type { get; set; }
}
What is the difference between these two? other than that the simple type is not a datacontract and will depende on how i want to use it.?
how should i declare it??
Those attributes give you the control over how your properties will be represented in different formats. For example for XML you can specify the XML Namespace and XML node names.
Even if you are happy with default property names and default namespace, when you try to serialize data to XML, your XML nodes will have weird names such as typek_BackingField.
In other words, if you use WCF you should use DataContract and DataMember attributes, even if you think it works fine the formatted data may not look what you expect. As a result it removes compatibility with other (non-WCF) systems. Or even when you don't share your types (contracts) with other WCF systems.

Set Json Attribute on existing class

I have an existing class in an external assembly which I can't change.
I would like to serialize an object from this class with Newtonsoft JSON.Net, but not all the properties.
Normally I can do this with the JsonIgnoreAttribute attribute like this:
public class TestJsonClass
{
public string PropA { get; set; }
[JsonIgnoreAttribute]
public string PropB { get; set; }
}
But since I can't change the class, is there a way to ignore a property without attributes?
Try inherit class and override property with appropriate annotations or copy property values in a completely new class.

Categories