Json.NET to list of class as attribute - c#

I build a rest service which output are json. I using Newtonsoft.Json.
This is my class.
public class DownloadPDA
{
public List<FRUTE> lsRute { get; set; }
public List<FCUSTMST> lsCustomer { get; set; }
public List<FMASTER> lsMaster { get; set; }
public List<FNOTEC> lsNotec { get; set; }
public List<FINFO> lsInfo { get; set; }
public List<FBRAND> lsBrand { get; set; }
public List<FKPL> lsKpl { get; set; }
}
but when I test my rest service my result are:
{"downloadDataResult":"{"lsBrand":[{}],"lsCustomer":[{},{},{}],"lsInfo":[],"lsKpl":null,"lsMaster":[{},{},{},{},{}],"lsNotec":[],"lsRute":[{},{},{}]}"}
it not show the data in list. I know something is wrong. Can anybody help?
This one of my collection class
public class FRUTE
{
private String norute;
private String custno;
private String flag;
private String st_visit;
private float amount;
private int jmlvisit;
public FRUTE() { }
public void getData(DCTRTDTO dto) {
this.norute = dto.NOROUT;
this.custno = dto.NOCUST;
this.flag = dto.FLAG;
this.st_visit = "not yet";
this.amount = 10;
this.jmlvisit = 1;
}
public static List<FRUTE> getList(List<DCTRTDTO> lsRute)
{
List<FRUTE> ls = new List<FRUTE>();
FRUTE info = new FRUTE();
foreach (DCTRTDTO dto in lsRute)
{
info.getData(dto);
ls.Add(info);
}
return ls;
}
}

Your FRUTE class doesn't have public properties that are required for Json serialization.
Encapsulate you private fields and all will work as expected.
public class FRUTE
{
private String norute;
private String custno;
public string Norute
{
get { return norute; }
set { norute = value; }
}
public string Custno
{
get { return custno; }
set { custno = value; }
}
//...
}

Related

More efficient way of serialization and deserialization?

I have the below classes.
public class Source { public string ConfigData { get; set; } }
public class Configuration { public IEnumerable<IpAddress> IpAddresses { get; set; } }
public class IpAddress
{
public string Start { get; set; }
public string End { get; set; }
public bool IsValid { get; set; }
public Family IPFamily { get; set; }
}
First, I am getting the ConfigData as string from a source and deserializing it below:
var storedIPAddresses = JsonConvert.DeserializeObject<Configuration>( source.ConfigData).IpAddresses;
Next I am doing some checks, which essentially sets the values of IsValid and IPFamily.
if (storedIPAddresses.Any())
{
foreach (var ipDetail in storedIPAddresses)
{
if (!string.IsNullOrEmpty(ipDetail.StartIpAddress) && !string.IsNullOrEmpty(ipDetail.EndIpAddress))
{
if (bla == blabla)
{
ipDetail.IsValid = true;
ipDetail.IPFamily = IPAddressFamily.IPV4;
}
}
}
}
Lastly, I am supposed to return the souce object by chucking in the updated storedIPAddresses inside, which is where I need some guidance.
I am able to do in following way; but looking for any more elegant way?
var config = new Configuration();
config = JsonConvert.DeserializeObject<Configuration>(source.ConfigData);
config.IpAddresses = storedIPAddresses;
source.ConfigData = JsonConvert.SerializeObject(config);
return source;

Clean Code: SRP and Open/Closed when fetching data from web services

