When Deserializing Json Object expected result is not correct? - c#

While doing JSON example, I have reached a point where i have a gridview and it should be bind to datasource. The datasource is in Json object
The code
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Employee employee = new Employee();
var list = employee.CreateEmployees();
var query = from emp in list.AsEnumerable()
select new
{
id = (int)emp.EmployeeId,
name = (string)emp.Name,
nic = (string)emp.Nic,
salary = (int)emp.Salary
};
JObject o = JObject.FromObject(new
{
Employees = query
});
Response.Write(o);
Session["JsonEmployee"] = o;
}
LoadGrid();
}
For loading Grid:
void LoadGrid() {
List<Employee> lst = new List<Employee>();
var objects = (JObject)Session["JsonEmployee"];
foreach (var v in objects)
{
lst = JsonConvert.DeserializeObject<List<Employee>>(v.Value.ToString());
}
GridView1.DataSource = lst;
GridView1.DataBind();
}
All works fine but the only problem is that the EmployeeId is 0 for every employee.
Employee class is as:
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Nic { get; set; }
public int Salary { get; set; }
.....
}
Note in the json object every employee has correct id but when it convert it to list getting employeeid 0 for every employee.

In the one object it's called id and in the other EmployeeId. Name them the same, it should solve the issue

Related

Data is not added well to ListView. (C# window form)

I added 3 columns.
The modified attribute values are as follows.
View - Details
Onwer - True
GirdLines - True
FullRowSelect - True
namespace TestWinForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void add_Click(object sender, EventArgs e)
{
//listView1.BeginUpdate();
string[] row = { "123", "456", "789" };
ListViewItem list_view = new ListViewItem(row);
listView1.Items.Add(list_view);
textBox1.Text = listView1.Items.Count.ToString();
//listView1.EndUpdate();
}
}
}
It is a code that updates the number of current rows to the textbox1 after adding a data row every time the add button is clicked.
Obviously, The number of rows keeps going up.... but the data is not output to listView1.
Which part should I check?
What you have should work in detail view with columns added. Here is an example
Design view
In this case a instance of the following class is used so later we can get information about a specific row.
public class Contact
{
public int CustomerIdentifier { get; set; }
public string CompanyName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneTypeDescription { get; set; }
public string PhoneNumber { get; set; }
public string CountryName { get; set; }
public string[] ItemArray => new[]
{
CompanyName,
FirstName,
LastName,
PhoneNumber,
CountryName
};
}
Code to do a mock add
private void AddRowButton_Click(object sender, EventArgs e)
{
var companyName = "Just added";
Contact contact = new Contact()
{
CompanyName = companyName,
FirstName = "Karen",
LastName = "Payne",
PhoneNumber = "123-333-4444",
CountryName = "USA"
};
ownerContactListView.Items.Add(
new ListViewItem(contact.ItemArray)
{
Tag = contact.CustomerIdentifier
});
CountLabel.Text = $#"Row count: {ownerContactListView.Items.Count}";
var index = ownerContactListView.Items.IndexOf(
ownerContactListView.FindItemWithText(companyName));
ownerContactListView.Items[index].Selected = true;
ownerContactListView.EnsureVisible(index);
ActiveControl = ownerContactListView;
}
After adding the row above (note I shorten the form so what you see is a partial view)
You can see the entire the initial load, see the following.
Havent used Winforms in ages, but I remember that using a binding source was more reliable
var bindingSource = new BindingSource();
bindingSource.DataSource = dataTable;
grid.DataSource = bindingSource;
//Add data to dataTable and then call
bindingSource.ResetBindings(false)

How to return lIEnumerable list

i am new to programming and i got stuck. I am not very sure how to return my list. Can someone help now i get only System.IEnumerable and if i try to use foreach i cant iterate over the Employee
public class Employee
{
public string Name { get; set; }
public int Id { get; set; }
public IEnumerable<Employee> GetEmployees()
{
return new List<Employee>
{
new Employee { Name = "Tom", Id = 1 },
new Employee { Name = "Peter", Id = 3 },
new Employee { Name = "Michael", Id = 2 }
};
}
}
class Program
{
static void Main(string[] args)
{
var employee = new Employee();
foreach(var emp in Employee)
{
}
}
}
You can do like this.
Employee emp = new Employee();
IEnumerable<Employee> ls = emp.GetEmployees();
foreach( Employee e in ls)
{
}
In your foreach loop, you forgot to invoke your method GetEmployees. You need to do it if you want to iterate over it.
foreach(var emp in Employee.GetEmployees())

