ASP.NET MVC View is showing NULL - c#

I have a Controller that I have hard coded some values and expect the values to populate the 2 models with the data. However, there is one Model that is null when I run through the controller. Here are some snippets of the app.
When I run the code, Orders is null. I would expect there be 3 entries in customer orders but that is null.
CustomerOrderModel.cs:
public class CustomerOrderModel
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public string Description { get; set; }
public decimal Total { get; set; }
}
CustomerViewModel.cs:
public class CustomerViewModel
{
public int CustomerNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get { return FirstName + " " + LastName; }
}
public List<CustomerOrderModel> Orders { get; set; }
}
Controller.cs:
public IActionResult Orders()
{
decimal iTotal = 55.23M;
CustomerViewModel customer = new CustomerViewModel();
List<CustomerOrderModel> orders = new List<CustomerOrderModel>();
try
{
for (int i = 1; i < 4; i++)
{
var order = new CustomerOrderModel();
customer.CustomerNumber = 111111;
customer.FirstName = "John";
customer.LastName = "Smith";
order.OrderId = i;
order.OrderDate = DateTime.Now;
order.Description = "Part " + i;
order.Total = iTotal;
iTotal += order.Total;
orders.Add(order);
}
return View(customer);
}
catch (Exception)
{
return View("Error");
}
}
I have tried to re-code the IActionResult Orders() without any luck. customer.Orders gives me no members.
Re-code Orders
public IActionResult Orders1()
{
decimal iTotal = 55.23M;
List<CustomerOrderModel> orders = new List<CustomerOrderModel>();
for (int i = 1; i < 4; i++)
{
CustomerViewModel customer = new CustomerViewModel();
customer.Orders = new List<CustomerOrderModel>();
customer.CustomerNumber = 111111;
customer.FirstName = "John";
customer.LastName = "Smith";
}
return View();
}

In the public IActionResult Orders() action method set the Orders property value before render the view:
customer.Orders = orders;
return View(customer);
The reference type default value is null and this what you see.
Default values of C# types (C# reference)

Related

ASP.NET MVC 5 - How to get value Session into table data

I'm trying to get a value session and add it into a table
here is my code i tried to get value :
public ActionResult CheckOut(FormCollection form)
{
try
{
Cart cart = Session["Cart"] as Cart;
OrderPro _order = new OrderPro();//Bảng hóa đơn sản phẩm
_order.DateOrder = DateTime.Now;
_order.AddressDeliverry = form["AddressDelivery"];
_order.IDCus = Convert.ToInt32(Session["ID"]);
db.OrderProes.Add(_order);
foreach (var item in cart.Items)
{
OrderDetail _order_detail = new OrderDetail();
_order_detail.IDOrder = _order.ID;
_order_detail.IDProduct = item.product.ProductID;
_order_detail.UnitPrice = (double)item.product.Price;
_order_detail.Quantity = item.quantity;
db.OrderDetails.Add(_order_detail);
}
db.SaveChanges();
cart.ClearCart();
return RedirectToAction("CheckOut_Success", "GioHang");
}
catch
{
return Content("<script language='javascript' type='text/javascript'>alert('Đã xảy ra lỗi, vui lòng kiểm tra thông tin');</script>");
}
}
here is the code Session :
public ActionResult Login(CustomerUser cus)
{
var check = db.CustomerUsers.Where(s => s.NameUser == cus.NameUser && s.PasswordUser == cus.PasswordUser).FirstOrDefault();
if(check == null)
{
ViewBag.ErrorLogin = "Sai info đăng nhập";
return View("Index");
}
else
{
db.Configuration.ValidateOnSaveEnabled = false;
Session["NameUser"] = cus.NameUser;
Session["PasswordUser"] = cus.PasswordUser;
Session["ID"] = cus.ID;
return RedirectToAction("DichVu", "Product");
}
}
Here is the model Session ID :
public partial class CustomerUser
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public CustomerUser()
{
this.OrderProes = new HashSet<OrderPro>();
}
public int ID { get; set; }
public string NameUser { get; set; }
public string PasswordUser { get; set; }
public string PhoneUser { get; set; }
public string EmailUser { get; set; }
}
i tried to debug but i get a error like this
enter image description here

