There are Supplier model and User model in my project, every Supplier has a few Users
Supplier model
public class SupplierRow
{
public Guid Id { get; set; }
public string FullName { get; set; }
public bool Subscribed { get; set; }
public bool Active { get; set; }
public int Visits { get; set; }
public List<UserRow> Users { get; set; }
public bool AllInactive
{
get
{
foreach (UserRow ur in Users)
{
if (ur.Status == 1) return false;
}
return true;
}
}
}
and User model
public class UserRow
{
public Guid Id { get; set; }
public string FullName { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Status { get; set; }
public int Role { get; set; }
public Guid SupplierId { get; set; }
}
then I use my models in controller
public ActionResult Grid(bool? active)
{
var suppliers = Context.Suppliers.AsNoTracking()
.WhereIf(active != null, e => e.Active == active)
.Select(e => new SupplierRow
{
Id = e.Id,
FullName = e.FullName,
Active = e.Active,
Visits = e.Visits,
})
.ToList();
List<Guid> supplierIds = new List<Guid>();
foreach (SupplierRow sr in suppliers)
{
supplierIds.Add(sr.Id);
}
var users = Context.Users.AsNoTracking()
.Where(e => supplierIds.Contains(e.SupplierId.Value))
.Select(e => new UserRow
{
Id = e.Id,
FullName = e.FullName,
Email = e.Email,
Name = e.Name,
Status = e.Status,
Role = e.Role,
SupplierId = e.SupplierId.Value
}).ToList();
foreach (UserRow ur in users)
{
foreach (SupplierRow sr in suppliers)
{
if (ur.SupplierId == sr.Id)
{
sr.Users.Add(ur);
}
}
}
return PartialView("_Grid", suppliers);
}
but when I try to debug my project I get some exception here
What's wrong? How can I fix that?
Your Users list are not initialized. Create a new list before accessing it Users = new List<UserRow>(); You can change the SupplierRow class:
public class SupplierRow {
private List<UserRow> users = new List<UserRow>();
public List<UserRow> Users
{
get { return users; }
set { users = value; }
}
...
}
or in the constructor:
public class SupplierRow
{
public SupplierRow()
{
Users = new List<UserRow>();
}
public List<UserRow> Users { get; set; }
...
}
or before accessing it:
foreach (UserRow ur in users)
{
foreach (SupplierRow sr in suppliers)
{
sr.Users = new List<UserRow>();
if (ur.SupplierId == sr.Id)
{
sr.Users.Add(ur);
}
}
}
or you can just use linq:
foreach (SupplierRow sr in suppliers)
{
sr.Users = users.Where(user => user.SupplierId == sr.Id);
}
return PartialView("_Grid", suppliers);
Related
I am trying to Edit existing instance of class project using a viewmodel. I think I have no issues in the GET method of the Edit (everything renders fine on the View) but I am struggling with the POST method. The problem is the POST method creates new instance of the project instead updating the current one.
This is my model:
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
public Project()
{
}
}
}
This is my CreateProjectViewModel (some of the attributes are not used in the controller code below):
public class CreateProjectViewModel
{
//project
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
//clients
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
//Members
public int MemberId { get; set; }
public Member Member { get; set; }
public Project Project { get; set; }
public List<SelectListItem> Members { get; set; }
public IEnumerable<SelectListItem> Clients { get; set; }
public IEnumerable<int> SelectedMembers { get; set; }
public CreateProjectViewModel() { }
}
}
This is My Edit GET method in ProjectController:
public async Task<IActionResult> Edit(int? id)
{
Project project = await _context.Project
.FirstOrDefaultAsync(m => m.ProjectId == id);
var members = _context.Member
.Select(m => new SelectListItem { Value = m.MemberId.ToString(), Text = m.MemberName }).ToList();
var clients = _context.Client
.Select(r => new SelectListItem { Value = r.ClientId.ToString(), Text = r.Name }).ToList();
CreateProjectViewModel viewmodel = new CreateProjectViewModel
{
Name = project.Name,
Budget = project.Budget,
BusinessCase = project.BusinessCase,
StartDate = project.StartDate,
FinishDate = project.FinishDate,
Project = project,
Clients = clients,
Members = members
};
return View(viewmodel);
This is my Edit POST method in ProjectController which is wrongly creating a new project instead of updating the current project:
(The controller is trying to save values to Project Model and at the same time in Join table containing MemberId and ProjectID - this works fine when creating a project, not sure if correct for updating)
public IActionResult Edit(int? id, CreateProjectViewModel model)
{
Project project = _context.Project
.Single(m => m.ProjectId == id);
//this is to post in many-to-many join table between Member and Project
var projectID = project.ProjectId;
var memberID = model.MemberId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
foreach (var selectedId in model.SelectedMembers)
{
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
//this is to update the values in the project which refers to ProjectID
project.ProjectId = model.ProjectId;
project.Name = model.Name;
project.Budget = model.Budget;
project.BusinessCase = model.BusinessCase;
project.StartDate = model.StartDate;
project.FinishDate = model.FinishDate;
project.ClientId = model.ClientId;
_context.Entry(project).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
Can you guys advise me what should be changed in either method to get the expected result?
Thanks a lot.
After some digging done this is the working code.
Edit POST Method:
public IActionResult Edit(int? id, CreateProjectViewModel viewmodel)
{
if (ModelState.IsValid)
{
var project = _context.Project
.SingleOrDefault(m => m.ProjectId == id);
//this is to update the Project from the viewmodel
project.Name = viewmodel.Name;
project.Budget = viewmodel.Budget;
project.BusinessCase = viewmodel.BusinessCase;
project.StartDate = viewmodel.StartDate;
project.FinishDate = viewmodel.FinishDate;
project.ClientId = viewmodel.ClientId;
//code below is to validate if the matched primary keys of Project and Member are not already in ProjectMembers table
foreach (var selectedId in viewmodel.SelectedMembers)
{
var projectID = project.ProjectId;
var memberID = selectedId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
//this is to add new entry into ProjectMembers table
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
_context.SaveChanges();
}
return RedirectToAction("Index");
The problem I'm having goes like this:
I have a textbox in my view that allows search/filter functionality of the Orders table. However, I would like it to be able to also search by the child table OrderDetails and filter appropriately.
The search textbox works for the order table but not the order details.
I realize this code can be shrunk down a lot but I'm new coding.
Something that may help - I'm doing Database first
Here is my code so far.
Controller:
EntitiesDB db = new EntitiesDB();
#region INDEX MAIN PAGE
[HttpGet]
public ActionResult Index(string sortOrder, string currentFilter, int? page, string jobNumberDropDown, string requesitionerDropDown, string supplierDropDown, string dateRequestedDropDown, string dateRequiredDropDown, string searchString)
{
var getSupplierList = db.Suppliers.OrderBy(SL => SL.SupplierName).ToList();
var getEmployeeList = db.Employees.OrderBy(EL => EL.FullName).ToList();
SelectList listOfSuppliers = new SelectList(getSupplierList, "SupplierName", "SupplierName");
SelectList listOfEmployees = new SelectList(getEmployeeList, "FullName", "FullName");
ViewBag.supplierNames = listOfSuppliers;
ViewBag.employeeNames = listOfEmployees;
#region PAGINATION FUNCTION
//Code for Paging
ViewBag.CurrentSort = sortOrder;
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = currentFilter;
int pageSize = 10;
int pageNumber = (page ?? 1);
#endregion
#region SEARCH FUNCTION
//Creates the LINQ Query to select the Orders from the ORDERS table
//var orders = from o in db.Orders join c in db.OrderDetails on o.OrderID equals c.OrderID select new { orders = o.JobNumber, o.PurchaseOrder, c.Description, c.PartNumber, c.AngstromPartNumber };
var orders = from o in db.Orders.Where(x => x.IsDeleted != true) select o; /*-****WORKING FOR ORDER TABLE*****/
var orderDetails = from od in db.OrderDetails.Where(x => x.IsDeleted != true) select od;
//List of Employees
var requesitionerList = new List<string>();
//List of Suppliers
var supplierList = new List<string>();
//List of Job Numbers
var jobNumberList = new List<string>();
//List of Dates Requested
var dateRequestedList = new List<DateTime>();
//List of Dates Required
var dateRequiredList = new List<DateTime>();
//Query the ORDERS table columns
var requesitionerQry = from r in db.Orders.Where(x => x.IsDeleted != true) orderby r.Requesitioner select r.Requesitioner;
var supplierQry = from s in db.Orders.Where(x => x.IsDeleted != true) orderby s.Supplier select s.Supplier;
var jobNumberQry = from j in db.Orders.Where(x => x.IsDeleted != true) orderby j.JobNumber select j.JobNumber;
var dateRequestedQry = from DRqst in db.Orders.Where(x => x.IsDeleted != true) orderby DRqst.DateRequested select DRqst.DateRequested;
var dateRequiredQry = from DRqrd in db.Orders.Where(x => x.IsDeleted != true) orderby DRqrd.DateRequired select DRqrd.DateRequired;
//Searches through the columns filters out NULLS
var t = requesitionerQry.Distinct().ToList().Where(x => String.IsNullOrWhiteSpace(x) == false);
var u = supplierQry.Distinct().ToList().Where(y => String.IsNullOrWhiteSpace(y) == false);
var v = jobNumberQry.Distinct().ToList().Where(z => String.IsNullOrWhiteSpace(z) == false);
var dRT = dateRequestedQry.Distinct().ToList().Where(z1 => String.IsNullOrWhiteSpace(z1.ToString()) == false);
var dRD = dateRequiredQry.Distinct().ToList().Where(z2 => String.IsNullOrWhiteSpace(z2.ToString()) == false);
//Searches through the columns and only pulls out one of each unique string
requesitionerList.AddRange(t);
supplierList.AddRange(u);
jobNumberList.AddRange(v);
dateRequestedList.AddRange(dRT);
dateRequiredList.AddRange(dRD);
//I believe this Grabs the list items and arranges them into a viewable anonamous object
ViewBag.requesitionerDropDown = new SelectList(requesitionerList);
ViewBag.supplierDropDown = new SelectList(supplierList);
ViewBag.jobNumberDropDown = new SelectList(jobNumberList);
ViewBag.dateRequestedDropDown = new SelectList(dateRequestedList);
ViewBag.dateRequiredDropDown = new SelectList(dateRequiredList);
//This defines which columns the text in the search textbox should locate
if (!String.IsNullOrEmpty(searchString))
{
orders = orders.Where(a => a.JobNumber.Contains(searchString)||
//a.Description.Contains(searchString) || a.PartNumber.Contains(searchString) || a.AngstromPartNumber.Contains(searchString) ||
a.Supplier.Contains(searchString) || a.Reason.Contains(searchString) || a.Requesitioner.Contains(searchString) ||
a.DateRequested.ToString().Contains(searchString) || a.DateRequired.ToString().Contains(searchString) ||
a.ExpectedDate.ToString().Contains(searchString) || a.DateOrderPlaced.ToString().Contains(searchString) ||
a.PurchaseOrder.ToString().Contains(searchString));
}
if (!String.IsNullOrEmpty(searchString))
{
orders = orders.Where(x => x.OrderDetails.Any(i => i.Description.Contains(searchString)));
}
//Search the REQUESITIONER column
if (!String.IsNullOrEmpty(requesitionerDropDown))
{
orders = orders.Where(b => b.Requesitioner == requesitionerDropDown);
}
//Search the SUPPLIER column
if (!String.IsNullOrEmpty(supplierDropDown))
{
orders = orders.Where(c => c.Supplier == supplierDropDown);
}
//Search the JOBNUMBER column
if (!String.IsNullOrEmpty(jobNumberDropDown))
{
orders = orders.Where(d => d.JobNumber == jobNumberDropDown);
}
if (!String.IsNullOrEmpty(dateRequestedDropDown))
{
orders = orders.Where(d => d.DateRequested.ToShortDateString() == dateRequestedDropDown);
}
if (!String.IsNullOrEmpty(dateRequiredDropDown))
{
orders = orders.Where(d => d.DateRequired.ToShortDateString() == dateRequiredDropDown);
}
#endregion
//List<Order> OrderList = db.Orders.ToList();
var sortedOrders = orders.OrderBy(x => x.JobNumber);
return View(sortedOrders.ToPagedList(pageNumber, pageSize));
}
#endregion
Here are my Models:
public partial class Order
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Order()
{
this.OrderDetails = new HashSet<OrderDetail>();
}
public System.Guid OrderID { get; set; }
public Nullable<bool> IsDeleted { get; set; }
public string JobNumber { get; set; }
public string Supplier { get; set; }
public string Reason { get; set; }
public string Requesitioner { get; set; }
public System.DateTime DateRequested { get; set; }
public System.DateTime DateRequired { get; set; }
public Nullable<bool> Urgent { get; set; }
public System.DateTime ExpectedDate { get; set; }
public System.DateTime DateOrderPlaced { get; set; }
public string PurchaseOrder { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}
public partial class OrderDetail
{
public System.Guid OrderDetailID { get; set; }
public Nullable<bool> IsDeleted { get; set; }
public int Quantity { get; set; }
public string Description { get; set; }
public string PartNumber { get; set; }
public string Notes { get; set; }
public string Comments { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public string AngstromPartNumber { get; set; }
public string Manufacturer { get; set; }
public Nullable<int> BoneYard { get; set; }
public System.Guid OrderID { get; set; }
public Nullable<System.Guid> EmployeeID { get; set; }
public Nullable<System.Guid> SupplierID { get; set; }
public virtual Employee Employee { get; set; }
public virtual Order Order { get; set; }
public virtual Supplier Supplier { get; set; }
}
Entities
public class Employee
{
public long BusinessUnitID{ get; set; }
public long EmployeeID { get; set; }
public long InfoTypeID { get; set; }
public string EmployeeName { get; set; }
public List<ContactData> ContactDetails{ get; set; }
}
public class ContactData
{
public string ContactTypeName { get; set; }
public string ContactValue { get; set; }
}
Model
Public class EmployeeDetails
{
public long BusinessUnitID { get; set; }
public List<EmployeeData> EmployeeInfo { get; set;}
public List<ContactInfo> Contacts { get; set; }
}
public class EmployeeData
{
public long EmployeeID { get; set;}
public string EmployeeName { get; set;}
}
Public class ContactInfo
{
public string ContactName { get; set; }
public long ContactValue { get; set; }
}
Controller
public ActionResult Update(long BusinessUnitID=2)
{
if (Session[Constants.Session_IsAdmin] != null && Convert.ToBoolean(Session[Constants.Session_IsAdmin]))
{
EmployeeDetails employeeDetails = new EmployeeDetails();
List<Employee> employee = GetEmployeeById(Convert.ToInt64(BusinessUnitID));
List<EmployeeData> lstEmployeeData = new List<EmployeeData>();
List<ContactInfo> lstContactInfo = new List<OptionDetails>();
var ID = employee.Select(x => x.BusinessUnitID).ToList();
foreach(var item in employee.Where(x => x.BusinessUnitID == BusinessUnitID))
{
EmployeeData employeeData = new EmployeeData();
employeeData.EmployeeID = item.EmployeeID;
employeeData.EmployeeName = item.EmployeeName;
foreach (var local in employee.Where(q => q.EmployeeID == employeeData.EmployeeID))
{
//ContactInfo contactInfo = new ContactInfo();
//contactInfo.ContactName = local.ContactDetails.Select(p => p.ContactName).ToString();
//contactInfo.ContactValue = local.ContactDetails.Select(s => s.ContactValue).ToString();
}
lstEmployeeData.Add(employeeData);
}
return View(EmployeeDetails);
}
else
{
return RedirectToAction("Login");
}
}
Here I'm getting a list Employee in which i have below properties and a list ContactDetails which is a list containing atleast 3 elements for its properties. For eg 3 types of ContactTypeName and ContactValue as Home: 000000000, work: 9999999, mobile: 8888888. For a businessUnitid i got all employeeid for a perticular EmployeeID i want contact details but i'm unable to get or 3 contactvalue and contactname. In list Employee there is list ContactDetails in which there would be 3 or 5 contact numbers. I don't know how must i assign it to a list.
As employee can have multiple contact details, you need to add contact detail list property to EmployeeData class
Model classes :
Public class EmployeeDetails
{
public EmployeeDetails()
{
EmployeeInfo = new List<EmployeeData>();
}
public long BusinessUnitID { get; set; }
public List<EmployeeData> EmployeeInfo { get; set;}
}
public class EmployeeData
{
public EmployeeData()
{
Contacts = new List<ContactInfo>();
}
public long EmployeeID { get; set;}
public string EmployeeName { get; set;}
public List<ContactInfo> Contacts { get; set; }
}
Public class ContactInfo
{
public string ContactName { get; set; }
public long ContactValue { get; set; }
}
Then it's easy to pass the data of employees with multiple contacts
public ActionResult Update(long BusinessUnitID=2)
{
if (Session[Constants.Session_IsAdmin] != null && Convert.ToBoolean(Session[Constants.Session_IsAdmin]))
{
List<Employee> employees = GetEmployeeById(Convert.ToInt64(BusinessUnitID));
List<EmployeeData> lstEmployeeData = new List<EmployeeData>();
foreach(var item in employee.Where(x => x.BusinessUnitID == BusinessUnitID))
{
EmployeeData employeeData = new EmployeeData();
employeeData.EmployeeID = item.EmployeeID;
employeeData.EmployeeName = item.EmployeeName;
foreach (var contact in employee.ContactDetails)
{
ContactInfo contactInfo = new ContactInfo();
contactInfo.ContactName = contact.ContactName;
contactInfo.ContactValue = contact.ContactValue;
employeeData.Contacts.Add(contactInfo);
}
lstEmployeeData.Add(employeeData);
}
EmployeeDetails empDetails = new EmployeeDetails();
empDetails.EmployeeInfo = lstEmployeeData;
return View(empDetails);
}
else
{
return RedirectToAction("Login");
}
}
I have got problem with return data from my database. In my database are three tables: Customer, Activity and CustomerActivity. I want to return activities data for specific customer and with specific type activity. I wrote query but it doesn't work exactly as I wish. Here is my code and tables. Thank you for advices.
var activities = db.Join(db.CustomerActivities, a => a.ActivityID, ca =>ca.CustomerActivityID, (a, ca) => new { Activity = a, CustomerActivity = ca })
.Where(a => a.CustomerActivity.customer.CustomerID == id && a.Activity.TypeActivityID == typeActivity)
.Select(m => new ActivityMV()
{
ActivityID = m.Activity.ActivityID,
Name = m.Activity.Name,
DateOfActivity = m.Activity.DateOfActivity,
Desc = m.Activity.Desc
})
.ToList();
public class CustomerActivity
{
public int CustomerActivityID { get; set; }
public int CustomerID { get; set; }
public int ActivityID { get; set; }
public virtual Customer customer { get; set; }
public virtual Activity activity { get; set; }
}
public class Activity
{
public int ActivityID { get; set; }
public string Name { get; set; }
public string Desc { get; set; }
public string DateOfActivity { get; set; }
public string TypeActivityID { get; set; }
public virtual ICollection <CustomerActivity> customerActivities { get; set; }
}
Try
var activities = db.CustomerActivities
.Where(ca => ca.CustomerID == id && ca.Activity.TypeActivityID == typeActivity)
.Select(ca => new ActivityMV()
{
ActivityID = ca.ActivityID,
Name = ca.Activity.Name,
DateOfActivity = ca.Activity.DateOfActivity,
Desc = ca.Activity.Desc
})
.ToList();
Is there a way I can read Ad leads data from Lead_ID in asp.net? I see there are examples of PHP but there is no SDK for C#.Unforunately I have to use Asp.net and cannot use any other technologies
Any suggestions are highly appreciated
You can use facebook sdk c# and
var fb = new FacebookClient
{
AccessToken ="token"
};
var json = fb.Get("page_id or ad_id/leadgen_forms");
var forms = JsonConvert.DeserializeObject<FormsLeads>(json.ToString());
foreach (var form in forms.data)
{
var jsonre = fb.Get(form.id + "/leads");
var leads = JsonConvert.DeserializeObject<Leads>(jsonre.ToString());
while (leads.paging != null)
{
foreach (var lead in leads.data)
{
var leadnovo = new Models.Lead();
leadnovo.CamposExtras.Add(new CampoExtra { Nome = "idfacebook", Valor = lead.id });
leadnovo.DataCadastro = lead.created_time;
foreach (var t in lead.field_data)
{
if (t.name == "full_name")
{
leadnovo.Nome = t.values.FirstOrDefault();
}
else
if (t.name == "email")
{
leadnovo.Email = t.values.FirstOrDefault();
}
else
if (t.name == "phone_number")
{
leadnovo.Celular = t.values.FirstOrDefault();
}
else
{
leadnovo.CamposExtras.Add(new CampoExtra()
{
Nome = t.name,
Valor = t.values.FirstOrDefault()
});
}
}
if (db.Leads.FirstOrDefault(c => c.Email == leadnovo.Email) == null)
{
db.Leads.Add(leadnovo);
db.SaveChanges();
}
}
if (leads.paging != null)
{
jsonre = fb.Get(form.id + "/leads?after=" + leads.paging.cursors.after);
leads = JsonConvert.DeserializeObject<Leads>(jsonre.ToString());
}
}
}
}
Class for deserialize
public class Cursors
{
public string before { get; set; }
public string after { get; set; }
}
public class Field_Data
{
public string name { get; set; }
public string[] values { get; set; }
}
public class FormsLeads
{
public Formulario[] data { get; set; }
public Paging paging { get; set; }
}
public class Formulario
{
public string id { get; set; }
public string leadgen_export_csv_url { get; set; }
public string locale { get; set; }
public string name { get; set; }
public string status { get; set; }
}
public class Lead
{
public DateTime created_time { get; set; }
public string id { get; set; }
public Field_Data[] field_data { get; set; }
}
public class Leads
{
public Lead[] data { get; set; }
public Paging paging { get; set; }
}
public class Paging
{
public Cursors cursors { get; set; }
}