I have a 'complex' object that I want to serialize with JSon.Convert. As 'complex' objects go it is rather simple: Here are the objects:
The main object:
public class CustomerContactRequest
{
private RequestHeaderArea header;
private RequestPayloadArea payload;
public CustomerContactRequest(string headerMessage, string npsGroup, string npsSection)
{
this.header = new RequestHeaderArea(headerMessage);
this.payload = new RequestPayloadArea(npsGroup, npsSection);
}
}
The 'header' Object:
public class RequestHeaderArea
{
private string headerMessage;
public string HeaderMessage { get { return headerMessage; } }
public RequestHeaderArea(string headerMessage)
{
this.headerMessage = headerMessage;
}
}
The Payload Area:
public class RequestPayloadArea
{
private string npsGroup;
private string npsSection;
public string NPSGroup { get { return npsGroup; } }
public string NPSSection { get { return npsSection; } }
public RequestPayloadArea(string npsGroup, string npsSection)
{
this.npsGroup = npsGroup;
this.npsSection = npsSection;
}
}
And Finally, the main process:
static void Main(string[] args)
{
CustomerContactRequest ccRequest = new CustomerContactRequest(
headerMessage: "test",
npsGroup: "1234567",
npsSection: "0000");
retrieveContactInfo(ccRequest);
}
static void retrieveContactInfo(CustomerContactRequest ccRequest)
{
string jsonRequest = JsonConvert.SerializeObject(ccRequest);
// code to call service
}
jsonRequest returns {} even though ccRequest contains the expected values. What am I missing?
I am expecting something like this (sans formatting):
{
"headerArea": {
"messageId": "test"
},
"payloadArea": {
"group": {
"Number": "1234567",
"Suffix": "0000"
}
}
}
Implementing Chris's answer my classes now look like below (main program did not change except that I added Formatted.Indented to the SerializeObject call to make it pretty):
CustomerContactRequest:
public class CustomerContactRequest
{
public RequestHeaderArea headerArea;
public RequestPayloadArea payloadArea;
public CustomerContactRequest(string headerMessage, string npsGroup, string npsSection)
{
this.headerArea = new RequestHeaderArea(headerMessage);
this.payloadArea = new RequestPayloadArea(npsGroup, npsSection);
}
}
RequestHeaderArea:
public class RequestHeaderArea
{
private string messageId;
public string MessageId { get { return messageId; } }
public RequestHeaderArea(string headerMessage)
{
this.messageId = headerMessage;
}
}
RequestPayloadArea:
public class RequestPayloadArea
{
public Group group;
public RequestPayloadArea(string npsGroup, string npsSection)
{
this.group = new Group(npsGroup, npsSection);
}
}
And a new class: Group:
public class Group
{
public string Number;
public string Suffix;
public Group(string npsGroup, string npsSection)
{
Number = npsGroup;
Suffix = npsSection;
}
}
Now my Json looks exactly as expected (see green text above)
SerializeObject ignores private members by default. You can either make them public, or by adding the SerializableAttribute to your CustomerContractRequest class.
Related
I have some Properties and i want to save some specific property value in json format.Here is my code and i want to save two properties value like SelectedScalesModel and SelectedScales port Can anyone help me with this.
public class SetUpViewModel : ViewModelBase
{
public List<string> ScalesModel { get; set; } = new List<string> { "None", "METTLER-TOLEDO", "DINI ARGEO DFW-DFWK", "ESSAE SI-810" };
private string _selectedScalesModel;
public string SelectedScalesModel
{
get { return _selectedScalesModel; }
set
{
_selectedScalesModel = value;
RaisePropertyChanged("SelectedScalesModel");
}
}
public List<string> ScalesPort { get; set; } = new List<string> { "None", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "COM10", "COM11", "COM12", "COM13", "COM14", "COM15" };
private string _selectedScalesPort;
public string SelectedScalesPort
{
get { return _selectedScalesPort; }
set
{
_selectedScalesPort = value;
RaisePropertyChanged("SelectedScalesPort");
}
}
string _text1;
public string BlackLineText
{
get { return _text1; }
set
{
_text1 = value;
RaisePropertyChanged(nameof(BlackLineText));
}
}
public RelayCommand SaveButtonCommand { get; private set; }
public SetUpViewModel()
{
SaveButtonCommand = new RelayCommand(SaveCommand);
}
private void SaveCommand()
{
SetUpViewModel setUpobj = new SetUpViewModel();
string strJsonResult = JsonConvert.SerializeObject(setUpobj);
File.WriteAllText("setup.json", strJsonResult);
MessageBox.Show("File save in Json Format");
}
}
You can try to SerializeObject by anonymous class then carry your expect property instead of SetUpViewModel object.
private void SaveCommand()
{
string strJsonResult = JsonConvert.SerializeObject(
new {
SelectedScalesModel = this.SelectedScalesModel,
SelectedScalesPort = this.SelectedScalesPort
}
);
File.WriteAllText("setup.json", strJsonResult);
MessageBox.Show("File save in Json Format");
}
Note
use this because your property info in your object.
I need to collect some classes and provide it by request to some parts of program. I have following code:
public interface ISameClass
{
int Value { get; set; }
void DoStuff();
}
public class SameClass : ISameClass
{
int Value { get; set; }
void DoStuff()
{
//Do something
}
}
public class SameClassProvider
{
private readonly Dictionary<string, ISameClass> _sameClasses;
public SameClassProvider(string parentDir)
{
_sameClasses = new Dictionary<string, ISameClass>
{
{ "Type1", new SameClass() },
{ "Type2", new SameClass() },
{ "Type3", new SameClass() }
};
}
public bool AddClass(string type, ISameClass class)
{
if (_sameClasses.ContainsKey(type) || class == null)
{
return false;
}
_nodes.Add(type, class);
return true;
}
public ISameClass GetClass(string type)
{
if (_sameClasses.TryGetValue(type, out var someClass))
{
return someClass;
}
}
}
Is using classes like SameClassProvider is good practice? Or i can refactor this something or replace with correct pattern? Tnx
Create three small classes unrelated by inheritance—classes Building, Car and Bicycle. Write an interface ICarbonFootprint with a GetCarbonFootprint method. Have each of your classes implement that interface, so that its GetCarbonFootprint method calculates an appropriate carbon footprint for that class (check out a few websites that explain how to calculate carbon footprints). Write an app that creates objects of each of the three classes, places references to those objects in List, then iterates through the List, polymorphically invoking each object’s GetCarbonFootprint method. Constructor of Car initialize “gallon of gas”, and the Building constructor will initialize buiding-square-footage.
how to calculate carbon-footprint
One gallon of gas yields 20 pounds of CO2 for a car
Multiply the square footage by 50 for a building
None for a bicycle
My instructor's code:
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
list[i].GetCarbonFootprint();
} // end Main
}
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Miller
{
class Program
{
static void Main(string[] args)
{
Bicycle bike = new Bicycle();
Building b = new Building();
Car car = new Car();
List<ICarbonFootprint> list = new List<ICarbonFootprint>();
list.Add(bike);
list.Add(b);
list.Add(car);
int totalCarbon = 0;
foreach (var item in list)
{
totalCarbon += item.GetCarbonFootprint();
Console.WriteLine("{0} has a footprint of: {1}", item, item.GetCarbonFootprint());
}
Console.WriteLine("Total footprint is: {0}", totalCarbon);
Console.ReadKey();
}
}
public class Bicycle : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 10;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Building : ICarbonFootprint
{
private string _address;
public string Address
{
get { return _address; }
set { _address = value; }
}
public int GetCarbonFootprint()
{
return 2000;
}
public override string ToString()
{
return string.Format("Building");
}
}
public class Car : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 1500;
}
public override string ToString()
{
return string.Format("Car");
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
}
Me integrating my instructor's code (lines 12-23 changed AKA class Program was the only thing changed):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Miller
{
class Program
{
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
list[i].GetCarbonFootprint();
} // end Main
}
public class Bicycle : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 10;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Building : ICarbonFootprint
{
private string _address;
public string Address
{
get { return _address; }
set { _address = value; }
}
public int GetCarbonFootprint()
{
return 2000;
}
public override string ToString()
{
return string.Format("Building");
}
}
public class Car : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 1500;
}
public override string ToString()
{
return string.Format("Car");
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
}
So, replacing my code for class Program with my instructor's code, I received the following errors:
Program.cs(51,23,51,41): error CS1729: 'Miller.Building' does not contain a constructor that takes 1 arguments
Program.cs(52,23,52,34): error CS1729: 'Miller.Car' does not contain a constructor that takes 1 arguments
Now, because the last two days before Spring break were cancelled due to the weather (snow), we weren't able to discuss. My code seems to do what the directions ask, but I would like to get my instructor's code for class Program working with my code. Could someone help me with these errors possibly?
There are a few issues with your code.
First up you need to include the constructors to make the code compile.
For Building this would look like:
private int squareFootage;
public Building(int squareFootage)
{
this.squareFootage = squareFootage;
}
And for Car this would look like:
private int gasGallons;
public Car(int gasGallons)
{
this.gasGallons = gasGallons;
}
Next, you're not following the rules for calculating the carbon footprint.
They should be:
//Bicycle
public int GetCarbonFootprint()
{
return 0;
}
//Building
public int GetCarbonFootprint()
{
return 50 * squareFootage;
}
//Car
public int GetCarbonFootprint()
{
return 20 * gasGallons;
}
Finally, your instructor's code doesn't actually display any results. The code in the for loop should be changed to be Console.WriteLine(list[i].GetCarbonFootprint()); if this is a console app.
So, all up the code should look like this:
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
Console.WriteLine(list[i].GetCarbonFootprint());
}
public class Bicycle : ICarbonFootprint
{
public string Make { get; set; }
public string Model { get; set; }
public int GetCarbonFootprint()
{
return 0;
}
}
public class Building : ICarbonFootprint
{
private int squareFootage;
public Building(int squareFootage)
{
this.squareFootage = squareFootage;
}
public string Address { get; set; }
public int GetCarbonFootprint()
{
return 50 * squareFootage;
}
}
public class Car : ICarbonFootprint
{
private int gasGallons;
public Car(int gasGallons)
{
this.gasGallons = gasGallons;
}
public string Make { get; set; }
public string Model { get; set; }
public int GetCarbonFootprint()
{
return 20 * gasGallons;
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
I've opted to short-cut the property definitions rather than implement them with fields.
The output is:
0
125000
200
You should write constructors for Building and Car like next:
public Building(int MyValue)
{
...
}
and your code will work fine.
Suggestion: Car and Bicycle shares properties, and the ICarbonFootprint implementation, so you can create a base class with an abstract method. Also the GetCarbonFootprint from ICarbonFootprint interface must be type of System.Double.
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
public class Building : ICarbonFootprint
{
public int BuildingSquareFootage { get; set; }
public string Address { get; set; }
public Building(int buildingSquareFootage, string address)
{
BuildingSquareFootage = buildingSquareFootage;
Address = address;
}
public int GetCarbonFootprint()
{
return BuildingSquareFootage * 50;
}
public override string ToString()
{
return string.Format("Building");
}
}
public abstract class CarBicycleBase : ICarbonFootprint
{
public string Make { get; set; }
public string Model { get; set; }
protected CarBicycleBase(string make, string model)
{
Make = make;
Model = model;
}
public abstract int GetCarbonFootprint();
}
public class Bicycle : CarBicycleBase
{
public Bicycle(string make, string model)
: base(make, model) { }
public override int GetCarbonFootprint()
{
return 0;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Car : CarBicycleBase
{
public int GallonOfGas { get; set; }
public Car(int gallonOfGas, string make, string model)
: base(make, model)
{
GallonOfGas = gallonOfGas;
}
public override int GetCarbonFootprint()
{
return GallonOfGas * 20;
}
public override string ToString()
{
return string.Format("Car");
}
}
Example:
...
var list = new List<ICarbonFootprint>(3)
{
new Car(10, "...", "..."),
new Bicycle("...", "..."),
new Building(20, "...")
};
foreach (ICarbonFootprint item in list)
item.GetCarbonFootprint();
...
I hope it helps.
I have the following code for supporting a list of different types :
public enum eType
{
tInt,
tString,
tDateTime
}
public interface ICustomType<out T>
{
T Value { get; }
}
public abstract class DifferentType
{
protected DifferentType(eType type, string mnemonic)
{
Type = type;
Mnemonic = mnemonic;
}
public string Mnemonic { get; private set; }
public eType Type { get; private set; }
}
public class DateTimeType : DifferentType, ICustomType<DateTime>
{
public DateTimeType(DateTime value, string mnemonic)
: base(eType.tDateTime, mnemonic)
{
Value = value;
}
public DateTime Value { get; private set; }
}
public class IntType : DifferentType, ICustomType<int>
{
public IntType(int value, string mnemonic)
: base(eType.tInt, mnemonic)
{
Value = value;
}
public int Value { get; private set; }
}
public class StringType : DifferentType, ICustomType<string>
{
public StringType(string value, string mnemonic)
: base(eType.tString, mnemonic)
{
Value = value;
}
public string Value { get; private set; }
}
public static class UtilValue
{
public static T GetValue<T>(DifferentType customType)
{
return ((ICustomType<T>)customType).Value;
}
}
public class testTypes2
{
public testTypes2()
{
var values = new List<DifferentType> { GetInt(), GetString(), GetDate() };
foreach (var i in values)
{
switch (i.Type)
{
case eType.tInt:
int resInt = UtilValue.GetValue<int>(i);
break;
case eType.tString:
string resString = UtilValue.GetValue<string>(i);
break;
case eType.tDateTime:
DateTime resDateTime = UtilValue.GetValue<DateTime>(i);
break;
}
}
}
private DateTimeType GetDate()
{
return new DateTimeType(new DateTime(2000, 1, 1), "MnemonicDate");
}
private IntType GetInt()
{
return new IntType(5, "MnemonicInt");
}
private StringType GetString()
{
return new StringType("ok", "MnemonicString");
}
}
and would like to avoid the cast at line return ((ICustomType<T>)customType).Value; in the UtilValue class, any idea how I can get rid of that while still keeping the design?
I am not even sure if this cast is expensive to do? My guess is most certainly.
Visitor-pattern example:
interface IDifferentTypeVisitor
{
void Visit(DateTimeType dt);
void Visit(StringType st);
}
class DifferentType
{
public abstract void Accept(IDifferentTypeVisitor visitor);
}
class DateTimeType : DifferentType
{
public void Accept(IDifferentTypeVisitor visitor)
{
visitor.Visit(this);
}
}
class StringType : DifferentType
{
public void Accept(IDifferentTypeVisitor visitor)
{
visitor.Visit(this);
}
}
class SomeVisitor : IDifferentTypeVisitor
{
public void Visit(DateTimeType dt)
{
//DateTime resDateTime = dt.Value; Or similar
}
public void Visit(StringType st)
{
//string resString = st.Value; Or similar
}
}
public class testTypes2
{
public testTypes2()
{
var values = new List<DifferentType> { /* Content */ };
var visitor = new SomeVisitor();
foreach (var i in values)
{
i.Accept(visitor);
}
}
}
In C# 4 with dynamic it's possible to save some code by adding this to DifferentType:
public void Accept(IDifferentTypeVisitor visitor)
{
visitor.Visit((dynamic)this);
}
and then delete all other Accept methods. It hurts performance but it looks better ;-)
I have implemented Single Pattern. Here is my code i am getting the an error when i call the Test.BuildData() function. Please help
public class WordDataItem
{
public string Word { get; set; }
public string Definition { get; set; }
public int WordGroupKey { get; set; }
}
public class WordDataGroup
{
public List<WordDataItem> listItem = new List<WordDataItem>();
public int GroupKey { get; set; }
}
public sealed class WordDataSource
{
private static WordDataSource _dataSoruce;
private List<WordDataGroup> listGroup = new List<WordDataGroup>();
public List<WordDataGroup> ListGroup
{
get { return listGroup; }
set { listGroup = value; }
}
private WordDataSource() { }
public static WordDataSource Instance
{
get
{
if (Instance == null)
{
_dataSoruce = new WordDataSource();
}
return _dataSoruce;
}
}
}
public static class Test
{
public static void BuildData()
{
WordDataSource.Instance.ListGroup.Add(new WordDataGroup() { GroupKey = 8, listItem = new List<WordDataItem>() { new WordDataItem() {Word = "Hello", Definition="Greetings", WordGroupKey = 8}} });
}
}
I get an error of stack over flow when i call the Test.BuildData() function.
Your Instance property is recursively calling into itself when you check if it is null.
Try this:
public static WordDataSource Instance
{
get
{
if (_dataSoruce == null)
{
_dataSoruce = new WordDataSource();
}
return _dataSoruce;
}
}