When I'm developing, I usually try to follow the SOLID principles.
Usually you have an interface that all affected classes implement and then use the interface as a parameter when making further calculations.
My question is how can this be achieved when calling, for example, a web service? The code below is not very lean and does NOT indeed meet the Single Responsibility Pattern and the Open/Closed Principle.
How would you re-design the following code to follow SRP and O/C:
public class Fetch
{
public void Run()
{
var url = "https://api.nasa.gov/planetary/apod?api_key=NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo";
var client = new HttpClient();
var response = client.GetAsync(url).Result;
var data = response.Content.ReadAsStringAsync().Result;
var parsedData = JsonConvert.DeserializeObject<Nasa>(data);
if(parsedData.media_type.Equals("image"))
{
CreateImage(parsedData);
}
if (parsedData.media_type.Equals("video"))
{
CreateVideo(parsedData);
}
if (parsedData.media_type.Equals("text"))
{
CreateText(parsedData);
}
}
}
public class Nasa
{
public string copyright { get; set; }
public string date { get; set; }
public string explanation { get; set; }
public string hdurl { get; set; }
public string media_type { get; set; }
public string service_version { get; set; }
public string title { get; set; }
public string url { get; set; }
}
(The Api key is taken from Nasa's example site so don't worry about exposing it. The async part using .Result is just for this example)
Without knowing much about your needs, or how the CreateVideo(item) and CreateImage(item) works, you can use this as a starting point.
Please note that if you are using a dependency container (like Simple Injector, love it!) much of the dependencies in the following can be provided by the container.
public class Nasa
{
public string copyright { get; set; }
public string date { get; set; }
public string explanation { get; set; }
public string hdurl { get; set; }
public string media_type { get; set; }
public string service_version { get; set; }
public string title { get; set; }
public string url { get; set; }
}
public interface ITransformFetch<in T>
{
void Transform(T data);
}
public interface IFetch<T>
{
T Fetch();
}
public class NasaFetcher : IFetch<Nasa>
{
private const string NasaUrl = "https://api.nasa.gov/planetary/apod?api_key=NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo";
private readonly IHttpClientWrapper _client;
public NasaFetcher(IHttpClientWrapper client)
{
_clientFactory = client;
}
public Nasa Fetch()
{
var response = _client.GetAsync(NasaUrl).Result;
var data = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<Nasa>(data);
}
}
public class NasaFetchImageTransformer : ITransformFetch<Nasa>
{
public void Transform(Nasa data)
{
// transform data
}
}
public class NasaFetchVideoTransformer : ITransformFetch<Nasa>
{
public void Transform(Nasa data)
{
// transform data
}
}
public class NasaFetcherTransformerDecorator : IFetch<Nasa>
{
private readonly IFetch<Nasa> _fetcher;
public NasaFetcherTransformerDecorator(IFetch<Nasa> fetcher)
{
_fetcher = fetcher;
}
public Nasa Fetch()
{
var result = _fetcher.Fetch();
if (result != null)
{
switch (result.media_type)
{
case "image":
var nasaFetchImageTransformer = new NasaFetchImageTransformer();
nasaFetchImageTransformer.Transform(result);
break;
case "video":
var nasaFetchVideoTransformer = new NasaFetchVideoTransformer();
nasaFetchVideoTransformer.Transform(result);
break;
}
}
return result;
}
}
public class Test
{
public void TestNasaFetcher()
{
var data = new NasaFetcherTransformerDecorator(new NasaFetcher(new HttpClientWrapper()));
var nasa = data.Fetch();
}
}

Strange deserialization issue

