I have two classes made as:
public class ipAddress
{
public object ip { get; set; }
}
public class Rule
{
public string name { get; set; }
public ipAddress conditions { get; set; }
public string action { get; set; }
public Boolean enabled { get; set; }
public string statusCode { get; set; }
}
My code to create/assign values to this is:
Rule new_rule = new Rule();
ipAddress ip_info = new ipAddress();
ip_info.ip = new { ipAddress = "34.5.6.7.8" };
new_rule.name = "test";
new_rule.conditions = ip_info;
new_rule.action = "ALLOW";
new_rule.enabled = true;
new_rule.statusCode = "FORBIDDEN_403";
var rule_json = JsonConvert.SerializeObject(new_rule);
after serializing I get this output
{"name":"test","conditions":{"ip":{"ipAddress":"34.5.6.7.8"}},"action":"ALLOW","enabled":true,"statusCode":"FORBIDDEN_403"}
While my expected output is:
{"name":"test","conditions":[{"ip":{"ipAddress":"34.5.6.7.8"}}],"action":"ALLOW","enabled":true,"statusCode":"FORBIDDEN_403"}
so the only difference is the extra object wrapped around the conditions' values.
How can I accomplish this? Tried different things but didn't get there.
Thanks
public ipAddress conditions { get; set; }
The above statement means conditions is an object and objects are represented by { }. If you are expecting it to be a list/array of objects (represented by [ ]), then you will need to define your conditions as an array/list item
public List<ipAddress> conditions { get; set; }
Your assignment object for conditions should look like this,
new_rule.conditions = new List<ipAddress>() { ip_info };
This will produce the result you want. Also, According to the naming conventions, your class name and variable names should start with UpperCase letters.
For you to get your expected output, your ipAddress should be an array.
public class Rule
{
public string name { get; set; }
public ipAddress[] conditions { get; set; }
public string action { get; set; }
public Boolean enabled { get; set; }
public string statusCode { get; set; }
}
Rule new_rule = new Rule();
ipAddress ip_info = new ipAddress();
ip_info.ip = new { ipAddress = "34.5.6.7.8" };
new_rule.name = "test";
new_rule.conditions = new ipAddress[] { ip_info };
new_rule.action = "ALLOW";
new_rule.enabled = true;
new_rule.statusCode = "FORBIDDEN_403";
var rule_json = JsonConvert.SerializeObject(new_rule);
The result that u will obtain from this is
{"name":"test","conditions":[{"ip":{"ipAddress":"34.5.6.7.8"}}],"action":"ALLOW","enabled":true,"statusCode":"FORBIDDEN_403"}
You want the conditions to be an array
So you need to declare public IP addresses[] conditions
You also assigned an object to it and that's the output you get
If you want the json to have an array output you have to declare it as an array
Related
C# and Newtonsoft.JSON
I've an object model class like this
class RolePerson
{
public NodeRolePerson[] Items { get; set; }
}
class NodeRolePerson
{
public bool active { get; set; }
public string dateUva { get; set; }
public bool delegated { get; set; }
public NodeentityOrg entityOrg { get; set; }
.....
public string userUva { get; set; }
}
.........
Now i get data with
RolePerson myP1 = JsonConvert.DeserializeObject<RolePerson>(data1,settings);
RolePerson myP2 = JsonConvert.DeserializeObject<RolePerson>(data2,settings);
How can i have only one object with both myP1 and myP2 ?
I've tried with
List<RolePerson> trace;
trace.Add(myP1);
trace.Add(myP2);
but receive a compilation error 'local variable not assigned'.
Thanks so much.
You never actually created a new list:
List<RolePerson> trace = new List<RolePerson>();
trace.Add(myP1);
trace.Add(myP2);
try this
var items = new List<NodeRolePerson>(myP1.Items);
items.AddRange(myP2.Items);
RolePerson trace = new RolePerson { Items = items.ToArray() };
Although the thing I want to do seems be really trivial I can not find a way to achieve what I want. I know there exist multiple questions how to put class properties into the list together and separate it by a comma like that on SO, but none of them seemed to be relevant to my case.
I have a class Form defined as follows:
public class Form
{
public string CustomerName { get; set; }
public string CustomerAdress { get; set; }
public string CustomerNumber { get; set; }
public string OfficeAdress { get; set; }
public string Date { get; set; }
public Boolean FunctionalTest { get; set; }
public string Signature { get; set; }
public Form()
{
}
}
In the MainPage.xaml.cs, I create a List<Form> with the Form class properties and subsequently I would like to create a string with all of those class properties separated by a comma. For that case I use basic Join method with Select which converts any kinds of objects to string.
I do that by createCSV method inside MainPage.xaml.cs :
void createCSV()
{
var records = new List<Form>
{
new Form {CustomerName = customerName.Text,
CustomerAdress = customerAdress.Text,
CustomerNumber = customerNumber.Text,
OfficeAdress = officeAdress.Text,
Date = date.Date.ToString("MM/dd/yyyy"),
FunctionalTest = testPicker.ToString()=="YES" ? true : false,
Signature = signature.Text
}
};
string results = String.Join(",", (object)records.Select(o => o.ToString()));
}
The problem is instead of the desirable outcome which is:"Mark Brown,123 High Level Street,01578454521,43 Falmouth Road,12/15/2020,false,Brown"
I am getting: "System.Linq.Enumerable+SelectListIterator'2[MyApp.Form,System.String]"
PS. As you have noticed I am newbie in C#. Instead of non constructive criticism of the code, please for a valuable reply which would help me to understand what am I doing wrong.
Thanks in advance
In the Form class, You can override the ToString() method and use System.Reflection to get your comma string.
Form.cs
public class Form
{
public string CustomerName { get; set; }
public string CustomerAdress { get; set; }
public string CustomerNumber { get; set; }
public string OfficeAdress { get; set; }
public string Date { get; set; }
public bool FunctionalTest { get; set; }
public string Signature { get; set; }
public override string ToString()
{
string modelString = string.Empty;
PropertyInfo[] properties = typeof(Form).GetProperties();
foreach (PropertyInfo property in properties)
{
var value = property.GetValue(this); // you should add a null check here before doing value.ToString as it will break on null
modelString += value.ToString() + ",";
}
return modelString;
}
}
Code
List<string> CSVDataList = new List<string>();
List<Form> FormList = new List<Form>();
...
foreach (var data in FormList)
{
CSVDataList.Add(data.ToString());
}
Now you have a list of string CSVDataList with each Form object's data in comma style
P.S.
for DateTime
var value = property.GetValue(this);
if(value is DateTime date)
{
modelString += date.ToString("dd.MM.yyyy") + ",";
}
I am fairly new to the MVVM design pattern and integrated one yesterday in my program with the help of a fellow user here. However, I can't seem to get the values of the variables into another class via the { get; } function. I tried fixing this for quiet some time now and this is my last resort. This is just the script integrated in a wpf form, but the error is here, so I just pasted the code I thought to be neccesary.
public class ViewModel
{
public IEnumerable<string> ServerNames { get; }
= new string[] { "s1", "s2" };
public string SSN { get; set; }
= "s1";
public string APort { get; set; }
= "9999";
public string FPort { get; set; }
= "9991";
public string HostName { get; set; }
= "localhost";
}
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
Now, my thought would be to get the values of the viewmodel by just using { get; }
private class Server
{
public string HostName { get; }
public string APort { get; }
public string FPort { get; }
public string SSN { get; }
}
But this would just leave the 4 variables with a NULL value instead of getting the data from the view model.
How can I get the values of the variables from the view model for further usage into my private class called "Server"?
EDIT:
The server class is initiated later:
private void WPFLoginButton_Click(object sender, RoutedEventArgs e)
{
try
{
Server server = new Server();
HAServerConnection aConnection =
new HAServerConnection(server.HostName, UInt16.Parse(server.APort), new HACalls(), new HErrors());
Of course the values of the properties will be null until you actually set them to some values. You don't seem to be doing this somewhere in your code, and there is no other piece of code that will do it for you.
You could either add setters to the properties and set them when you initialize the Server:
Server server = new Server() { HostName = viewModel.HostName, APort = viewModel.Aport };
Or you could define a constructor that accepts some values and set the properties:
private class Server
{
public Server(string hostName, string aPort, string fPort, string sSN)
{
HostName = hostName;
APort = aPort;
FPort = fPort;
SSN = sSN;
}
public string HostName { get; }
public string APort { get; }
public string FPort { get; }
public string SSN { get; }
}
You will still need to get the actual values from somewhere when you initialize the class, like for example from the view model.
I have a list created from a stored procedure using EF6.0
I have also created 3 classes
public class Resas
{
public string todo{ get; set; }
public string prop { get; set; }
public string Code { get; set; }
public string statusCode { get; set; }
public string checkin { get; set; }
public string checkout { get; set; }
public List<profiles> profiles { get; set; }
}
public class profiles
{
public string action { get; set; }
public string id { get; set; }
public string profileType { get; set; }
public string title { get; set; }
public string firstName { get; set; }
public string middleName { get; set; }
public string lastName { get; set; }
public List<emailAddresses> emailAdresses { get; set; }
}
public class emailAddresses
{
public string emailAddress { get; set; }
public string emailAddress2 { get; set; }
}
I am doing a for-loop in the list and I need to get certain columns and put it in the array (I will put two, to keep it simple)
myEntities db = new myEntities();
List<rev_Result> revList = new List<rev_Result>();
revList.Clear();
revList = db.rev().ToList();
for (int i = 0; i < revList.Count(); i++)
{
Resas resas = new Resas();
profiles[] profiles = new profiles[1];
resas.todo = revList[i].todo;
resas.profiles[0].lastName = revList[i].lastName;
}
I am not familiar with C# as you can see from the psedo-code above.
I cannot figure out how to feed the Resas with data and then its Profile with data and then move to the next Resas entry.
Any help appreciated.
That's fairly simple using Linq:
Resas resas = new Resas();
resas.profiles = revList
.Select(x => new profiles() { action = x.todo, lastName = x.lastName })
.ToList();
What's happening here is: You loop through every entry in revList and get your wanted data structure (that's what Select is doing). x refers to the current entry in the loop, while the stuff to the right side of the arrow is you 'output': a new instance of your profiles class with the members assigned accordingly. The result of all of this is then converted to a list (before ToList(), think of it as a recipe to create the list) and assigned to resas.profiles.
By the way, a word on conventions: Usually, in C#, you would give your classes a name that starts with a capital letter. Also, your profiles class seems to contain data of exactly one profile, so a better name might be Profile. This also makes your data structure more clear, since List<profiles> seems to be a list of lists of profiles - but that's not what it actually is, is it?
Furthermore, Members generally start with a capital letter as well, so instead of action, lastName, you'd have: Action and LastName.
You can try with Linq. This is the code that should solve your issue, but Resas class doesn't have action property:
List<Resas> ls = revList.Select(x => new Resas() {
action = x.todo,
profiles = new List<profiles>() {
new profiles { lastName = x.lastName }
}
).ToList();
If you need to use action property of inprofiles` class:
List<Resas> ls = revList.Select(x => new Resas() {
profiles = new List<profiles>() {
new profiles {
action = x.todo,
lastName = x.lastName
}
}
).ToList();
In my common.cs class I have the below declarations for a list based on a class:
public static List<edbService> edb_service;
public class edbService
{
public string ServiceID { get; set; }
public string ServiceName { get; set; }
public string ServiceDescr { get; set; }
public string ServiceInterval { get; set; }
public string ServiceStatus { get; set; }
public string ServiceUrl { get; set; }
public string SourceApplication { get; set; }
public string DestinationApplication { get; set; }
public string Function { get; set; }
public string Version { get; set; }
public string userid { get; set; }
public string credentials { get; set; }
public string orgid { get; set; }
public string orgunit { get; set; }
public string customerid { get; set; }
public string channel { get; set; }
public string ip { get; set; }
}
I have a public method to populate the list from xml data files declared like this in the same class (common.cs):
#region PublicMethods
public List<edbService> populateEDBService(string xmlDataFile)
{
try
{
XElement x = XElement.Load(global::EvryCardManagement.Properties.Settings.Default.DataPath + xmlDataFile);
// Get global settings
IEnumerable<XElement> services = from el in x.Descendants("Service")
select el;
if (services != null)
{
edb_service = new List<edbService>();
foreach (XElement srv in services)
{
edbService edbSrv = new edbService();
edbSrv.ServiceID = srv.Element("ServiceID").Value;
edbSrv.ServiceName = srv.Element("ServiceName").Value;
edbSrv.ServiceDescr = srv.Element("ServiceDescr").Value;
edbSrv.ServiceInterval = srv.Element("ServiceInterval").Value;
edbSrv.ServiceStatus = srv.Element("ServiceStatus").Value;
edbSrv.ServiceUrl = srv.Element("ServiceUrl").Value;
foreach (XElement ServiceHeader in srv.Elements("ServiceHeader"))
{
edbSrv.SourceApplication = ServiceHeader.Element("SourceApplication").Value;
edbSrv.DestinationApplication = ServiceHeader.Element("DestinationApplication").Value;
edbSrv.Function = ServiceHeader.Element("Function").Value;
edbSrv.Version = ServiceHeader.Element("Version").Value;
foreach (XElement ClientContext in ServiceHeader.Elements("ClientContext"))
{
edbSrv.userid = ClientContext.Element("userid").Value;
edbSrv.credentials = ClientContext.Element("credentials").Value;
edbSrv.orgid = ClientContext.Element("orgid").Value;
edbSrv.orgunit = ClientContext.Element("orgunit").Value;
edbSrv.customerid = ClientContext.Element("customerid").Value;
edbSrv.channel = ClientContext.Element("channel").Value;
edbSrv.ip = ClientContext.Element("ip").Value;
}
}
edb_service.Add(edbSrv);
}
}
}
catch (Exception ex)
{
/* Write to log */
Common.logBuilder("CustomerCreate : Form --> CustomerCreate <--", "Exception", Common.ActiveMQ,
ex.Message, "Exception");
/* Send email to support */
emailer.exceptionEmail(ex);
}
return edb_service;
}
but the problem is, in my calling class when I try to have a list returned from this method, it is not found - I get a compile error that an object reference is required.
I am trying to call it like this:
Common.edbService edb_service = Common.populateEDBService("CardUpdate.xml");
and I get the below error:
An object reference is required for the non-static field, method, or property 'EvryCardManagement.Common.populateEDBService(string)'
What am I doing wrong?
I would like to have a generic method that can be called from several classes (which run async after being instantiated by background workers on my form)
You can try making your method as static.
public static List<edbService> populateEDBService(string xmlDataFile)
{
//Your code here
....
}
Now you can call this method from all the other classes by using common.populateEDBService();
You need either to create the class static, or to create an object to call it.
class edbService { }
public static void Main() {
//this is error
edbService.populateEDBService("");
//this is correct
edbService s = new edbService();
s.populateEDBService("");
}
The last line in my example shows the object reference required by the compiler. The s variable here is the object reference.
Are there any missing values in your XML? The.Value property won't work if the value is missing. So if ServiceID is missing then srv.Element("ServiceID").Value; will cause an error. You can get it to return an empty string for missing values, for example, by instead using (string)srv.Element("ServiceID");