This question already has answers here:
Add multiple items to a list
(5 answers)
Closed 3 years ago.
I was wondering if someone could help me. I have 2 classes:
`public class EventPutDto
{
//public string id { get; set; }
public string eventGbsCode { get; set; }
//public string portfolioId { get; set; }
public string businessUnitId { get; set; }
public List<Multilingual> multilingual { get; set; }
public bool supportedInPlatform { get; set; }
public bool gbsEnabled { get; set; }
public bool isParticipationEvent { get; set; }
}`
public class Multilingual
{
public string locale { get; set; }
public string name { get; set; }
}
I want to add a name and locale to the list property in the eventPutDto class. How do I do it? For example I want to add 3 locales so it should be something like
"en-gb" - "english name",
"it-it" - "italian name",
"es-es" - "spanish name"
I need to know this as I'm trying to post some Json to an endpoint.
Looks like what you want is a dictionary.
So, locale should not be of type string, but a Dictionary<string, string>
Read up on them, they are a collection of keys and values.
This question already has an answer here:
Deserializing JSON into an object
(1 answer)
Closed 5 years ago.
I have the following string of Json records:
{
"records":[
{
"PK":"1_1_8",
"ID":"8",
"DeviceID":"1",
"RootID":"1",
"CustName":"test1",
"CustSurname":"test2",
"Address":"Nisou 1",
"City":"",
"ZipCode":"",
"PhoneNumber":"45646",
"HomePhoneNumber":"",
"Email":"",
"Notes":"",
"Owner":"1",
"LanguageID":"1",
"LanguagePK":"",
"DeletedFlag":"false",
"created":"2017-10-25 10:15:00",
"modified":"2017-10-25 09:35:43"
},
{
"PK":"1_1_33",
"ID":"33",
"DeviceID":"1",
"RootID":"1",
"CustName":"",
"CustSurname":"",
"Address":"",
"City":"",
"ZipCode":"",
"PhoneNumber":"",
"HomePhoneNumber":"",
"Email":"",
"Notes":"",
"Owner":null,
"LanguageID":"0",
"LanguagePK":"",
"DeletedFlag":"true",
"created":"2017-10-25 10:13:54",
"modified":"2017-10-25 10:13:54"
},
{
"PK":"1_1_16",
"ID":"16",
"DeviceID":"1",
"RootID":"1",
"CustName":"Theodosis",
"CustSurname":"",
"Address":"Dali",
"City":"Nicosia",
"ZipCode":"2540",
"PhoneNumber":"45645",
"HomePhoneNumber":"99123456",
"Email":"theodosis#gmail.com",
"Notes":"",
"Owner":"",
"LanguageID":"1",
"LanguagePK":"",
"DeletedFlag":"false",
"created":"2017-10-25 09:36:22",
"modified":"2017-10-25 09:36:22"
}
]
}
I am using Xamarin PCL in C# trying to parse this string into a list of objects.
I have a Customer class:
public class Customer
{
[PrimaryKey]
public string PK { get; set; }
public int DeviceID { get; set; }
public int ID { get; set; }
public string RootID{ get; set; }
public string CustName { get; set; }
public string CustSurname { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string PhoneNumber { get; set; }
public string HomePhoneNumber { get; set; }
public string Email { get; set; }
public string Notes { get; set; }
public bool Owner { get; set; }
public int LanguageID { get; set; }
public string LanguagePK { get; set; }
public bool DeletedFlag { get; set; }
public DateTime created { get; set; }
public DateTime modified { get; set; }
}
I also tried out having a container class with a list of Customer objects.
public class DataContainer
{
public List<Customer> customers { get; set; }
}
I have seen quite a few of examples online on how to parse this into a list or any workable type but nothing seems to be working for me.
I have tried the following (JsonResults holds the string of Json records):
var observation = JsonConvert.DeserializeObject<DataContainer>(JsonResults);
From other posts, I am not able to access JavaScriptSerializer class from my code, perhaps because of the Xamarin PCL Framework I am using.
Any ideas would be very welcome, as I said I do not mind the format I parse the string into, as long as it's workable.
Thank you.
You would have to make the following changes to your code to make this work.
First and most importantly, you don't have a property customers, you have records, so either rename it
public class DataContainer {
public List<Customer> records { get; set; }
}
or add a JsonProperty attribute
[JsonProperty(PropertyName = "records")]
Secondly, your Owner is a bool in C# and a nullable int (int?) in Json. So either change it in your C# class
public int? Owner { get; set; }
or write a converter to do that (e.g. like here)
[JsonConverter(typeof(NullableIntToBooleanConverter))]
public bool Owner { get; set; }
Here is a working .NetFiddle
The JSON string you provided is a JSON object, which contains a single property called records. records property is a List<Customer>. You can not deserialize the given string directly into DataContainer class that you provided because the property names do not match.
In the Class that your provided it is called customers
public class DataContainer {
public List<Customer> customers { get; set; } //records
}
Or please have a look at the attribute for a bit of advanced mapping
[JsonProperty]
JSON you provided is of the form:
{"records":[{Customer},{Customer},{Customer}]}
But Owner property is "1", null or "". Therefore I would suggest redefining Owner as int? (nullable)
Your string shows one object with a property named records that contains a list of other objects. Your code is trying to deserialize this into an object that doesn't have such a property.
Furthermore, the string contains objects with a property Owner that may be missing or have a numeric value. It's definitely not a bool.
You'll have to change Owner to :
public int? Owner { get; set; }
To deserialize the string, you need an object with a records property:
public class DataContainer
{
public Customer[] records { get; set; }
}
var data=JsonConvert.DeserializeObject<DataContainer>(json);
Debug.Assert(data.records.Length == 3);
First of all I'm new to C#.
The error I get is:
Additional information: Unable to cast object of type 'UserGUI.MyItems' to type 'CommonBookLib.AbstractItem'.
They are 2 different classes:
public class MyItems
{
public string ItemName { get; set; }
public int CopyNumber { get; set; }
public int Guid { get; set; }
public DateTime? TimePrinted { get; set; }
public string Category { get; set; }
public string SubCategory { get; set; }
public bool? BestSeller { get; set; }
}
and
public class AbstractItem : IPropsDetails
{
public int CopyNumber { get; }
public string ItemName { get; }
public DateTime Time { get; }
public int Guid { get; }
public AbstractItem(int copyNumber, string itemName, DateTime time, int guid)
{
this.CopyNumber = copyNumber;
this.ItemName = itemName;
this.Time = time;
this.Guid = guid;
}
}
It happens when I do:
AbstractItem myItemsList = (AbstractItem)LibraryList.SelectedItem;
logicManager.Remove(myItemsList);
Well, as you can see, I have MyItems which are responsible for the DataBindings in my GUI and AbstractItem which responsible for implementing an addition operation to where my data is saved.
Since I did not managed my code well I got into this situation and I really do not want to change MyItems (delete and recode AbstractItem).
How can I Convert the two?
By the way, I know AbstractItem has only 4 properties while MyItems has more.
However, I have children with the exact same properties of AbstractItem.
Any help would be appreciated. Thanks in advance!
Remove fields from the MyItems class that are also present in AbstractItem, and then have MyItems derive from it instead.
You'll have to add a constructor to MyItems that passes the required values to the base constructor, or add an empty constructor to the base class.
public class MyItems : AbstractItem
{
public MyItems(int copyNumber, string itemName, DateTime time, int guid)
:base(copyNumber, itemName, time, guid)
{
}
public DateTime? TimePrinted { get; set; }
public string Category { get; set; }
public string SubCategory { get; set; }
public bool? BestSeller { get; set; }
}
You can make MyItems inherit AbstractItem, or make a method that handle the conversion between them.
You seem to need a mapper more than a cast. Look at AutoMapper or write your own routine as suggested by habibhassani. Also, Grant's answer is very good.
But your question was about casting so here I show how you can implement a casting operator so that your cast would work. This is not a technique you should reach for lightly. It puts a dependency on AbstractItem directly in MyItems and it is not the most discoverable pattern for maintainers of your code.
public class MyItems
{
public string ItemName { get; set; }
public int CopyNumber { get; set; }
public int Guid { get; set; }
public DateTime? TimePrinted { get; set; }
public string Category { get; set; }
public string SubCategory { get; set; }
public bool? BestSeller { get; set; }
public static explicit operator AbstractItem(MyItems myitems)
{
return new AbstractItem(myitems.CopyNumber, myitems.ItemName, myitems.TimePrinted, myitems.Guid);
}
}
A couple more observances. Naming your class AbstractItem is confusing, it implies that it is actually abstract but it is not.
Guid is a poor name for a property because it is already a Type. You have something named Guid that is an int - confusing.
I have objects that are defined this way:
class BFull
{
public string ImageID { get; set; }
public List<string> Tapes { get; set; }
}
class OptSet
{
public int SetID { get; set; }
public List<string> Tapes { get; set; }
public List<string> Images { get; set; }
}
The BFull object is DB defined and I can't alter it much. The second one is the wanted result of my actions. And the problem is:
I need to optimize those BFulls into OptSets with a limitation that any given OptSet can have max 24 distinct tapes and consist only complete BFulls. Can anybody help how to achieve that?
I have a number of classes that are all related conceptually, but some more-so at the details level than others. For example, these three classes have nearly identical properties (although member functions will vary):
public class RelatedA : IRelatedType
{
public string Name { get; set; }
public string Value { get; set; }
public DateTime Stamp { get; set; }
}
public class RelatedB : IRelatedType
{
public string Name { get; set; }
public string Value { get; set; }
public DateTime Stamp { get; set; }
}
public class RelatedC : IRelatedType
{
public string Name { get; set; }
public string Value { get; set; }
public DateTime Stamp { get; set; }
public int Special { get; set; }
}
There are a couple of other classes that are conceptually related to the above 3, but can be a bit different implementation-wise:
public class RelatedD : IRelatedType
{
public string Name { get; set; }
public string Statement { get; set; }
}
public class RelatedE : IRelatedType
{
public string Name { get; set; }
public string Statement { get; set; }
public bool IsNew { get; set; }
}
Instances of these can be created by a factory based on some sort of "type" enumerated value. The problem is that later on when these objects are being used (in a business layer, for example), there could be a lot of code like this:
IRelatedType theObject = TheFactory.CreateObject(SomeEnum.SomeValue);
if (theObject is RelatedC)
{
RelatedC cObject = theObject as RelatedC;
specialVal = cObject.Special;
}
else if (theObject is RelatedD)
{
RelatedD dObject = theObject as RelatedD;
statementVal = dObject.Statement;
}
else if (theObject is RelatedE)
{
RelatedE eObject = theObject as RelatedE;
statementVal = eObject.Statement;
isNewVal = eObject.IsNew;
}
This could be repeated in many places. Is there a better approach to the design that I should be using (there's got to be)?
You could try and factor the differences into seperate classes that are then provided so for example:
IRelatedType theObject = TheFactory.CreateObject(SomeEnum.SomeValue);
RelatedTypeHelper theHelper=TheFactory.CreateHelper(theObject);
theHelper.DoSpecialThing(theObject);
Now you won't have to have all the if else blocks, and if you add a new type which requires new handling, you just whip up a new helper implement the required pieces and you should be good to go. The helper should help document this process.
I would also question why a single method would have such a different implementation for specialVal and StatementVal could be your sample, but It makes me curious what your really doing here. can you simplify things back taking a step back and questioning the point of these being included in this specific hierarchy.