I've created classes from XSD Schema using xsd.exe (also tried with xsd2code which had better results in a way that they worked immediately, and with xsd.exe I have to debug some errors). XSD Schema I've used can be found at http://www.landxml.org/schema/LandXML-1.2/LandXML-1.2.xsd , and sample file can be found at http://landxml.org/schema/LandXML-1.1/samples/AASHTO%20SDMS/MntnRoad.xml .
My code for deserialization looks like:
var mySerializer = new XmlSerializer(typeof (LandXML), new XmlRootAttribute(""));
TextReader myFileStream = new StreamReader("myFile.xml");
var myObject = (LandXML) mySerializer.Deserialize(myFileStream);
My problem is that result of deserialization is list of items of type XmlElement, so if I try to access their properties, I can't easy do that. If I want to access, for example, some Alignment object attribute in myFile.xml, the code is similar to this:
var a = myObject.Items[5];
var b = (XmlElement) a;
var c = b.ChildNodes.Item(5).ChildNodes.Item(0).ChildNodes.Item(0).Attributes[0].Value;
It is obvious that this is not a way which is meant to be while deserializing XML to classes. My idea was like (for same element):
var c = LandXML.Alignments.Alignment.CoordGeometry.Curve.rot
I don't know what I'm doing wrong, I've tried with simpler schemas, and this code was working well. Please help and tnx in advance!
EDIT 1
this is at top of my class and I think that this List type generating troubles. And there is a more similar code in my generated classes
public class LandXML
{
private List<object> _items;
private System.DateTime _date;
private System.DateTime _time;
private string _version;
private string _language;
private bool _readOnly;
private int _landXMLId;
private string _crc;
public LandXML()
{
this._items = new List<object>();
}
[System.Xml.Serialization.XmlAnyElementAttribute()]
[System.Xml.Serialization.XmlElementAttribute("Alignments", typeof(Alignments))]
[System.Xml.Serialization.XmlElementAttribute("Amendment", typeof(Amendment))]
[System.Xml.Serialization.XmlElementAttribute("Application", typeof(Application))]
[System.Xml.Serialization.XmlElementAttribute("CgPoints", typeof(CgPoints))]
[System.Xml.Serialization.XmlElementAttribute("CoordinateSystem", typeof(CoordinateSystem))]
[System.Xml.Serialization.XmlElementAttribute("FeatureDictionary", typeof(FeatureDictionary))]
[System.Xml.Serialization.XmlElementAttribute("GradeModel", typeof(GradeModel))]
[System.Xml.Serialization.XmlElementAttribute("Monuments", typeof(Monuments))]
[System.Xml.Serialization.XmlElementAttribute("Parcels", typeof(Parcels))]
[System.Xml.Serialization.XmlElementAttribute("PipeNetworks", typeof(PipeNetworks))]
[System.Xml.Serialization.XmlElementAttribute("PlanFeatures", typeof(PlanFeatures))]
[System.Xml.Serialization.XmlElementAttribute("Project", typeof(Project))]
[System.Xml.Serialization.XmlElementAttribute("Roadways", typeof(Roadways))]
[System.Xml.Serialization.XmlElementAttribute("Surfaces", typeof(Surfaces))]
[System.Xml.Serialization.XmlElementAttribute("Survey", typeof(Survey))]
[System.Xml.Serialization.XmlElementAttribute("Units", typeof(Units))]
public List<object> Items
{
get
{
return this._items;
}
set
{
this._items = value;
}
}
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlSerializer xs = new XmlSerializer(typeof(LandXML));
XmlTextReader reader = new XmlTextReader(FILENAME);
reader.Namespaces = false;
LandXML landXML = (LandXML)xs.Deserialize(reader);
}
}
[XmlRoot("LandXML")]
public class LandXML
{
[XmlAttribute("version")]
public double version { get;set; }
[XmlAttribute("date")]
public DateTime date { get;set; }
[XmlAttribute("time")]
public DateTime time { get; set; }
[XmlAttribute("readOnly")]
public Boolean readOnly { get;set; }
[XmlAttribute("language")]
public string language { get;set; }
[XmlElement("Project")]
public Project project { get; set; }
[XmlElement("Units")]
public Units units { get; set; }
[XmlElement("Application")]
public Application application { get; set; }
[XmlElement("Alignments")]
public Alignments alignments { get; set; }
}
[XmlRoot("Project")]
public class Project
{
[XmlAttribute("name")]
public string name;
}
[XmlRoot("Units")]
public class Units
{
[XmlElement("Imperial")]
public Imperial imperial { get; set; }
}
[XmlRoot("Application")]
public class Application
{
[XmlElement("Author")]
public Author author { get; set; }
}
[XmlRoot("Imperial")]
public class Imperial
{
[XmlAttribute("linearUnit")]
public string linearUnit;
[XmlAttribute("areaUnit")]
public string areaUnit;
[XmlAttribute("volumeUnit")]
public string volumeUnit;
[XmlAttribute("temperatureUnit")]
public string temperaturUnit;
[XmlAttribute("pressureUnit")]
public string pressureUnit;
[XmlAttribute("angularUnit")]
public string angularUnit;
[XmlAttribute("directionUnit")]
public string name;
}
[XmlRoot("Author")]
public class Author
{
[XmlAttribute("createdBy")]
public string createdBy;
[XmlAttribute("createdByEmail")]
public string createdByEmail;
[XmlAttribute("company")]
public string company;
[XmlAttribute("companyURL")]
public string companyURL;
}
[XmlRoot("Alignments")]
public class Alignments
{
[XmlAttribute("desc")]
public string desc;
[XmlElement("Alignment")]
public Alignment alignment { get; set; }
}
[XmlRoot("Alignment")]
public class Alignment
{
[XmlAttribute("name")]
public string name;
[XmlAttribute("desc")]
public string desc;
[XmlAttribute("length")]
public string length;
[XmlAttribute("staStart")]
public string staStart;
[XmlElement("AlignPIs")]
public AlignPIs alignPIs { get; set; }
}
[XmlRoot("AlignPIs")]
public class AlignPIs
{
[XmlElement("AlignPI")]
public List<AlignPI> alignPI { get; set; }
}
[XmlRoot("AlignPI")]
public class AlignPI
{
[XmlElement("PI")]
public PI pi { get; set; }
[XmlElement("InSpiral")]
public InSpiral inSpiral { get; set; }
[XmlElement("Curve1")]
public Curve1 cureve1 { get; set; }
[XmlElement("OutSpiral")]
public OutSpiral outSpiral { get; set; }
[XmlElement("Station")]
public Station station { get; set; }
}
[XmlRoot("Station")]
public class Station
{
[XmlText]
public string value { get; set; }
}
[XmlRoot("PI")]
public class PI
{
[XmlAttribute("code")]
public int code;
[XmlAttribute("name")]
public int name;
[XmlText]
public string value;
}
[XmlRoot("InSpiral")]
public class InSpiral
{
[XmlElement("Spiral")]
public Spiral spiral { get; set; }
}
[XmlRoot("Spiral")]
public class Spiral
{
[XmlAttribute("length")]
public double length;
[XmlAttribute("radiusEnd")]
public double radiusEnd;
[XmlAttribute("radiusStart")]
public double radiusStart;
[XmlAttribute("rot")]
public string rot;
[XmlAttribute("spiType")]
public string spiType;
}
[XmlRoot("Curve1")]
public class Curve1
{
[XmlElement("Curve")]
public Curve curve { get; set; }
}
[XmlRoot("Curve")]
public class Curve
{
[XmlAttribute("rot")]
public string rot;
[XmlAttribute("radius")]
public double radius;
}
[XmlRoot("OutSpiral")]
public class OutSpiral
{
[XmlElement("Spiral")]
public Spiral spiral { get; set; }
}
}

