Making property [NonSerialized] for a value - c#

I am trying to figure out how can i make a property [NonSerialized] for a value
Check this out :
using System;
using System.Text.Json;
class Test
{
public static bool GoingToBeSerialized = false;
public int PaymentForTheDay { get; set; }
public int NumberOfDays { get; set; }
// i want to disable it if GoingToBeSerialized is true
[System.Text.Json.Serialization.JsonIgnore]
public int TotalPayment;
public bool ShouldSerializeTotalPayment() => GoingToBeSerialized;
}
Thanks.

Note that [Serializable] and [NonSerialized] (in the original question, now removed in the edit) do nothing with most serializers - they only apply to BinaryFormatter, which you aren't using.
There's a very good chance that simply using:
public int TotalPayment {get;set;}
public bool ShouldSerializeTotalPayment() => GoingToBeSerialized;
will do what you want; with the recent addition of your pastebin that shows you're using Json.NET, this should indeed work - conditional serialization is a Json.NET feature using the standard pattern. Note also that I made TotalPayment a property, and removed the [JsonIgnore].

Related

Can I safely remove the fields and properties with the suffix Specified in my C# Model classes if I am only using JSON.Net

I have a C# Application.
I have a class that is generated from an xsd. The class looks as below
public class Transaction
{
public bool amountSpecified {get; set;}
public double amount {get; set;}
}
If you notice in the class above, along with the property amount, the generator has also generated a property called amountSpecified.
I know that the properties with suffix "Specified" are required for all non-nullable field/property, because this is the requirement of XML Serializer as mentioned in this [article][1].
However I only use JSON serialization and deserialization(with JSON.NET), do I still need those fields with "Specified" suffix? If I remove them should I make my fields/properties nullable as shown below?
double? amount;
My question being is all of this internally handled by JSON.Net? Can I safely remove all the fields with suffix "specified" and not make my fields nullable?
I would be very glad if someone can point me in the right direction.
Thanks in Advance.
As discussed since 2008, they fixed it to support nullable type. Also I tried with this code
using System;
using Newtonsoft.Json;
namespace TestJson
{
class Test {
public double? amount { get; set; }
}
class MainClass
{
public static void Main(string[] args)
{
string jsonStr = JsonConvert.SerializeObject(new Test());
string jsonStr2 = JsonConvert.SerializeObject(new Test { amount = 5 } );
Console.WriteLine(jsonStr);
Console.WriteLine(jsonStr2);
Console.ReadLine();
}
}
}
It works just fine:
{"amount":null}
{"amount":5.0}
And the properties with Specified suffix are not required.

Remapping a single tag while deserializing

