How to call ArrayList from Controller to view in MVC4? - c#

i want to call Arraylist in view. I will explain my issue clearly.
My Controller Code
public ActionResult customerid()
{
List<Customer> n = (from c in db.Customers where c.IsDeleted == false select c).ToList();
var customertype = string.Empty;
for (var i = 0; i < n.Count; i++)
{
var objCustomerName = n[i].DisplayName;
var objCustomerID = n[i].CustomerID;
var objCusCreatedDate=n[i].CreatedDate;
var objNextDate = objCusCreatedDate.GetValueOrDefault().AddDays(120);
var salescount = (from sc in db.SalesOrders where sc.CustomerID==objCustomerID && sc.CreatedDate >= objCusCreatedDate && sc.CreatedDate<= objNextDate select sc.SalesOrderID).Count();
if (salescount <= 3&& salescount> 0)
{
customertype = "Exisiting Customer";
}
else if (salescount >= 3)
{
customertype = "Potential Customer";
}
else
{
customertype = "New Customer";
}
ArrayList obj = new ArrayList();
{
obj.Add(new string[] { objCustomerName, customertype, salescount.ToString()});
}
var details = obj;
}
return View();
}
My View Model
public class CustomerTypeViewModel
{
public System.Guid CustomerID { get; set; }
public string CustomerName { get; set; }
public DateTime CreatedDate { get; set; }
public string SalesCount { get; set; }
public string CustomerType { get; set; }
}
I want to call this array list in view. How I do that? That is i am generating one view based on controller code I need output same as like which is mentioned in the below image .
Wanted Output
Wanted Output
So i put all the fields (which i going to give as a column in View) in Array list. Now i want to call that Arraylist
obj.Add(new string[] { objCustomerName, customertype, salescount.ToString()});
in view . How I do that? I tried to explain my issue as per my level best. please understand my problem and tell me one solution. I am new to MVC so please help me to solve this problem.

In your controller:
List<CustomerTypeViewModel> obj = new List<CustomerTypeViewModel>();
obj.Add(new CustomerTypeViewModel(){
CustomerName = objCustomerName,
CustomerType = customertype,
SalesCount = salescount.ToString()
});
return View(obj);
In your view
#model IEnumerable<CustomerTypeViewModel>
and display values like this
#if (Model.Any()) {
foreach (var m in Model) {
#Html.DisplayFor(x => m.CustomerName)
#Html.DisplayFor(x => m.CustomerType)
}
}

Related

ASP.NET MVC5 Display data to user with specific selected data"Branch"

