I have a situation that I can't figure out. I have two object classes:
[Serializable]
[DataContract]
public class Instrument
{
[DataMember]
public string Name {get; set;}
[DataMember]
public string Id {get; set; }
[DataMember]
public bool HideMe {get; set;}
}
[Serializable]
[DataContract]
public class Order
{
[DataMember]
public string Code {get; set;}
[DataMember]
public string OrderId {get; set; }
[DataMember]
public Instrument Inst {get; set;}
}
My code tries to serialize a JSON message of Orders. I can see in the JSON string that instrument data exists but the serialized order objects contain blank Instrument objects.
Can anyone explain this?
Thanks for the replies. The issue was that I hadn't rebuilt and released the windows service that sends the JSON.
Related
I would like to do a deep copy of an object. This object has some normal string, int, properties but it would also have custom objects (e.g. a list of custom objects).
Is there a way to do a deep copy where I pick and choose which properties to copy?
e.g. I want to copy
public class BankAccount
{
[Required]
[DeepCopy]
public string Number { get; }
[Required]
[DeepCopy]
public string Owner { get; set; }
[Required]
[DeepCopy]
public decimal Balance { get; }
[Required]
[DeepCopy]
public List<CustomAddress> {get; set;}
[Required]
public List<CustomLinkedAccounts> {get; set;}
}
Where perhaps I would want to copy everything except the List of CustomLinkedAccounts.
This is a solution I have used in the past for deep cloning.
It requires Newtonsoft JSON library.
It can be adapted to use System.Text.Json if you can't use third party libraries.
using Newtonsoft.Json;
public class BankAccount
{
[Required]
public string Number { get; }
[Required]
public string Owner { get; set; }
[Required]
public decimal Balance { get; }
[Required]
public List<CustomAddress> {get; set;}
[Required]
[JsonIgnore]//this is not in the json
public List<CustomLinkedAccounts> {get; set;}
public BankAccount Clone()
{
var json = JsonConvert.SerializeObject(this);
var result = JsonConvert.DeserializeObject<BankAccount>(json);
//this is a deep copy... no reference issues
return result;
}
}
I have a weird problem:
I have a class A which contains a subclass B. class A is rather complex and changes frequently. I do need only a small fraction of the properties of class A and a complete json representation of class B, to pass it on to a different service.
This looks like this
[DataContact]
public class A
{
[DataMember]
public B Inner {get; set;}
}
[DataContact]
public class B
{
[DataMember]
public int SomeThing {get; set;}
}
What I would like to achieve is this:
[DataContact]
public class ADesired
{
[DataMember]
public B Inner {get; set;}
[DataMember]
public string InnerAsJsonString {get; set;}
}
I tried the most obvious ideas (e.g. a Jsonproperty which refers to the same name, but NewtonSoft.Json refusses to make this work)
What I have tried so far:
JsonConverter, did not work at all.
JsonProperties:
[DataContact]
public class ADesired
{
[JsonProperty("Source")]
public B Inner {get; set;}
[JsonProperty("Source")]
public string InnerAsJsonString {get; set;}
}
Which does not work at runtime, since the reference to the same property is detected.
Nuclear option: Just deserialize the string twice in the controller, but this feels just wrong.
One option is to serialize it in the class
[DataContact]
public class ADesired
{
[DataMember]
public B Inner {get; set;}
public string InnerAsJsonString => Newtonsoft.Json.JsonConvert.SerializeObject(Inner);
}
If you don't care about performance, you could use JObject as the Json-Property type.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
[DatanContract]
public class ADesired
{
[JsonIgnore]
public B Inner { get; set; }
[JsonIgnore]
public string InnerJson { get; set; }
[DataMember]
[JsonProperty(nameof(Inner))
public JObject JInner
{
get => JObject.FromObject(Inner);
set { Inner = value.ToObject<B>(); InnerJson = value.ToString(); }
}
}
That way when deserializing, the actual json is saved as InnerJson and what can be, is deserialized into Inner, and when serializing back, whatever is in Inner will get serialized.
Let me explain my problem.
So I have JSON:
{"num":20, "meta":[{"id":312, "identif":{"type":true,"status":false}}}]}
I am currently grabbing the meta id field with:
var id = JsonConvert.DeserializeObject<typeObj>
(returnJSON(ApiUrl)).meta[0].id;
class to refrence:
class typeObj
{
public int num {get; set; }
public List<metatypes> meta {get; set;}
}
class metatypes
{
public int id {get; set;}
}
The issue doesn't lay here though. I am trying to get the indentif status element from meta.
I have tried putting a list in metatypes like:
class metatypes
{
public int id {get; set;}
public List<idtypes> identif {get; set;}
}
class idtypes
{
public bool type {get; set;}
public bool status {get; set;}
}
Calling it with:
var id = JsonConvert.DeserializeObject<typeObj>
(returnJSON(ApiUrl)).meta[0].identif[0].status;
But when I try this it returns
'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1'
Looked around and couldn't find a direct solution to my problem.
You have an incorrect json for the desired structure:
Given classes:
class typeObj
{
public int num {get; set; }
public List<metatypes> meta {get; set;}
}
class metatypes
{
public int id {get; set;}
public List<idtypes> identif {get; set;}
}
class idtypes
{
public bool type {get; set;}
public bool status {get; set;}
}
Your json should look like (identif must be an array): (.NET Fiddle)
{"num":20, "meta":[{"id":312, "identif":[{"type":true,"status":false}]}]}
For the json in question your classes should be like this: (.NET Fiddle)
class typeObj
{
public int num {get; set; }
public List<metatypes> meta {get; set;}
}
class metatypes
{
public int id {get; set;}
public idtypes identif {get; set;}
}
class idtypes
{
public bool type {get; set;}
public bool status {get; set;}
}
I have a class named "City"
public class City
{
public int ID {get; set;}
public int StateID {get; set;}
public int CountryID{get; set;}
public string Name{get; set;}
.......
}
and i have an asp.net page named CityAdd.aspx, in this page i want to create a collection of city class that can be store in the viewstate.
Is it possible to make a Generic Collection Serializable?
do as below, add Serializable attribute
[Serializable]
public class City
{
}
I have a WCF service that I have built from an XSD from a client. The client XSD calls for a field named 3rdPartyTrackingNumber. Because in c# I can't have a field that starts with a number I have named it ThirdPartyTrackingNumber. Is there a meta tag or something that I can put on the column that will render it as 3rdartyTrackingNumber when serialized?
public class OSSShipmentGroup
{
public string status { get; set; }
public string shipmentNumber { get; set; }
public object shipFrom { get; set; }
public string carrierName { get; set; }
[Some meta tag here]
public string ThirdPartyTrackingNumber {get; set;}
public OSSOrderDates dates { get; set; }
public OSSOrderAddress[] address {get; set;}
public OSSOrderShipmentItem[] containedItems { get; set; }
public OSSShipmentInvoice[] invoice {get; set;}
}
I know I can implement ISerializable and make the changes in GetObjectData, but if it is only one field i was hoping I could just add a meta tag to the field.
It depends on what serializer you are using. For example if you are using DataContractSerializer which is the default in WCF basicHttpBinding and wsHttpBinding you could use the [DataMember] attribute
[DataMember(Name = "ABC")]
public string ThirdPartyTrackingNumber { get; set; }
If you are using XmlSerializer then the [XmlElement] attribute should do the job:
[XmlElement(ElementName = "ABC")]
public string ThirdPartyTrackingNumber { get; set; }
For WCF, the normal process is to annotate the class with [DataContract], an each property with [DataMember], which has an optional Name="foo" property.
Note that by adding the class-level attribute you are saying "I will explicitly tell you which members to serialize; you can't then just annotate the one you want to rename.