I've refactored code like this:
public string CamelCASE { get; set; }
to:
public string CamelCase {get; set; }
only do discover that the input XML contains the former casing (let's call it a shouting camel). I have no control over how the XML document is produced. Nor do I burn of desire to retract my changes.
I'd like to map the loud camel property to a softly speaking one.
I've tried XmlElement and XmlMapping but to no greater success. A googling gave me only hits on how to map stuff to attributes, along lines of this post. However, I need only something like <LoudCAMEL> to be deserialized to a property public string QuietCamel.
Is there a smooth way to do so?
Edit
After adding the attribute as follows:
using System.Collections.Generic;
using System.Xml;
public class Beep : SuperBeep
{
private readonly BeepType _a;
public Beep() { _a = BeepType.SomeSome; }
public Beep(BeepType input) { _a = input; }
~Beep() { }
public override void Dispose() { }
public BeepType Aaa { get { return _a; } }
[XmlElement("CamelCASE")]
public bool CamelCase { get; set; }
}
I can see the red, wavy highlight telling me Cannot access constructor 'XmlElement' here due its protection level. When I compile, though, I get the IDE crying out loud that 'System.Xml.XmlElement' is not an attribute class.
Frankly, I'm a bit confused by the suggestion to use attributes (this is targeting .NET 2.0), since I was under the impression that attributing wasn't available to .NET prior to version 3.5. Am I mistaken?
[XmlElement("CamelCASE")]
public string CamelCase { get; set; }
should be all you need, if you are keeping the shouty name in the xml. If you want to use the quieter name in new xml, but allow the old name to still work, it gets more complicated. You could use:
public string CamelCase { get; set; }
[XmlElement("CamelCASE"), Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public string CamelCaseLegacy {
get { return CamelCase; }
set { CamelCase = value; }
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeCamelCaseLegacy() { return false; }
When serializing, the CamelCase property will serialize to <CamelCase>, and the CamelCaseLegacy element will be ignored due to the ShouldSerialize* method. However, when deserializing, the CamelCaseLegacy property will be used whenever <CamelCASE> is seen. We then map this value back to the CamelCase property.
You are referring to the wrong namespace.
Remove
using System.Xml;
and add
using System.Xml.Serialization;

Replacing XML serialization of class member

In my class (Camera), that I need to serialize, I have one member which doesn't have much serialization means and I can't modify its class. But there are only 2-3 parameters out of whole class that I can serialize and then de-serialize based on that.
XmlSerializer SerializerObj = new XmlSerializer(typeof(Camera));
TextWriter WriteFileStream = new StreamWriter(#"C:\test.xml");
SerializerObj.Serialize(WriteFileStream, cc);
WriteFileStream.Close();
How and where can I put custom serialization code, to take those 2-3 parameters from object and give to serializer, then during de-serialization create again that object using those 2-3 parameters.
Update. The example code:
[Serializable()]
public class Camera
{
public string name;
public int index;
public double distance;
public List<string> CameraList { get; set; }
[XmlIgnore()]
public GMarkerGoogle marker;
public Camera()
{
}
}
marker is the member that doesn't have serialization means. But there with marker.position, marker.rotation I can re-create that object.
If you can't or don't want to Xml serialize your GMarker then make sure that you do serialize the properties needed to reconstruct it (kind of what you already suggested). That way you can make a property with backing field to lazy recreate the GMarker.
[Serializable()]
public class Camera
{
public string name;
public int index;
public double distance;
public List<string> CameraList { get; set; }
private GMarkerGoogle _marker;
[XmlIgnore()]
public GMarkerGoogle Marker
{
set
{
_marker = value;
MarkerPosition = _marker.position;
MarkerRotation = _marker.rotation;
}
get
{
if (_marker == null)
{
_marker = new GMarkerGoogle(MarkerPosition, MarkerRotation);
}
return _marker;
}
}
public double MarkerPosition { get; set; }
public double MarkerRotation { get; set; }
public Camera()
{
}
}
Does this help? I made up a thing or two because I don't know the API for the marker, but I hope you can draw the picture from this point onwards.
By implementing the IXmlSerializable interface in your Camera class.
Check MSDN for more info.
Alternatively you could use the [XmlIgnore] attribute to flag the properties you do not want to serialize to XML.
Check MSDN for more info :).
PS: If you post some code I can show you an example but you probably don't need me. Let me know if you do though.

how to set a readonly property value in Json.net in the JsonConverter

I am using Json.net 4.5. I am using JsonConverter to convert the data from one version to another version.
Version 1
public class AV1
{
public string PNr { get; set; } // "x253yN-69Uj"
}
Version 2
public class AV2
{
public string FirstNr { get; private set; } // "x253yN"
public string LastNr { get; private set; } // "69Uj"
public void SetFirstAndLastNr(string a, string b, string c)
{
//Logic to set the values of FirstNr and LastNr
}
}
In the derived JsonConverter, I am creating the instance of AV2 class. But since properties are readonly properties now, how should i set the value of these properties? Does Json.net offers any methods to do the same? Or do i have to use reflection?
If you want to deserialize read-only property , maybe try this
public class AV2
{
[JsonProperty]
private readonly string _firstNr;
[JsonProperty]
private readonly string _lastNr;
public string FirstNr => _firstNr// "x253yN"
public string LastNr => _lastNr// "69Uj"
}
As you said you have hundreds different classes which needs to be converted, JsonDeserializer might not be the best choice.
It's not a bad idea to look at other solution like AutoMapper: http://automapper.org/ , https://github.com/AutoMapper/AutoMapper
If you spend an hour or two and look at the sample codes, you will find it so powerful and flexible to convert (map) different object to each other.

System.Reflection GetProperties method not returning values

Can some one explain to me why the GetProperties method would not return public values if the class is setup as follows.
public class DocumentA
{
public string AgencyNumber = string.Empty;
public bool Description;
public bool Establishment;
}
I am trying to setup a simple unit test method to play around with
The method is as follows and it has all the appropriate using statements and references.
All I'm doing is calling the following but it returns 0
PropertyInfo[] pi = target.GetProperties(BindingFlags.Public | BindingFlags.Instance);
But if I setup the class with private members and public properties it works fine.
The reason I didn't setup up the the class the old school way was because it has 61 properties and doing that would increase my lines of code to at least triple that. I would be a maintenance nightmare.
You haven't declared any properties - you've declared fields. Here's similar code with properties:
public class DocumentA
{
public string AgencyNumber { get; set; }
public bool Description { get; set; }
public bool Establishment { get; set; }
public DocumentA()
{
AgencyNumber = "";
}
}
I would strongly advise you to use properties as above (or possibly with more restricted setters) instead of just changing to use Type.GetFields. Public fields violate encapsulation. (Public mutable properties aren't great on the encapsulation front, but at least they give an API, the implementation of which can be changed later.)
Because the way you have declared your class now is using Fields. If you want to access the fields trough reflection you should use Type.GetFields() (see Types.GetFields Method1)
I don't now which version of C# you're using but the property syntax has changed in C# 2 to the following:
public class Foo
{
public string MyField;
public string MyProperty {get;set;}
}
Wouldn't this help in reducing the amount of code?
I see this thread is already four years old, but none the less I was unsatisfied with the answers provided. OP should note that OP is referring to Fields not Properties. To dynamically reset all fields (expansion proof) try:
/**
* method to iterate through Vehicle class fields (dynamic..)
* resets each field to null
**/
public void reset(){
try{
Type myType = this.GetType(); //get the type handle of a specified class
FieldInfo[] myfield = myType.GetFields(); //get the fields of the specified class
for (int pointer = 0; pointer < myfield.Length ; pointer++){
myfield[pointer].SetValue(this, null); //takes field from this instance and fills it with null
}
}
catch(Exception e){
Debug.Log (e.Message); //prints error message to terminal
}
}
Note that GetFields() only has access to public fields for obvious reasons.
As mentioned, these are fields not properties. The property syntax would be:
public class DocumentA {
public string AgencyNumber { get; set; }
public bool Description { get; set; }
public bool Establishment { get; set;}
}

Categories