I have table with the next columns
Id,Name,A_Status,BranchName.
Would be that expendiently to achive, with the next method, i described bellow?
Column branch has 25 different names. So, i want to create a page, with 25 titles of branch(and for each, create his own cshtml page), where user can enter and view data of that specific branch, he has chosen. On each of those pages specific permissions, not all users can enter and view them.
I decided to achive it with the next code.
My controller
public ActionResult A_Branch ()
{
string query = "SELECT BranchName,Name, MAX(A_STATUS) AS A_Status "
+ "FROM Students "
+ "WHERE BranchName= '1_Branch' "
+ "GROUP BY BranchName,Name";
IEnumerable<EnrollmentStudentGroup> data = db.Database.SqlQuery<EnrollmentStudentGroup>(query);
return View(data.ToList());
}
And the next actionresult which i'm going to create 23 times more.
public ActionResult B_Branch ()
{
string query = "SELECT BranchName,Name, MAX(A_STATUS) AS A_Status "
+ "FROM Students "
+ "WHERE BranchName= '2_Branch' "
+ "GROUP BY BranchName,Name";
IEnumerable<EnrollmentStudentGroup> data = db.Database.SqlQuery<EnrollmentStudentGroup>(query);
return View(data.ToList());
}
My 2 models;
public class Student : BaseEntity
{
public int Id { get; set; }
public string BranchName { get; set; }
public string Name { get; set; }
public int A_Status { get; set; }
}
public class EnrollmentStudentGroup
{
public string BranchName { get; set; }
public string Name { get; set; }
public int A_Status { get; set; }
public IEnumerable<EnrollmentStudentGroup> StudentCollection { get; set; }
}
and my Model
public class Model
{
public List<Student> Students { get; set; }
public List<EnrollmentStudentGroup> EnrollmentStudentGroup { get; set; }
}
My newest controller ( after " .select " he is giving me errors )
[HttpGet]
public ActionResult TestNew(string branchname)
{
// check stuff like permissions
var db = new MovieContext();
var model = new Model();
var students = db.Student
.Where(x => x.BranchName == branchname)
.GroupBy(x => new { x.BranchName, x.Name, x.Currency, x.NoCart, x.NoAccount })
.Select(x => new
{
BranchName = x.FirstOrDefault().BranchName,
Name = x.FirstOrDefault().Name,
A_Status = x.Max(p => p.A_Status),
Currency = x.FirstOrDefault().Currency,
NoCart = x.FirstOrDefault().NoCart,
NoAccount = x.FirstOrDefault().NoAccount
}).ToList();
foreach (var item in students)
{
model.Students.Add(new Student
{
A_Status = item.A_Status,
BranchName = item.BranchName,
Name = item.Name,
NoAccount = item.NoAccount,
NoCart = item.NoCart,
Currency = item.Currency
});
}
return View(model);
}
Now that error, i updated my model and view(cshtml) by your answer.
My view(cshtml)
#model Tessa.Models.Model
#{
ViewBag.Title = "BranchView";
}
<h2>BranchView</h2>
#foreach (var item in Model.Students)
{
<p>#item.Name</p>
<p>#item.A_Status</p>
<p>#item.BranchName</p>
<p>#item.NoAccount</p>
<p>#item.NoCart</p>
<p>#item.Currency</p>
}
As in the comments wrote you dont have to do this for every single branch. Here is a solutions which may help you
Your Controller
public ActionResult Branch(string branchname)
{
var db = new ApplicationDbContext();
var model = new Model();
var students = db.Students
.Where(x => x.BranchName == branchname)
.GroupBy(x => new { x.BranchName, x.Name, x.Currency, x.NoCart, x.NoAccount })
.Select(x => new
{
BranchName = x.FirstOrDefault().BranchName,
Name = x.FirstOrDefault().Name,
A_Status = x.Max(p => p.A_Status),
Currency = x.FirstOrDefault().Currency,
NoCart = x.FirstOrDefault().NoCart,
NoAccount = x.FirstOrDefault().NoAccount
}).ToList();
foreach (var item in students)
{
model.Students.Add(new Student
{
A_Status = item.A_Status,
BranchName = item.BranchName,
Name = item.Name,
NoAccount = item.NoAccount,
NoCart = item.NoCart,
Currency = item.Currency
});
}
return View(model);
}
So you only pass the branchname to the controller. Her are severale diffrent ways to do this.
Its good practice to have a model to pass to a view.
public class Model
{
public List<Student> Students { get; set; }
//Some other propertys
public Model()
{
Students = new List<Student>();
}
}
And finialy you can write your view like this
#model TestApp.Models.Model
#{
ViewBag.Title = "BranchView";
}
<h2>BranchView</h2>
#foreach (var item in Model.Students)
{
<p>#item.Name</p>
<p>#item.A_Status</p>
<p>#item.Branchname</p>
<p>#item.NoAccount</p>
<p>#item.NoCart</p>
<p>#item.Currency</p>
}
In the foreach-loop you can do normal html stuff. This will done for every element in your list.
I hope this help you.

List of "View Models" returns Null

