C# - Storing data in classes - c#

I'm trying to understand how to query a web service that provides information about the weather. The service outputs XML.
I am not sure how to store the retrieved information in a class. Looking on the internet there seems to be two ways of doing it.
Either this way:
class CurrentWeather
{
public string CityName { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF { get; set; }
public int WindSpeedMph { get; set; }
//Lots and lots of more weather related properties
}
Or this way:
class CurrentWeather
{
public string CityName { get; set; }
public double TemperatureC { get; set; }
public double TemperatureF { get; set; }
public double WindSpeedMph { get; set; }
public CurrentObservation(string cityName, double temperatureC, double temperatureF, double windSpeedMph)
{
CityName = cityName;
TemperatureC = temperatureC;
TemperatureF = temperatureF;
WindSpeedMph = windSpeedMph;
}
}
My question: I don't know which way to do it. Which approach is the "correct" one, and why is that the case? Why would I use one way other the other?

They are exactly the same way to store data, the only difference is you added a constructor to ensure all the parameters are filled when you instance the class.
But it has a drawback, a class without an empty constructor cannot be instantiated by a serializer.
Why I say that? Because if you are receiving an XML well formed and you code your class structure as the data in that XML, you can use an XmlSerializer to deserialize the XML into an instance of that class without parsing the XML or filling the class properties.

The second is probably heading more the right way to support deserialization, but I'd probably consider breaking the data up a bit. Keep the data encapsulated so related data stays together. Your exact structure is up to you, but I'd probably break down something like:
public class CurrentConditions {
public City CurrentCity { get; set;}
public Temperature[] TemperatureReadings {get; set;}
public Wind[] WindCondtions {get; set;}
}
public class City {
public string Name {get; set;}
}
public enum TemperatureScale { Celsius, Fahrenheit }
public enum SpeedScale { MPH, KPH }
public class Temperature {
public int Degrees {get; set;}
public TemperatureScale Scale {get; set;}
}
etc.
It keeps the data organized. Allows you to only pass around and/or update the particular details you need to if you're making changes, etc.
If you posted the XML I'd have a better feel for how you could map the elements of the XML to objects.

Related

Only return some fields in JSON

I have an API that returns some data of a class in JSON. Is there any way to return only some specific fields of a C# class in JSON?
For example:
class Person {
public int Id{ get; set; }
public string Name { get; set; }
public string Family { get; set; }
public string Gender { get; set; }
}
Person myPerson = new Person();
var Json = (new
{
Person = myPerson
});
return Request.CreateResponse(HttpStatusCode.OK, Json);
It returns ID, Name, Family, Gender. I need to return only the Name and Family. I thought I can create an object and add my specific fields in the class in that object and return object?
Use anonymous types?
return Request.CreateResponse(HttpStatusCode.OK, new {Name = person.Name; Family = person.Family});
You should consider applying the DRY principle.
The DRY principle is not "never write code twice", but rather that "every piece of knowledge must have a single, unambiguous, authoritative representation in the system".
What this means is that you have to build a model that has a meaningful name, contains properties that it actually has, and can be changed as needed later without having to figure out where else in the application it's used. I'm certain you could also find a name that would better represent this area of the application.
Should I create a different model with just the properties I need or
use the same model and have NULL values for the field I don't use? Or just create anonymous type and make this way harder in future?
I don't recommend using the same model for your case, from my understanding of it. It's going to make your life easier down the road if you build a model that has a meaningful name as I said before.
So what should we do? I have seen many people trying to use JsonIgnore in domain model but you should not get down that path. You should avoid using JsonIgnore in domain model. I will give an example for it.
For example:
class Person {
public int Id { get; set; }
public string Name { get; set; }
public string Family { get; set; }
public string Gender { get; set; }
}
So you have this model and you want other models to inherit from it but like in your case you don't want to return Id and Gender, only Name and Family. So you go like this.
class Person {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Family { get; set; }
public virtual string Gender { get; set; }
}
public class PersonNameModel : Person {
[JsonIgnore]
public override int Id { get; set; }
[JsonIgnore]
public override string Gender{ get; set; }
}
If a class has many properties and you only want to serialize a small
subset of them then adding JsonIgnore to all the others will be
tedious and error prone. The way to tackle this scenario is to add the
DataContractAttribute to the class and DataMemberAttributes to the
properties to serialize. This is opt-in serialization, only the
properties you mark up with be serialized, compared to opt-out
serialization using JsonIgnoreAttribute.
But, you can do it with the help of JsonIgnore but this way does not support XML format. So, in case your application has to support XML format more (or only support XML), instead of using Json.Net, you should use [DataContract] which supports both JSON and XML.
Datacontract is a great solution. It gives me a clean REST API. At the same time when I save the data in a no-sql, the ignored properties are persisted despite the objects being stored as json.
[DataContract]
public class Person {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Family { get; set; }
public virtual string Gender { get; set; }
}
public class PersonNameModel : Person {
// included in JSON
[DataMember]
public override string Name { get; set; }
[DataMember]
public override string Family { get; set; }
// other inherited properties will be ignored
}
I will also mention another way of doing it as there are more (custom contact resolver, Web API convention ("ShouldSerialize")...)
Another way you can do it is to decorate your auto property with JsonProperty attribute in order to skip the serialization of that field if it is null.
Example:
class Person {
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? Id { get; set; }
public string Name { get; set; }
public string Family { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Gender { get; set; }
}
Happy coding!

Automapper with dynamic values C#

I am a bit stuck, hoping for guidance. I have 2 tables, Header and Details. However, the details is a bit different than most, and allows for a way to dynamically store data.: Yes, I am aware that I can create a table storing the details in the standard fashion, but the nature of the app needs to be more dynamic on the database side. I also realize I will have to modify the DTOs for different incarnations of the app, but this model is what I need to accomplish.
public class Header
{
public int Id { get; set; }
public string HeaderName { get; set; }
public ICollection<Detail> Details { get; set; }
}
public class Detail
{
public int Id { get; set; }
public int HeaderId { get; set; }
public string FieldName { get; set; }
public string FieldProperty { get; set; }
}
I want to use the following DTOs:
public class DataForDisplayDto
{
public int Id { get; set; }
public string HeaderName { get; set; }
public string TaskToPerform { get; set; }
public string Location { get; set; }
}
public class DataForCreationDto
{
public string HeaderName { get; set; }
public string TaskToPerform { get; set; }
public string Location { get; set; }
}
The data would be stored in the details in this fashion:
{
"FieldName": "tasktoperform",
"FieldProperty": "Thing to Do"
},
{
"FieldName": "location",
"FieldProperty": "Over there"
}
I am trying to use the Automapper to make it so I can read and write to the database using the DTOs, but I think I may be trying something it can't do.
Is there an article or something that anyone knows about that can point me in the direction to go? Or even the right keywords to search online for it. Is it even possible?
I suppose if it is not possible, I will have to do things a bit more manually, which is the last option, I am just hoping to do this with Automapper.
Thanks!
How about deriving your DTO from a base class that uses reflection to generate a mapping, and cache that mapping.
This way your DTO need only inherit a base class.

.Net Parse JSON from Google

So I am using one of the google Id API; https://developers.google.com/instance-id/reference/server#manage_registration_tokens_for_push_subscriptions
I have previously been fortunate to have API that had WDSL or similar and been easy to parse into a class.
But the JSON I got back I can not parse easily.
{
"connectDate":"2018-02-12",
"application":"com.chrome.windows",
"subtype":"wp:https://xxxxxxxxxxxxxxxxxxx",
"authorizedEntity":"xxxxxx",
"rel":{
"topics":{
"movies":{
"addDate":"2018-01-26"
},
"anotherTopic":{
"addDate":"2018-02-12"
}
}
},
"connectionType":"WIFI",
"platform":"WEBPUSH"
}
Movies and anotherTopics are the topics I created so I can't add them to my class . Or can I?
There are of course ways to do it treating the json as string and using regex or going through the node as a dynamic object (dynamic dyn = JsonConvert.DeserializeObject(content);) but ideally I think it should be a dictionary (I think at least) but can not see how.
And as this is Google I assume there is more standard way to handle this kind of JSON.
I have tried creating a dictionary which I couldn't get working.
Stepping through the nodes I can get the data but end up with code like
DateTime.Parse(((Newtonsoft.Json.Linq.JValue)((Newtonsoft.Json.Linq.JProperty)((Newtonsoft.Json.Linq.JContainer)(obj.First)).First).Value).Value.ToString())
I have tried to look for similar JSON parsing exampels but I can not find any.
I did not share my attempt to extract the data in my first edit as I don't think that is the way to do it; it is a hack.
I created a class for it
public class SubscriptionDetails
{
public DateTime connectDate { get; set; }
public string application { get; set; }
public string subtype { get; set; }
public string authorizedEntity { get; set; }
public string connectionType { get; set; }
public string platform { get; set; }
public topics rel { get; set; }
}
But I am stuck when it comes to defining the subclass topics.
So I tried
public class topics : Dictionary<string, object>
which results in one dictionary entry with key topics?
the other option requires a dictionary name
public class topics
{
public Dictionary<string, Dictionary<string, string>> DUMMY { get; set; }
}
So thanks to the suggestion from Jamiec I got on the right track.
Of course already the node rel is a dictionary with one item called topics.
So need a few classes to parse the entire thing:
public class SubscriptionDetails
{
public DateTime connectDate { get; set; }
public string application { get; set; }
public string subtype { get; set; }
public string authorizedEntity { get; set; }
public string connectionType { get; set; }
public string platform { get; set; }
public Dictionary<string, topicItems> rel { get; set; }
}
public class topicItems : Dictionary<string, topicData> { }
public class topicData
{
public DateTime addDate { get; set; }
}
But if they add another node to rel in addition to 'topics' this most likely will crash.
Just doesn't seem to be a very good way to structure the data and the deserialised class isn't very user friendly either..
Anyway it works (for now)

Entity Framework Code First, DTO and n-tier scenario (WCF)

I've read several articles about bunch of EF and DTO, and I need some clarification about using EF Code First and DTO in n-tier scenario with WCF.
Let's look a these classes:
public class Order
{
public int Id { get; set; }
public DateTime ShipDate { get; set; }
public ObservableCollection<OrderDetail> Details { get; private set; }
}
public class OrderDetail
{
public int Id { get; set; }
public int OrderId { get; set; }
public int ProductId { get; set; }
public decimal Quantity { get; set; }
}
When user want to edit existing order, my client application (WPF MVVM app) requests some DTO, which then being converted to Order instance. Then, user makes some changes in order through UI - e.g., changes ShipDate, removes two positions, modifies one, and adds one.
Now I want to deliver changes to the server. As far as I understand DTO concept, I need to construct some DTO type, containing info about changes has been made:
[DataContract]
public class UpdateOrderDTO
{
[DataMember]
public DateTime ShipDate { get; set; }
[DataMember]
public Collection<OrderDetail> NewDetails { get; private set; }
[DataMember]
public Collection<OrderDetail> ModifiedDetails { get; private set; }
[DataMember]
public Collection<OrderDetail> DeletedDetails { get; private set; }
}
But when, and where should I to create this DTO? I mean, I can't create it on submitting changes - there's no change tracking information in Order class.
Looks like, this object have to be created together with Order after it was requested for edition by user. This allows to track changes... Am I wrong?
Please note, that the question isn't about STEs. For some reasons, I don't want/can't use them in current project.
Thanks a lot for sharing your experience.

C# ideal data structure to store 1 float and 3 string fields

What is the ideal data structure I can use in C# to store data consisting of 1 float and 3 string fields (1000+ rows)? I want it such that the structure is easily serializable to a file and can be easily accessed for updating.
A class?!
public class SomeClass
{
public float MyFloat{ get; set; }
public String StringOne{ get; set; }
public String StringTwo{ get; set; }
public String StringThree{ get; set; }
}
or possibly a struct!
public struct SomeStruct
{
public float MyFloat{ get; set; }
public String StringOne{ get; set; }
public String StringTwo{ get; set; }
public String StringThree{ get; set; }
}
Make sure you understand the difference before choosing one or t'other.
I'll post an answer that assumes you already considered and dismissed using a class or a struct for some reason.
As a throwback to my graduate school database courses, I kind of like .NET 4.0's introduction of the Tuple class. If you were so inclined, you could use
var myEntry = Tuple<float, string, string, string>(floatVal, string1Val, string2Val, string3Val);
and reference the items with
float myFloat = myEntry.Item1;
string myString = myEntry.Item2;
Tuple is also decorated with the Serializable attribute, so you can serialize them.

Categories

Resources