Grouping in Entity Framework MVC - asp.net-mvc

Hi all i've currently got a list of telephone numbers being output using:-
Controller:-
public ActionResult ViewSubRange(int id)
{
IEnumerable<Number> numbers = context.Numbers.Where(m => m.RangeID == id).ToList();
return View("SubRange", numbers);
}
View:-
#model IEnumerable<TelephoneNumberManagement.Models.Number>
<table>
<tr>
<th>
Number
</th>
<th>
Status
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.Number1</td>
<td>#item.Status.StatusName</td>
</tr>
}
</table>
This is fine, however i've noticed that we can have a lot of numbers being output. I was wondering if its possible to group the numbers, so for example by Customer. So what i want to achieve is something like:-
01132210000-01132210999 CUSTOMER A
01132211000-01132211009 CUSTOMER B
01132211010-01132211029 CUSTOMER C

You could define a new view model:
public class MyViewModel
{
public string StatusName { get; set; }
public string Numbers { get; set; }
}
and then group by customer name:
public ActionResult ViewSubRange(int id)
{
var numbers = context.Numbers
.Where(m => m.RangeID == id)
.GroupBy(x => x.Status.StatusName)
.Select(x => new MyViewModel
{
StatusName = x.Key,
// TODO: could change the format if you will or
// select the min and max or whatever you need
Numbers = string.Join("-", x.Select(n => n.Number1))
})
.ToList();
return View(numbers);
}
and finally in your view:
#model IEnumerable<MyViewModel>
<table>
<tr>
<th>Number</th>
<th>Status</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.Numbers</td>
<td>#item.StatusName</td>
</tr>
}
</table>

Related

ASP.NET Core - Creating View with select from database based on existing model

I have standards views generated with scaffolding my model from Main table.
Now instead of standard Details view which shows details of single record based on Main table I want to show list (like in Index view) of all rows where this id appears in another table (called Audit table).
So when user clicks Details in Index view of Main table (model) it should get list of records from Audit table where that id appears.
Main table model:
public partial class Main
{
public int id{ get; set; }
public int SocID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string User { get; set; }
}
Audit table model:
public partial class Audit
{
public int idAudit{ get; set; }
public int id{ get; set; }
public int SocID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string User { get; set; }
public string DateOfChange { get; set; }
public string Operation { get; set; }
}
So I've modified Details class in my Main model Controller to return all records from Audit table based on id from Main table in following way:
public IActionResult Details(int? id)
{
if (id == null)
{
return NotFound();
}
var Audit = (from c in _context.Audit
where c.id == id
select new Audit
{
SocID = c.SocID,
Name = c.Name,
Title = c.Title,
User = c.User,
DateOfChange = c.DateOfChange,
Operation = c.Operation
}).ToList();
if (Audit == null)
{
return NotFound();
}
return View(Audit);
}
And my View for Details class looks like this now:
#model IEnumerable<Audit>
#{
ViewData["Title"] = "Audit ....";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="table-responsive tableFixHead">
<table class="table table-striped table-hover mx-auto w-auto" id="nkz10table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.SocID)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.User)
</th>
<th>
#Html.DisplayNameFor(model => model.DateOfChange)
</th>
<th>
#Html.DisplayNameFor(model => model.Operation)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.SocID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.User)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateOfChange)
</td>
<td>
#Html.DisplayFor(modelItem => item.Operation)
</td>
</tr>
}
</tbody>
</table>
</div>
EDIT
In Index view I'm calling Details with:
#model IEnumerable<Audit>
....
<a asp-action="Details" asp-route-id="#item.id">Details</a>
when I click Details for specific id which has several records in Audit table I get
404 - page not found.
What am I doing wrong?
Problem was with definition of controller, here is what worked for me in the end:
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var audit= _context.audit
.Where(m => m.Nkz10Pk == id);
if (audit== null)
{
return NotFound();
}
return View(audit);
}

How to implement image dynamically in multiple views?