I have used List Instance of ViewModel to gather the data from the query and am trying to display in the View.However the object "CustomerVMlist" is return null with no results,customerlist is showing me 4 query results. and my view is completely empty.
public class CustomerVM
{
public int CustomerID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Mobileno { get; set; }
public Nullable<System.DateTime> OrderDate { get; set; }
public Nullable<decimal> OrderPrice { get; set; }
}
Index Function
public ActionResult Index()
{
List<CustomerVM> CustomerVMlist = new List<CustomerVM>(); // to hold list of Customer and order details
var customerlist =(from Cust in db.Customers
join Ord in db.Orders
on Cust.CustomerID equals Ord.CustomerID
select new
{
Cust.Name,
Cust.Mobileno,
Cust.Address,
Ord.OrderDate, Ord.OrderPrice
}).ToList();
foreach (var item in customerlist)
{
CustomerVM VMOBJ = new CustomerVM();
VMOBJ.Name= item.Name;
VMOBJ.Mobileno = item.Mobileno;
VMOBJ.Address = item.Address;
VMOBJ.OrderDate = item.OrderDate;
VMOBJ.OrderPrice = item.OrderPrice;
}
return View(CustomerVMlist);// returns null
}
You need to add items to the list
foreach (var item in customerlist) {
CustomerVM VMOBJ = new CustomerVM();
VMOBJ.Name= item.Name;
VMOBJ.Mobileno = item.Mobileno;
VMOBJ.Address = item.Address;
VMOBJ.OrderDate = item.OrderDate;
VMOBJ.OrderPrice = item.OrderPrice;
CustomerVMlist.Add(VMOBJ);
}
You have forgotten to add the objects you create in your list.
foreach (var item in customerlist)
{
CustomerVM VMOBJ = new CustomerVM();
VMOBJ.Name= item.Name;
VMOBJ.Mobileno = item.Mobileno;
VMOBJ.Address = item.Address;
VMOBJ.OrderDate = item.OrderDate;
VMOBJ.OrderPrice = item.OrderPrice;
// after having set all the values you add the newly created object to the list.
CustomerVMlist.Add(VMOBJ);
}
You could achieve the same thing with fewer lines of code like below:
public ActionResult Index()
{
var CustomerVMlist = (from Cust in db.Customers
join Ord in db.Orders
on Cust.CustomerID equals Ord.CustomerID
select new CustomerVM
{
Name = Cust.Name,
Mobileno = Cust.Mobileno,
Address = Cust.Address,
OrderDate = Ord.OrderDate,
OrderPrice = Ord.OrderPrice
}).ToList();
return View(CustomerVMlist)
}
As you see we can project our result to the desired type, CustomerVM, without having to loop through the result set (with the foreach), create one by one the desired obejcts and adding them to the list.

Add value to list

I am calling a API method that is returning some question and answer as List. I need show this list in View, not sure how to add value to the faq list. As I am sending this List that is part of Model to the View to show in on the screen.
Inside the foreach loop is where I have to add value of web api to the faq List.
This is my method which is returning the Model.
[HttpGet]
public async Task<ActionResult> ShowContact(int loanId)
{
HelpCenterViewModel helpCenterViewModel = new HelpCenterViewModel();
helpCenterViewModel.ContactInfo.loanId = loanId;
string json = string.Empty;
List<Faq> FaqObject = null;
var responseApi = await httpClient.GetAsync(string.Format("{0}/{1}",
CommonApiBaseUrlValue, "faqs"));
if (responseApi.IsSuccessStatusCode)
{
json = responseApi.Content.ReadAsStringAsync().Result;
FaqObject = new JavaScriptSerializer().Deserialize<List<Faq>>(json);
}
var response = new
{
success = FaqObject != null,
data = FaqObject
};
foreach (var faqitem in response.data)
{
//This is where I dont know how to add to faq list.
//helpCenterViewModel.Faq.Answer = faqitem.Answer;
//helpCenterViewModel.Faq.Category = faqitem.Category;
}
return View(helpCenterViewModel);
}
This is the Model that I am retunign it to view:
public class HelpCenterViewModel
{
public List<Faq> Faq { get; set; }
public ContactUsInfo ContactInfo { get; set; }
public HelpCenterViewModel()
{
this.Faq = new List<Faq>();
this.ContactInfo = new ContactUsInfo();
}
}
and this is the faq class:
public class Faq
{
public int Id { get; set; }
public string Category { get; set; }
public string Question { get; set; }
public string Answer { get; set; }
}
and this is my view:
#model IEnum erable<Carfinance.Loans.Web.ViewModels.HelpCenterViewModel>
#foreach (var item in Model)
{
<li>#Html.DisplayFor(faq => item.Faq)</li>
}
But It gave me this error.
The 'DelegatingHandler' list is invalid because the property 'InnerHandler' of 'CorsMessageHandler' is not null.
Parameter name: handlers
You need to create a new object for each of your items and add them to your list. This can be done in various ways, depending on how verbose you want your implementation to be:
foreach (var faqitem in response.data)
{
var faq = new Faq();
faq.Answer = faqitem.Answer;
faq.Category = faqitem.Category;
helpCenterViewModel.Faq.Add(faq);
}
OR
foreach (var faqitem in response.data)
helpCenterViewModel.Faq.Add(new Faq()
{
Answer = faqitem.Answer;
Category = faqitem.Category;
});
OR
helpCenterViewModel.Faq = response.data.Select(x => new Faq {
Answer = x.Answer,
Category = x.Category
}).ToList();
Cleaned up the code some, but you already have a List<Faq>, so just assign it to your model.
[HttpGet]
public async Task<ActionResult> ShowContact(int loanId)
{
string json = string.Empty;
List<Faq> FaqObject = null; // Should probably be new List<Faq>
var responseApi = await httpClient.GetAsync(string.Format("{0}/{1}", CommonApiBaseUrlValue, "faqs"));
if (responseApi.IsSuccessStatusCode)
{
json = responseApi.Content.ReadAsStringAsync().Result;
FaqObject = new JavaScriptSerializer().Deserialize<List<Faq>>(json);
}
var response = new
{
success = FaqObject != null,
data = FaqObject
};
return View(new HelpCenterViewModel
{
ContactInfo=new ContactInfo {loanId},
Faq=FaqObject
});
}
Not sure what you were doing with the response variable, so I just left it there, but it appears to do nothing useful and could be removed as well. Then you'd have this:
[HttpGet]
public async Task<ActionResult> ShowContact(int loanId)
{
var responseApi = await httpClient.GetAsync(string.Format("{0}/{1}", CommonApiBaseUrlValue, "faqs"));
if (responseApi.IsSuccessStatusCode)
{
return View(new HelpCenterViewModel
{
ContactInfo=new ContactInfo {loanId},
Faq=new JavaScriptSerializer().Deserialize<List<Faq>>(
responseApi.Content.ReadAsStringAsync().Result)
});
}
return View(new HelpCenterViewModel
{
ContactInfo=new ContactInfo {loanId},
Faq=new List<Faq>()
});
}
well, the Faq property on HelpCenterViewModel is really a List<Faq> (kind of misleading naming you have there), so use the Add method:
foreach (var faqitem in response.data)
{
var faq = new Faq();
faq.Answer = faqitem.Answer;
faq.Category = faqitem.Category;
helpCenterViewModel.Faq.Add(faq);
//^ this Faq is a List
}
You should pluralize your List<Faq>'s name to Faqs to prevent confusing yourself.