Get subclass content from object

I have the following classes
public enum Category { foo, foo1, foo2 }
public class Event
{
public DateTime Timestamp { get; set; } = DateTime.Now;
public string GameTime { get; set; }
public string Content { get; set; }
public Person Author { get; set; }
public Category Category { get; set; }
}
and
public class MemberEvent : Event
{
public Member Person { get; set; }
}
The object is created correctly, but if I want to call "Person", this is not displayed to me. If I have a var match, I can call for example match[0].Timestamp but not match[0].Person. The Event object is stored in a List, therefore also the index. I feel I'm missing something simple.
UPDATE: The Code that create the Object
var match = SessionController.Instance.Current;
DataTable dt = dataGrid.ItemsSource as DataTable;
foreach (System.Data.DataRow item in dt.Rows)
{
var memberFoo = new MemberEvent();
memberFoo.Category = Category.Warning;
memberFoo.Time = item["Time"].ToString();
var person = new Person();
person.FirstName = item["FirstName"].ToString();
person.LastName = item["LastName"].ToString();
var passport = new Passport();
passport.Active = true;
passport.PassNumber = item["Pass"].ToString();
passport.Player = person;
memberFoo.Person = passport;
match.Match.Events.Add(memberFoo);
}
SessionController.Instance.Current = match;
Cast your instance to the expected type and test for null to guard for the unexpected:
var memberEvent = match[0] as MemberEvent;
if (memberEvent != null)
{
Console.WriteLine(memberEvent.Person)
}
You will have to cast your Event into a MemberEvent if you want to access the Person property. It is not possible to get the property from Event.
List<Event> myEvents = GetMyEvents();
var myMemberEvent = (MemberEvent)myEvent[0];
It can cause an exception if it can't convert to MemberEvent.

Assign value to member variable failed, StackOverflowException occured

I want to assign a List to a member variable (the variable is a List), but I always get error message: System.StackOverflowException was unhandled, I don't know why, please see my code below:
public class Employee
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public int DeptID { get; set; }
}
public class Department
{
public int DeptID { get; set; }
public string DeptName { get; set; }
public List<Employee> Employees
{
set { Employees = value; }
//get { return EmployeeDataAccessLayer.getEmployeesByDeptID(DeptID); }
get { return Employees; }
}
}
public class EmployeeDataAccessLayer
{
public static List<Employee> getEmployeesByDeptID(int deptID)
{
string conStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string sqlStr = "select * from tblemployee where deptid = :deptid order by employeeid asc";
List<Employee> employees = new List<Employee>();
using (OracleConnection ocon = new OracleConnection(conStr))
{
OracleCommand ocmd = new OracleCommand(sqlStr, ocon);
ocmd.Parameters.Add(":deptid", deptID);
ocmd.Connection.Open();
OracleDataReader rdr = ocmd.ExecuteReader();
while (rdr.Read())
{
Employee employee = new Employee();
employee.EmployeeID = Convert.ToInt32(rdr["EMPLOYEEID"]);
employee.EmployeeName = rdr["NAME"].ToString();
employee.DeptID = Convert.ToInt32(rdr["DEPTID"]);
employees.Add(employee);
}
}
return employees;
}
}
public class DepartmentDataAccessLayer
{
public static List<Department> getAllDepartments()
{
string conStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string sqlStr = "select * from tbldepartment order by departmentid asc";
List<Department> depts = new List<Department>();
using (OracleConnection ocon = new OracleConnection(conStr))
{
OracleCommand ocmd = new OracleCommand(sqlStr, ocon);
ocmd.Connection.Open();
OracleDataReader rdr = ocmd.ExecuteReader();
while (rdr.Read())
{
Department dept = new Department();
dept.DeptID = Convert.ToInt32(rdr["DEPARTMENTID"]);
dept.DeptName = rdr["NAME"].ToString();
dept.Employees = EmployeeDataAccessLayer.getEmployeesByDeptID(dept.DeptID);
depts.Add(dept);
}
}
return depts;
}
}
so, I debug it and found the exception occured at:
set { Employees = value;}
see below screenshot:
I really don't know why, can you tell me the reason or give me some suggestions?
In your case, when you assign something to the Employees it's setter will trigger it again assigns to the same variable so the same process will continues and it's leads to a infinity assignments, that's why you are getting that Exception. to overcome this Change the property definition like this:
private List<Employee> _Employees
public List<Employee> Employees
{
set { _Employees = value; }
get { return _Employees; }
}
or like this:
public List<Employee> Employees { get; set; }
Because you're setting Employees to value which is setting Employees to value which is setting Employees to value which is setting.......etc etc until the stack overflows.
Because you're not using a private variable to hold employees, you can just use an auto-getter and -setter to set the value to itself, like your other properties:
public List<Employee> Employees { get; set; }
Otherwise, setup a private variable to hold the list of employees. This can be use
private List<Employee> _employees;
public List<Employee> Employees
{
set { _employees = value; }
get { return _employees; }
}
If you're setting a value in C# with get and set, all you'll need to do is
public List<Employee> Employees{get; set;}
With an empty get and set block, the value will be assigned automatically. In your code, you're essentially calling the set function for your variable over and over again until a StackOverflow exception occurs
More information on properties here