I am looking for a way to display the Image dynamically based on Placement_Position and Region into different View.
Placement view, where I display all the content from table.
There is no link between these Views.
I am confused, how to implement this scenario. Anyone please help me here.
In Employee view, I want to display the image Atop_1if the region is 1 and Atop_2 if the region is 2
public class ClsPlacement
{
public int Id { get; set; }
public string Placement_Position { get; set; }
public string Path { get; set; }
public int Region { get; set; }
}
Controller
public ActionResult Placement()
{
var model = context.Placement.ToList();
return View(model);
}
Placement View
<table>
<tr>
<th>
#Html.DisplayNameFor(m => m.Id)
</th>
<th>
#Html.DisplayNameFor(m => m.Placement_Position)
</th>
<th>
#Html.DisplayNameFor(m => m.Region)
</th>
<th>
#Html.DisplayNameFor(m => m.Path)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
#Html.DisplayFor(modelItem => item.Id)
<td>
#Html.DisplayFor(modelItem => item.Placement_Position)
</td>
<td>
#Html.DisplayFor(modelItem => item.Region)
</td>
<td>
#Html.Image(item.Path, "Image")
</td>
</tr>
}
</table>
you can use LINQ to write query for each controller and return IList :
so in Employee view :
public ActionResult Employee()
{
IList<ClsPlacement> plcList = new List<ClsPlacement>();
var query= from m in context.Placement
select m;
var plc= query.ToList();
foreach(var plcData in plc)
{
if(plcData.Placement_Position=="A_Top")
{
plcList.Add(new ClsPlacement()
{
Id= plcData.Id,
Placement_Position= plcData.Placement_Position,
Path = plcData.Path ,
Region= plcData.Region
});
}
}
return View(plcList);
}
then in your view you can write this:
#foreach (var item in Model)
{
<div class="col-md-5">
<img src="#Url.Content(String.Format("~/Content/Place/{0}{1}{2}", "Atop_",item.Region,".jpg"))" />
</div>
}
and same this for Customer view.

lambda expression Problems

My question is when I click actionlink,the view send specific ID to controller(ex. ProductID = 6), but my controller grab all data to me not specific ID data.
I think the problem is the lambda expression at controller, it will grab all data to me.
These are my Models:
public class ShoppingCart
{
public List<ShoppingCartItemModel> items = new List<ShoppingCartItemModel>();
public IEnumerable<ShoppingCartItemModel> Items
{
get { return items; }
}
}
public class ShoppingCartItemModel
{
public Product Product
{
get;
set;
}
public int Quantity { get; set; }
}
Controller :
[HttpGet]
public ActionResult EditFromCart(int ProductID)
{
ShoppingCart cart = GetCart();
cart.items.Where(r => r.Product.ProductID == ProductID)
.Select(r => new ShoppingCartItemModel
{
Product = r.Product,
Quantity = r.Quantity
});
return View(cart);
//return RedirectToAction("Index", "ShoppingCart");
}
private ShoppingCart GetCart()
{
ShoppingCart cart = (ShoppingCart)Session["Cart"];
//如果現有購物車中已經沒有任何內容
if (cart == null)
{
//產生新購物車物件
cart = new ShoppingCart();
//用session保存此購物車物件
Session["Cart"] = cart;
}
//如果現有購物車中已經有內容,就傳回 view 顯示
return cart;
}
View
#model ShoppingCart
#{
ViewBag.Title = "購物車內容";
}
<h2>Index</h2>
<table class="table">
<thead>
<tr>
<th>
Quantity
</th>
<th>
Item
</th>
<th class="text-right">
Price
</th>
<th class="text-right">
Subtotal
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.items)
{
<tr>
<td class="text-center">
#item.Quantity
</td>
<td class="text-center">
#item.Product.ProductName
</td>
<td class="text-center">
#item.Product.Price.ToString("c")
</td>
<td class="text-center">
#( (item.Quantity * item.Product.Price).ToString("c"))
</td>
<td>
#using (Html.BeginForm("RemoveFromCart", "ShoppingCart"))
{
#Html.Hidden("ProductId", item.Product.ProductID)
#*#Html.HiddenFor(x => x.ReturnUrl)*#
<input class="btn btn-warning" type="submit" value="Remove">
}
</td>
<td>
#using (Html.BeginForm("EditFromCart", "ShoppingCart", FormMethod.Get))
{
#Html.Hidden("ProductId", item.Product.ProductID)
<input class="btn btn-warning" type="submit" value="Edit">
}
</td>
</tr>
}
</tbody>
</table>
The key issue is that this code doesn't return the result of the LINQ queries, because you have not assigned a variable to the result:
cart.items.Where(r => r.Product.ProductID == ProductID)
.Select(r => new ShoppingCartItemModel
{
Product = r.Product,
Quantity = r.Quantity
});
I strongly suggest you create a viewmodel specifically to display the cart items.
public class CartItemsViewModel
{
public List<ShoppingCartItemModel> Items { get; set; }
}
[HttpGet]
public ActionResult EditFromCart(int ProductID)
{
ShoppingCart cart = GetCart();
var viewModel = new CartItemsViewModel();
viewModel.Items.AddRange(cart.items.Where(r => r.Product.ProductID == ProductID)
.Select(r => new ShoppingCartItemModel
{
Product = r.Product,
Quantity = r.Quantity
}));
return View(viewModel);
}
In my example I use the .AddRange() method to take the results of the LINQ calls against the cart items and store them in the viewmodel's Items property.
You must have to assign filtered value to cart like this.
cart.item = cart.items.Where(r => r.Product.ProductID == ProductID)
.Select(r => new ShoppingCartItemModel
{
Product = r.Product,
Quantity = r.Quantity
}).ToList();
use ToList(); or FirstOrDefault() as per your condition
You need to hold the return value from the linq query on cart.Items in a variable and pass that to the View method.
At the moment, the result of your query is being lost and the whole cart passed to the View method.