Get all Area, Controller and Action as a tree

I need to get all areas that has been registered as list and all of their controllers as a sub list and the same thing for actions. something like this:
AdminArea
HomeController
Index
Add
...
OtherController
...
AnotherArea
HomeController
Index
...
...
I have checked the answer of this question, and this one, but they are not what i'm looking for.
The first one return all the routes that has been registered and the second one return all controllers at once.
Update
Ok, with the below code i can get all the areas and with the answer of the second question i can get all the controllers, but i can't figure it out each controller belong to what area.
var areaNames = RouteTable.Routes.OfType<Route>()
.Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area"))
.Select(r => r.DataTokens["area"]).ToList()
.Distinct().ToList();
So here is what i came up with, it's exactly what i wanted.
I hope it will be helpful.
public virtual ActionResult Index()
{
var list = GetSubClasses<Controller>();
// Get all controllers with their actions
var getAllcontrollers = (from item in list
let name = item.Name
where !item.Name.StartsWith("T4MVC_") // I'm using T4MVC
select new MyController()
{
Name = name.Replace("Controller", ""), Namespace = item.Namespace, MyActions = GetListOfAction(item)
}).ToList();
// Now we will get all areas that has been registered in route collection
var getAllAreas = RouteTable.Routes.OfType<Route>()
.Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area"))
.Select(
r =>
new MyArea
{
Name = r.DataTokens["area"].ToString(),
Namespace = r.DataTokens["Namespaces"] as IList<string>,
}).ToList()
.Distinct().ToList();
// Add a new area for default controllers
getAllAreas.Insert(0, new MyArea()
{
Name = "Main",
Namespace = new List<string>()
{
typeof (Web.Controllers.HomeController).Namespace
}
});
foreach (var area in getAllAreas)
{
var temp = new List<MyController>();
foreach (var item in area.Namespace)
{
temp.AddRange(getAllcontrollers.Where(x => x.Namespace == item).ToList());
}
area.MyControllers = temp;
}
return View(getAllAreas);
}
private static List<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(
type => type.IsSubclassOf(typeof(T))).ToList();
}
private IEnumerable<MyAction> GetListOfAction(Type controller)
{
var navItems = new List<MyAction>();
// Get a descriptor of this controller
ReflectedControllerDescriptor controllerDesc = new ReflectedControllerDescriptor(controller);
// Look at each action in the controller
foreach (ActionDescriptor action in controllerDesc.GetCanonicalActions())
{
bool validAction = true;
bool isHttpPost = false;
// Get any attributes (filters) on the action
object[] attributes = action.GetCustomAttributes(false);
// Look at each attribute
foreach (object filter in attributes)
{
// Can we navigate to the action?
if (filter is ChildActionOnlyAttribute)
{
validAction = false;
break;
}
if (filter is HttpPostAttribute)
{
isHttpPost = true;
}
}
// Add the action to the list if it's "valid"
if (validAction)
navItems.Add(new MyAction()
{
Name = action.ActionName,
IsHttpPost = isHttpPost
});
}
return navItems;
}
public class MyAction
{
public string Name { get; set; }
public bool IsHttpPost { get; set; }
}
public class MyController
{
public string Name { get; set; }
public string Namespace { get; set; }
public IEnumerable<MyAction> MyActions { get; set; }
}
public class MyArea
{
public string Name { get; set; }
public IEnumerable<string> Namespace { get; set; }
public IEnumerable<MyController> MyControllers { get; set; }
}
For getting actions, i used this answer.
If you have any better ways, please let me know.