How to determine whether a model is valid?

I am having some trouble here. The situation is to update an existing record, at the same time, save a new row if there is no record by searching first the table.
When I am saving a new record, there is no problem. But when I'm trying to update an existing one, there are no changes. I tried to place some breakpoints specifically on the code that do the thing. It just ending up on the line if(!ModelState.IsValid).
Note:
Some of the lines are hard-coded for the sake of having some dummy data.
Function for retrieving some data from DB to pass to view model
[HttpGet]
public ActionResult CardNumberAssignment(string empId, int cardNumberId)
{
var getIdDetails = dbContext.CardNumberAssignments.Where(c => c.CardNumberId == cardNumberId && c.IsActive == true).SingleOrDefault();
if (cardNumberId == 0) //EMPLOYEE HAS NO CARD NUMBER YET
{
var viewModel = new CardNumberQRCodeVM
{
CardNumberId = 0,
CMId = empId,
OldQRCode = "No QR Code history",
OldReservedCardNumber = "No Card Number history",
NewReservedCardNumber = GetRandomCardNumber()
};
return View(viewModel);
}
else
{
if (getIdDetails.CMId != empId) //JUST CHECKING IF THE EMPLOYEE HAS THE CORRECT CARDNUMBERID FROM DB
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var empCardDetails = dbContext.CardNumberAssignments
.Include(c => c.ReservedCardNumber)
.Where(emp => emp.CMId == empId && emp.IsActive == true)
.Select(fields => new CardNumberQRCodeVM
{
CardNumberId = fields.CardNumberId,
CMId = empId,
OldQRCode = fields.QRCode,
IsActive = fields.IsActive,
OldReservedCardNumber = fields.ReservedCardNumber.CardNumber,
}).FirstOrDefault();
empCardDetails.NewReservedCardNumber = GetRandomCardNumber();
return View(empCardDetails);
}
}
Function for adding/editing record
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveIdInformation(CardNumberQRCodeVM vm)
{
if (!ModelState.IsValid)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// JUST ADDING/EDITING SOME CARD NUMBERS....
else
{
if (vm.CardNumberId == 0) //INSERT A NEW ROW FOR NEW CARD NUMBER AND QR CODE
{
var newCardNumber = new ReservedCardNumber
{
CardNumber = vm.NewReservedCardNumber,
IsActive = true,
CreatedDate = DateTime.Now,
CreatedBy = "Paolo",
ModifiedDate = DateTime.Now,
ModifiedBy = "Paolo"
};
dbContext.ReservedCardNumbers.Add(newCardNumber);
var newIdInfo = new CardNumberAssignment
{
CardNumberId = newCardNumber.Id,
QRCode = vm.NewQRCode,
CMId = vm.CMId,
IsActive = true,
CreatedDate = DateTime.Now,
CreatedBy = "Paolo",
ModifiedDate = DateTime.Now,
ModifiedBy = "Paolo"
};
dbContext.CardNumberAssignments.Add(newIdInfo);
}
else // EDIT EXISTING
{
var getEmployeeIdInDb = dbContext.CardNumberAssignments.Single(e => e.Id == vm.CardNumberId);
getEmployeeIdInDb.ReservedCardNumber.CardNumber = vm.NewReservedCardNumber;
getEmployeeIdInDb.QRCode = vm.NewQRCode;
getEmployeeIdInDb.IsActive = true;
getEmployeeIdInDb.ModifiedDate = DateTime.Now;
getEmployeeIdInDb.ModifiedBy = "Paolo";
}
dbContext.SaveChanges();
}
return RedirectToAction("CMDetails", "Admin", new { #empId = vm.CMId });
}
View model
public class CardNumberQRCodeVM
{
public int CardNumberId { get; set; }
public string CMId { get; set; }
[Display(Name = "Existing QR Code")]
public string OldQRCode { get; set; }
[Required]
[Display(Name = "New QR Code")]
public string NewQRCode { get; set; }
[Display(Name = "Resigned Cast Member?")]
public bool IsActive { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public string ModifiedBy { get; set; }
public DateTime ModifiedDate { get; set; }
public ReservedCardNumber ReservedCardNumber { get; set; }
[Display(Name = "Old Card Number")]
public string OldReservedCardNumber { get; set; }
[Display(Name = "New Card Number")]
public string NewReservedCardNumber { get; set; }
}

Entity Framework related entities on object is not updated

Whenever I try to change Department and Position objects of the Employee class they are not updating inside database on the Employee entity. For example, I want to change employee Position from junior (id - 1, name of the position - junior) to middle (id - 2, name of the position - middle). But, whenever I try to save this changes to the database they don't apply.
My Employee entity
public class Employee
{
public int EmployeeId { get; set; }
public string FullName { get; set; }
public Department Department { get; set; }
public EmployeePosition Position { get; set; }
public string Head { get; set; }
public double Salary { get; set; }
public Employee()
{
Department = new Department();
Position = new EmployeePosition();
}
}
EmployeePosition entity
public class EmployeePosition
{
public int Id { get; set; }
public string Name { get; set; }
}
My modify employee method in ViewModel
public void ModifyEmployee(int id)
{
Employee employee = employeeRepository.GetEmployee(id);
using (var context = new PowerCoEntity())
{
employee.Position = context.EmployeePositions.FirstOrDefault(d => d.Id == SelectedPositionId);
employee.Department = context.Deprtments.FirstOrDefault(d => d.DepartmentId == SelectedDepartmentId);
if (SelectedHeadId != null)
employee.Head = employeeRepository.GetHeadName(SelectedHeadId.Value);
else employee.Head = "";
}
employee.Salary = Employee.Salary;
employee.FullName = Employee.FullName;
employeeRepository.ModifyEmployee(employee);
}
Modify method in the context class
public void ModifyEmployee(Employee employee)
{
using (var context = new PowerCoEntity())
{
context.Entry(employee).State = EntityState.Modified;
context.SaveChanges();
}
}
UPDATE 1
I got it working by changing ModifyEmployee methods in the ViewModel and Context class. But I need to pass all the parameters through method now. How can I be able to use different contexts to modify object?
Context class:
public void ModifyEmployee(int id, int selectedPositionId, int selectedDepartmentId, int? selectedHeadId, Employee employee)
{
using (var context = new PowerCoEntity())
{
Employee emp = context.Employees.FirstOrDefault(e=> e.EmployeeId == 32);
emp.Salary = employee.Salary;
emp.FullName = employee.FullName;
emp.Department = employee.Department;
emp.Position = context.EmployeePositions.FirstOrDefault(d => d.Id == selectedPositionId);
emp.Department = context.Deprtments.FirstOrDefault(d => d.DepartmentId == selectedDepartmentId);
if (selectedHeadId != null)
emp.Head = GetHeadName(selectedHeadId.Value);
else emp.Head = "";
emp.Salary = employee.Salary;
emp.FullName = employee.FullName;
context.Entry(emp).State = EntityState.Modified;
context.SaveChanges();
}
}
ViewModel:
public void ModifyEmployee(int id)
{
Employee employee = new Employee();
employee.Salary = Employee.Salary;
employee.FullName = Employee.FullName;
employeeRepository.ModifyEmployee(id, SelectedPositionId, SelectedDepartmentId, SelectedHeadId, employee);
}

Dapper MultiMapping not working

I'm trying to create a List of object Work using Dapper to do the mapping.
This is the code:
public class Work
{
public int id { get; set; }
public int id_section { get; set; }
public decimal price { get; set; }
public Model id_model { get; set; }
public Type id_type { get; set; }
}
class Model
{
public int id_model { get; set; }
public string Name { get; set; }
}
class Type
{
public int id_type { get; set; }
public string Name { get; set; }
}
public List<Work> GetListOfWork(int idList)
{
using (DatabaseConnection db = new DatabaseConnection()) //return a connection to MySQL
{
var par = new {Id = idList};
const string query = "SELECT id,id_section,price,id_model,id_type FROM table WHERE id_section = #Id";
return db.con.Query<Work, Model, Type, Work>(query,
(w, m, t) =>
{
w.id_model = m;
w.id_type = t;
return w;
}, par, splitOn: "id_model,id_type").ToList();
}
}
It doesn't give me any error but id_model and id_type in my the returned List are always empty (The object are created but all the fields are empty or null), other fields are mapped correctly.
Any clue ?
You need to add yourself the joins in the query string
Probably it is something like this
var par = new {Id = idList};
const string query = #"SELECT w.id,w.id_section,w.price,
m.id_model, m.Name, t.id_type, t.Name
FROM work w INNER JOIN model m on w.id_model = m.id_model
INNER JOIN type t on w.id_type = t.id_type
WHERE w.id_section = #Id";
return db.con.Query<Work, Model, Type, Work>(query,
(w, m, t) =>
{
w.id_model = m;
w.id_type = t;
return w;
}, par, splitOn: "id_model,id_type").ToList();

How do I extend a model class to another model?

I am trying to extend a class to another class that will collect them as a list.
model:
public class Brand
{
public int BrandId { get; set; }
public string Name { get; set; }
public string Guid { get; set; }
public float Rating { get; set; }
public string Industry { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string CountryCode { get; set; }
public virtual Snapshot Snapshot { get; set; }
}
public class Snapshot
{
public int ID { get; set; }
public string Guid { get; set; }
public int CompanyID { get; set; }
public string CompanyName { get; set; }
public string Email { get; set; }
public DateTime DateTimeSent { get; set; }
public string Subject { get; set; }
public string Html { get; set; }
public string Image { get; set; }
public string Unsubscribe { get; set; }
}
public class BrandSnaphotViewModel
{
public Brand Brand { get; set; }
public List<Snapshot> SnapshotItems { get; set; }
}
controller:
public ActionResult Index(string brandGuid)
{
BrandSnaphotViewModel viewModel = new BrandSnaphotViewModel();
Brand brand = GetBrand(brandGuid);
viewModel.Brand = brand;
List<Snapshot> snapshot = GetBrandSnapshots(brand.BrandId);
viewModel.SnapshotItems = snapshot;
List<BrandSnaphotViewModel> viewModelList = new List<BrandSnaphotViewModel>();
viewModelList.Add(viewModel);
return View(viewModelList.AsEnumerable());
}
private Brand GetBrand(string brandGuid)
{
Brand brand = new Brand();
string dbConnString = WebConfigurationManager.ConnectionStrings["dbConn"].ConnectionString;
MySqlConnection dbConn = new MySqlConnection(dbConnString);
dbConn.Open();
MySqlCommand dbCmd = new MySqlCommand();
dbCmd.CommandText = "SELECT *, industries.name AS industry_name FROM brands LEFT JOIN industries ON brands.industry_id = industries.industry_id WHERE brand_guid = '" + brandGuid.ToString() + "' AND private = 0 LIMIT 1";
dbCmd.Connection = dbConn;
MySqlDataReader dbResult = dbCmd.ExecuteReader();
if (dbResult.Read())
{
brand.Guid = dbResult["brand_guid"].ToString();
brand.BrandId = Convert.ToInt32(dbResult["brand_id"]);
brand.Industry = dbResult["industry_name"].ToString();
}
dbResult.Close();
dbConn.Close();
return brand;
}
private List<Snapshot> GetBrandSnapshots(int brandId)
{
string dbConnString = WebConfigurationManager.ConnectionStrings["dbConn"].ConnectionString;
MySqlConnection dbConn = new MySqlConnection(dbConnString);
dbConn.Open();
MySqlCommand dbCmd = new MySqlCommand();
dbCmd.CommandText = "SELECT * FROM snapshots WHERE brand_id = " + brandId + " AND archive = 0 ORDER BY date_sent DESC";
dbCmd.Connection = dbConn;
MySqlDataReader dbResult = dbCmd.ExecuteReader();
List<Snapshot> snapshots = new List<Snapshot>();
while (dbResult.Read())
{
snapshots.Add(new Snapshot
{
SnapshotId = Convert.ToInt32(dbResult["snapshot_id"]),
Subject = dbResult["subject"].ToString(),
DateTimeSent = Convert.ToDateTime(dbResult["date_sent"]),
Image = dbResult["image"].ToString(),
Email = dbResult["email"].ToString(),
ContentType = dbResult["content_type"].ToString(),
Type = dbResult["type"].ToString()
});
}
dbResult.Close();
dbConn.Close();
return snapshots;
}
edit
FIXED
The issue was the VIEW was not referencing the ViewModel as an IENumerable<>. FACEPALM.
#model IEnumerable<projectvia.ViewModels.BrandSnaphotViewModel>
#{
ViewBag.Title = "Index";
}
#foreach(var item in Model)
{
#item.Brand.Guid;
for(int i = 0; i< #item.SnapshotItems.Count; i++)
{
#item.SnapshotItems[i].Subject<br/>
}
}
That resolved the issue.
Thank you both experts for the insights... i took both advice and came to this solution.
you are doing wrong, it is a list.
you cannot add element this way. Create object and add that object in list by calling Add()
do like this to add items in it:
List<BrandEmailList> brandSnapshotsList = new List<BrandEmailList>();
while (dbResult.Read())
{
BrandEmailList brandSnapshots = new BrandEmailList (); // create an object
brandSnapshots.ID = Convert.ToInt32(dbResult["snapshot_id"]);
brandSnapshots.Guid = dbResult["snapshot_guid"].ToString();
brandSnapshots.DateTimeSent = dbResult["date_sent"];
brandSnapshots.Subject = dbResult["subject"].ToString();
brandSnapshots.Image = dbResult["image"];
brandSnapshotsList.Add(brandSnapshots); // add it in list
}
EDIT:
List is a generic thing, you don't need to create a class for it. you can just instantiate a list and add items in it.
why are you doing like that you can do it this way simply:
List<Snapshot> brandSnapshotsList = new List<Snapshot>();
while (dbResult.Read())
{
Snapshot brandSnapshots = new Snapshot(); // create an object
brandSnapshots.ID = Convert.ToInt32(dbResult["snapshot_id"]);
brandSnapshots.Guid = dbResult["snapshot_guid"].ToString();
brandSnapshots.DateTimeSent = dbResult["date_sent"];
brandSnapshots.Subject = dbResult["subject"].ToString();
brandSnapshots.Image = dbResult["image"];
brandSnapshotsList.Add(brandSnapshots); // add it in list
}
Building on what Ehsan Sajjad did, looking at public IEnumerator<Snapshot> BrandEmails, i believe what you look for looks more like this:
public class Snapshot
{
public int ID { get; set; }
public string Guid { get; set; }
// ...
}
public class BrandEmailList : List<Snapshot>
{
}
You need not even create a new type for your brand email list, you can use List<Snapshot> directly.
public ViewResult Whatever() {
var brand = GetBrand(brandName);
var brandSnapshots = GetBrandSnapshots();
return View(brand, brandSnapshots);
}
private Brand GetBrand(string brandName)
{
try
{
var brand = new Brand();
brand.Name = brandName;
// database stuffs ...
return brand;
}
catch (Exception ex)
{
throw ex;
}
}
private List<Snapshot> GetBrandSnapshots()
{
// ...
// DB stuffs -- that *really* should not be in the controller anyways.
// ...
var snapshots = new List<BrandEmailList>();
while (dbResult.Read())
{
// object initializer syntax
snapshots.Add(new Snapshot {
ID = Convert.ToInt32(dbResult["snapshot_id"]),
Guid = dbResult["snapshot_guid"].ToString(),
DateTimeSent = dbResult["date_sent"],
Subject = dbResult["subject"].ToString(),
Image = dbResult["image"],
});
}
return snapshots
}
As a side note, mixing database access into controller methods can be a bad idea. It does not have to be, but it can be. Generally, fetching data from the database happens at a different "level" than serving a MVC result. MVC controller don't have the "purpose" to talk to a database, that work can/should be delegated to a dedicated type. Compare the single responsibility principle part of the SOLID principles.

Categories