save all tr elements of a table with checkbox and send it to the controller , in MVC 4

I am new to MVC and now stuck in a serious problem. it is for me, very serious
I need to load a view with a list of meetings (which is loading fine) in html , I have added a checkbox to each row also. Now I need to save to the database ,only the checked values. But the controller is returning null when posting.. Really stuck and cant find a solution.
Pls see code below which I have done
Model
public class aMeet
{
public List<AcceptedRecords> amList { get; set; }
public static List<AcceptedRecords> GetamList()
{
DataSet ds = new DataSet();
List<AcceptedRecords> resultlist = new List<AcceptedRecords>();
using (cmd)
{
cmd.CommandText = #"SELECT Line_code,person_code,person_address from tbl where meeting_code =859489;
ds = cmd.ExecuteDataSet();
}
if (!Utils.IsDataSetEmpty(ds))
{
AcceptedRecords tpmApp;
foreach (DataRow row in ds.Tables[0].Rows)
{
tpmApp = new AcceptedRecords();
tpmApp = tpmApp.LoadRecords(row);
resultlist.Add(tpmApp);
}
}
return resultlist;
}
}
Model
public class AcceptedRecords
{
public int line_Code { get; set; }
public string person_Name { get; set; }
public string person_Address { get; set; }
public bool extra_checked { get; set; }
}
View
#model projct.Models.aRecs
#using (Html.BeginForm("AddRecord","Home"))
{
<table id="tbl" style ="width:100%" cellpadding="0" cellspacing="0" class="race-fields">
<thead>
<tr>
<th style="width:500px">line code</th>
<th style="width:100px">name</th>
<th style="width:500px">address</th>
<th style="width:500px">extra</th>
</tr>
</thead>
<tbody>
<tr>
#for (int i = 0; i < Model.amList.Count; i++)
{
<tr class="EvenRow">
<td>
#Html.DisplayFor(m => m.amList[i].line_Code) </td>
<td>#Html.DisplayFor(m => m.amList[i].person_name) </td>
<td>#Html.DisplayFor(m => m.amList[i].person_address) </td>
<td>
#Html.CheckBoxFor(m => m.amList[i].extra_checked) </td>
</tr>
}
</tr>
<tr>
<span>
<input type="submit" Value ="Save"/>
</span>
</tr>
</tbody>
</table>
}
Controller
[HttpPost]
public ActionResult AddRecord(List<aMeet> spm)
{
if (spm == null)
throw new ApplicationException("No Parameters passed to Create");
int? appID = 0;
return Json(appID);
}
}
--- It Is triggering to controller on Save but model [spm] is null.
How to get this corrected. Here I need to save to database the tr elements that are checked. Please request any help. I have tried a lot of things but the model is always null/
Many thanks
Assuming your aRecs class has a amList property which is a list of AcceptedRecords
public class aRecs
{
public List<AcceptedRecords> amList { set; get; }
}
Assuming line_code value is a unique (may be primary key) to get a record from your corresponding table, In your view, you need to keep the line_code property value of each item in amList in a hidden field so that when the form is submitted you will get this value and using that you can query the corresponding record and update it.
#model YourNamespaceHere.aRecs
#using (Html.BeginForm("AddRecord","Home"))
{
<table>
#for (int i = 0; i < Model.amList.Count; i++)
{
<tr class="EvenRow">
<td>
#Html.DisplayFor(m => m.amList[i].line_Code)
</td>
<td>#Html.DisplayFor(m => m.amList[i].person_Name) </td>
<td>
#Html.CheckBoxFor(m=>m.amList[i].extra_checked)
#Html.HiddenFor(m => m.amList[i].line_Code)
</td>
</tr>
}
</table>
<input type="submit"/>
}
And in your HttpPost action, your parameter will be a single object of aRecs
[HttpPost]
public ActionResult AddRecord(aRecs model)
{
foreach (var item in model.amList)
{
var lineCode = item.line_Code;
var isChecked = item.extra_checked;
/// get the record using lineCode and update the record.
}
return RedirectToAction("Index");
}