Binding DropDownList in Mvc and Get Selected Value

my Model is
public class ChildMenu
{
public string Name { get; set; }
public string Comments { get; set; }
public List<UlrikenModel.ulriken_tblChildMenu> FormDetails { get; set; }
public long pkChildMenuID { get; set; }
public long fkSubMenuID { get; set; }
[Required(ErrorMessage = "Requird")]
public string ChildManuName { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string Events { get; set; }
public IList<SelectListItem> Drp_Submenu { get; set; }
}
My Controller action is :
public ActionResult FillDeptName()
{
UlrikenEntities db1 = new UlrikenModel.UlrikenEntities();
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "-Please select-", Value = "Selects
items" });
var cat = (from c in db1.ulriken_tblSubMenu where c.fkMainMenuID == 1 &&
c.Status == true select new { c.pkSubMenuID,c.SubManuName }).ToArray();
for (int i = 0; i < cat.Length; i++)
{
list.Add(new SelectListItem
{
Text = cat[i].SubManuName,
Value = cat[i].pkSubMenuID.ToString(),
Selected = (cat[i].pkSubMenuID == 1)
});
}
ViewBag.list = list;
return View("ChildMenuOfSubMenu", ViewBag.list);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult ChildMenuOfSubMenu(ChildMenu obj)
{
UlrikenEntities db = new UlrikenEntities();
ulriken_tblChildMenu objchild = new ulriken_tblChildMenu();
objchild.fkSubMenuID = obj.fkSubMenuID;
objchild.ChildMenuName = obj.ChildManuName;
objchild.cPageBody = obj.Name;
db.ulriken_tblChildMenu.Add(objchild);
db.SaveChanges();
return View("ChildMenuOfSubMenu");
}
and view is
#Html.DropDownListFor(m=>m.fkSubMenuID,
(IEnumerable<SelectListItem>)ViewBag.list,"Select" ,new { id = "ddlSubMenu" })
At start dropdown bind successfully but after saving data to database show an exception in
as "There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key
'fkSubMenuID'"
AnyBody guide me where am i doing wrong.
Move that code to the helper class:
public class ControllerHelper
{
public List<SelectListItem> FetchListItems()
{
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
var cat = (from c in db1.ulriken_tblSubMenu where c.fkMainMenuID == 1 &&
c.Status == true select new { c.pkSubMenuID,c.SubManuName }).ToArray();
for (int i = 0; i < cat.Length; i++)
{
list.Add(new SelectListItem
{
Text = cat[i].SubManuName,
Value = cat[i].pkSubMenuID.ToString(),
Selected = (cat[i].pkSubMenuID == 1)
});
}
return list;
}
}
And then your controller should looks like:
public ActionResult FillDeptName()
{
UlrikenEntities db1 = new UlrikenModel.UlrikenEntities();
ViewBag.list = new ControllerHelper().FetchListItems();
return View("ChildMenuOfSubMenu", ViewBag.list);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult ChildMenuOfSubMenu(ChildMenu obj)
{
UlrikenEntities db = new UlrikenEntities();
ulriken_tblChildMenu objchild = new ulriken_tblChildMenu();
objchild.fkSubMenuID = obj.fkSubMenuID;
objchild.ChildMenuName = obj.ChildManuName;
objchild.cPageBody = obj.Name;
db.ulriken_tblChildMenu.Add(objchild);
db.SaveChanges();
ViewBag.list = new ControllerHelper().FetchListItems();
return View("ChildMenuOfSubMenu");
}
Of course:
new ControllerHelper().FetchListItems();
should be a field in the controller class, for example:
private ControllerHelper controlerHelper;
You can use Interface instead of concerete implementation, if you use DI.
Regards

Categories