JSONDeserializer from Json string to List of objects

I'm new on java/android:
I'm using this list of objects on wp7 and I want pass to android, how I do this:
My big object c#:
public class ListCountries
{
public List<CountriesRepresented> _countriesRepresented { get; set; }
public List<CountriesOrigin > _countriesOrigin { get; set; }
}
My others two objects in c#:
public class CountriesRepresented
{
public int CountryID { get; set; }
public string Designation { get; set; }
public string Symbol { get; set; }
public string NomDesignationISO { get; set; }
}
public class CountriesOrigin
{
public int CountryID { get; set; }
public string Designation { get; set; }
public string Symbol { get; set; }
public string NomDesignationISO { get; set; }
}
My java Deserializer:
public Object[] getListCountries()
{
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost(Config.WS_PATH);
post.setHeader("content-type", "application/json; charset=UTF-8");
post.addHeader("Client-Application","3601cfde-e440-4a84-a2cc-a402f4c7bd14");
HttpResponse resp = httpClient.execute(post);
String respStr = EntityUtils.toString(resp.getEntity());
ListCountries _listCountries = new JSONDeserializer().deserialize(ListCountries .class, respStr);
return _listCountries;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
My big object in java:
public class ListCountries {
public List<CountriesRepresented> _CountriesRepresented;
public List<CountriesOrigin > _CountriesOrigin ;
public List<CountriesRepresented> getCountriesRepresented() {
return this._CountriesRepresented;
}
public List<CountriesOrigin > getCountriesOrigin() {
return this._CountriesOrigin ;
}
public void setCountriesRepresented (List<CountriesRepresented> CountriesRepresented) {
this._CountriesRepresented = CountriesRepresented;
}
public void setCountriesOrigin (List<CountriesOrigin > CountriesOrigin ) {
this._CountriesOrigin = CountriesOrigin ;
}
}
My service is on WebAPI and give me an correct answer example: `{"PaisesRepresentantes":[{"PaisID":4,"Designacao":"Alemanha","Sigla":"DEU","NomDesignacaoISO":"GERMANY"},{"PaisID":21,.......
your classes in Java should be something like,
public class ListCountries
{
public List<CountriesRepresented> _countriesRepresented; //Make it private if you want and then you can add getter setter function
public List<CountriesOrigin > _countriesOrigin;
}
public class CountriesRepresented
{
public int CountryID; //Make it private if you want and then you can add getter setter function
public String Designation;
public String Symbol;
public String NomDesignationISO;
}
public class CountriesOrigin
{
public int CountryID; //Make it private if you want and then you can add getter setter function
public String Designation;
public String Symbol;
public String NomDesignationISO;
}
The problem with your existing code is that you have declared variable as _CountriesRepresented rather it should be _countriesRepresented i.e. properties are case sensitive and those are mapped to variables declared in class and do remember to add a default constructor if you add any custom constructor to any of those classes

How can I cache objects and read from memory if it exists instead of database?

I have four classes as following:
public class Section
{
public int SectionId { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string MetaTag { get; set; }
public string MetaDescription { get; set; }
public string UrlSafe { get; set; }
public string Header { get; set; }
public string ImageName { get; set; }
}
public interface ISectionRepository
{
List<Section> GetAllSections();
}
public class SectionRepository : ISectionRepository
{
Context context = new Context();
public List<Section> GetAllSections()
{
return context.Sections.ToList();
}
}
public class SectionApplication
{
SectionRepository sectionRepo = new SectionRepository();
public List<Section> GetAllSections()
{
return sectionRepo.GetAllSections();
}
}
And in my controller, I have
public class SectionController : Controller
{
SectionApplication sectionApp = new SectionApplication();
public ActionResult Index()
{
return View(sectionApp.GetAllSections());
}
}
Now, I want to do cache sections on memory for a specific time in order to read sections from cache if it exists, else read it from database.
Simple possible approach, you can use MemoryCache, the code will look like:
public List<Section> GetAllSections()
{
var memoryCache = MemoryCache.Default;
if (!memoryCache.Contains("section"))
{
var expiration = DateTimeOffset.UtcNow.AddMinutes(5);
var sections = context.Sections.ToList();
memoryCache.Add("section", sections, expiration);
}
return memoryCache.Get("section", null);
}
You do the caching by adding a new class with a timeout. When you read the first time, you read directly from the database and write the data into a property of the new class and make a timestamp. In the next read operation, you check your new class to see if the timeout has been reached. If not, you read the data from the new class. Otherwise, you read from the database and put it into the cache class and update the timeout.
public interface IRepositoryCollection
{
DateTime dateCreated { get; set; }
}
public class Cache<T> : Dictionary<string, T>
{
private int cacheDuration = 1;
private int maxCacheSize = 20;
public Cache(int cacheDuration, int maxCacheSize)
{
this.cacheDuration = cacheDuration;
this.maxCacheSize = maxCacheSize;
}
public new void Add(string key, T invoices)
{
base.Add(key, invoices);
RemoveOld();
RemoveOldest();
}
public void RemoveOld()
{
foreach (KeyValuePair<string, T> cacheItem in this)
{
Interfaces.IRepositoryCollection currentvalue = (Interfaces.IRepositoryCollection)cacheItem.Value;
if (currentvalue.dateCreated < DateTime.Now.AddHours(-cacheDuration))
{
this.Remove(cacheItem.Key);
}
}
}
public void RemoveOldest()
{
do
{
this.Remove(this.First().Key);
}
while (this.Count > maxCacheSize);
}
}
public class ProformaInvoiceCache
{
private static Cache<ProformaInvoices> cache = new Cache<ProformaInvoices>(1, 20);
public static string AddInvoiceCollection(ProformaInvoices invoices)
{
// Adds invoice collection to static instance of cache, returns guid required to retrieve item from cache
return cache.Add(invoices);
}
public static ProformaInvoices GetInvoiceCollection(string guid)
{
// Gets invoice collection from cache corresponding to passed guid
return cache.Get(guid);
}
}

Categories