How to send the value of a dropdownlist along with the model?

I have a view that displays user names with groups they are part of.
In case i switch the group of a user, how can i send bot the user and the new group to the controller ?
View :
<table>
<tr>
<td>user ID</td>
<td>user group</td>
<td>Actions</td>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.UserName</td>
<td>#Html.DropDownList("grup", new SelectList(ViewBag.GroupList, "ID", "UserGroupName"), item.UserGroupName)</td>
<td>#Html.ActionLink("Save","EditUserGroup", UserInGroup)</td>
</tr>
}
</table>
Viewbag.GroupList is a list of {ID, GroupName}
Controller
public ActionResult EditUserGroup(UserInGroup userInGroup, string grup)
{
}
How can i send the value of the selected group and the user with all the details ?
Edit
I changed the Model to :
public class UserInGroupModel
{
public IList<UserInGroup> userInGroupList { get; set; }
public int GroupId { get; set; }
}
Controller
public ActionResult UserGroup()
{
IUserGroupService userGroupService = new UserGroupService();
ViewBag.GroupList = userGroupService.GetEntities();
var lista = userInGroupService.GetEntities();
UserInGroupModel userInGroupModel = new UserInGroupModel();
userInGroupModel.userInGroupList = lista;
return View(userInGroupModel);
}
View:
#using (Html.BeginForm("EditUserGroup", "Admin"))
{
<table>
<tr>
<td>user ID</td>
<td>user group</td>
<td>Actions</td>
</tr>
#foreach (var item in Model.userInGroupList)
{
<tr>
<td>#item.UserName</td>
<td>#Html.DropDownListFor(model => model.GroupId, new SelectList(ViewBag.GroupList, "ID", "UserGroupName"))</td>
<td><input type="submit" value="Save"/></td>
</tr>
}
</table>
}
I still cannot send the value of the UserInGroup. I can get the GroupId in the groupId parameter of the controller but, the UserInModel entity is not passed. Can you help me ?
use dropdownlistfor
#Html.DropDownListFor(x => x.grup, new SelectList(ViewBag.GroupList, "ID"...
add a variable to your model for the selected item (grup in this case)

Resources