How to get value from dropdown to insert in EF CodeFirst

I am working on Webforms (no MVC) I have the following scenario. I want to get ID of selected text of dropdown and insert on click event. but it is showing conversion error from string to EFCode.Department.
Code
EmployeeDbContext db = new EmployeeDbContext();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DropDownList1.DataSource = db.Departments.ToList();
DropDownList1.DataBind();
}
GridView1.DataSource = db.Departments.Include("Employees").ToList();
GridView1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
Employee emp = new Employee(){Name = TextBox1.Text,
Gender= TextBox2.Text,
Salary = float.Parse(TextBox3.Text),
**Department = DropDownList1.SelectedValue**}; // error here
db.Employees.Add()
db.SaveChanges();
}
public class Department
{
public int ID { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public List<Employee> Employees { get; set; }
}
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public float Salary { get; set; }
**public Department Department { get; set; }**
}
public class EmployeeDbContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public DbSet<Department> Departments { get; set; }
}
you cannot use string substitute department object
when you execute the code the relation will be int , there for you must use conversion to Int32
Employee emp = new Employee(){Name = TextBox1.Text,
Gender= TextBox2.Text,
Salary = float.Parse(TextBox3.Text),
Department = db.GetDepartmentByID(Convert.ToInt32(DropDownList1.SelectedValue))};
Employee emp = new Employee(){Name = TextBox1.Text,
Gender= TextBox2.Text,
Salary = float.Parse(TextBox3.Text),
Department = db.FirstOrDefault(x => x.Name == DropDownList1.SelectedValue)};
You cant declare department as a property.. I have modified your code in the way that Name will be retrived from your department table which is in your database by using the dropDownList1.SelectValue.. Not sure whether this is your requirement..
Code:
protected void Button1_Click(object sender, EventArgs e)
{
Employee emp = new Employee(){
Name = TextBox1.Text,
Gender= TextBox2.Text,
Salary = float.Parse(TextBox3.Text),
Department = new Department()
{
Name = db.Department.Where(s => s.Id == dropDownList1.SelectValue).Select(s.Name).FirstOrDefault();
},
};
db.Employees.Add();
db.SaveChanges();
}
Your problem is in the page load
if (!IsPostBack)
{
DropDownList1.DataSource = db.Departments.ToList();
DropDownList1.DataBind();
}
You need to add this
if (!IsPostBack)
{
DropDownList1.DataSource = db.Departments.ToList();
DropDownList1.DataTextField = "Name";
DropDownList1.DataValueField = "ID"; **//This will get the id**
DropDownList1.DataBind();
}
Also convert to Int: (Convert.ToInt32(Dropdownlist.SelectedValue))

Categories