partial view in mvc core - asp.net-mvc

I would like to sum table column for view model is
public class ColumnTotal {
public int ID { get; set; }
public decimal ColumnOne { get; set; }
public decimal ColumnTwo { get; set; }
public decimal ColumnThree { get; set; }
}
My home controller of columntotal method looks like this
public IActionResult ColumnTotal()
{
var query = _context.REHPData.Include(r => r.BudgetYear).GroupBy(r => r.BudgetYearlyAllocation.ID).Select(s => new ColumnTotal
{
ID = s.Key,
ColumnOne = s.Sum(x => x.BudgetYearlyAllocation.AdminThaTeen),
ColumnTwo = s.Sum(x => x.BudgetYearlyAllocation.AdminThaTwo),
ColumnThree = s.Sum(x => x.BudgetYearlyAllocation.AdminThaFour)
}).ToList();
return View(query);
}
MY partial view _test.cshtml looks like this
#model RenewableEnergyProjcet.Models.CalculationViewModels.ColumnTotal
<tr>
<td> #Html.DisplayFor(m=>m.ColumnOne)</td>
<td> #Html.DisplayFor(m=>m.ColumnTwo)</td>
<td> #Html.DisplayFor(m=>m.ColumnThree)</td>
</tr>
my report.chtml looks like this
#{
ViewData["Title"] = "Budget Result Table ";
}
<h2>Budgets Result Table </h2>
<table class="table table-bordered table-condensed table-responsive table-hover">
<tr>
<td>Some Columns -----</td>
</tr>
#foreach (var item in Model)
{
<tr>
some data----
</tr>
}
<tr>
#await Html.PartialAsync("_test"); //how to call this partial _test.chtml
</tr>
</table>
please how to call partial _test.chtml from in method.

In Action that fill report.chtml call too the query that you use in ColumnTotal() action and send it to the view and in the view use RenderPartial() to call the view.
public IActionResult report()
{
ViewData["ColumnTotal"] = _context.REHPData.Include(r => r.BudgetYear).GroupBy(r => r.BudgetYearlyAllocation.ID).Select(s => new ColumnTotal
{
ID = s.Key,
ColumnOne = s.Sum(x => x.BudgetYearlyAllocation.AdminThaTeen),
ColumnTwo = s.Sum(x => x.BudgetYearlyAllocation.AdminThaTwo),
ColumnThree = s.Sum(x => x.BudgetYearlyAllocation.AdminThaFour)
}).ToList();
return View("report");
}
An in the view do something like this.
#Html.RenderPartial("_test",ViewData["ColumnTotal"])

Related

Send List Type to View from Controller

Entities:
public partial class Institution
{
public int? Id { get; set; }
public string? District { get; set; }
public string? InstitutionCode { get; set; }
public string? InstitutionName { get; set; }
public string? DemolitionStatus { get; set; }
public string? ReinforcementStatus { get; set; }
}
Controller:
public class HomeController : Controller
{
_context c;
public HomeController(_context c)
{
this.c = c;
}
public IActionResult Index()
{
var GetAll=c.Institutions.ToList();
return View(GetAll);
}
}
In View
#model List<GetAll>
#foreach (var item in Model)
{
#item.InstitutionName
}
Also it doesn't work:
The type or namespace name 'GetAll' could not be found
Try with #model SolutionName.Entities or Ienumarable or adding namespace #using FBMv3.Controllers
What is the wrong or missing?
Try with #model SolutionName.Entities or Ienumarable or adding
namespace #using FBMv3.Controllers
What is the wrong or missing?
Well, first of all, GetAllcannot be a reference for your Institution list.
assuming, you are using asp.net core application, in this scenario, here #model List<GetAll> should be the location of your Institution class. For instance if your Institution class located like below folder:
So you should write the code like this #model IEnumerable<DotNet6MVC.Models.Institution> instead of #model List<GetAll>
Complete sample for you:
Controller:
public IActionResult Index()
{
var instituteList = new List<Institution>()
{
new Institution(){ Id =101,District = "Dis-A", InstitutionCode = "IC-1",InstitutionName = "IN-AAA",DemolitionStatus="YES",ReinforcementStatus = "T"},
new Institution(){ Id =102,District = "Dis-B", InstitutionCode = "IC-2",InstitutionName = "IN-BBB",DemolitionStatus="NO",ReinforcementStatus = "F"},
new Institution(){ Id =103,District = "Dis-C", InstitutionCode = "IC-3",InstitutionName = "IN-CCC",DemolitionStatus="NO",ReinforcementStatus = "T"},
new Institution(){ Id =104,District = "Dis-D", InstitutionCode = "IC-4",InstitutionName = "IN-DDD",DemolitionStatus="NO",ReinforcementStatus = "T"},
new Institution(){ Id =105,District = "Dis-E", InstitutionCode = "IC-5",InstitutionName = "IN-EEE",DemolitionStatus="YES",ReinforcementStatus = "T"},
};
return View(instituteList);
}
Note: You could write your controller code as well. Like this:
var GetAll=c.Institutions.ToList();
return View(GetAll)
View:
#model IEnumerable<DotNet6MVC.Models.Institution>
#{
ViewData["Title"] = "Index";
}
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Id)
</th>
<th>
#Html.DisplayNameFor(model => model.District)
</th>
<th>
#Html.DisplayNameFor(model => model.InstitutionCode)
</th>
<th>
#Html.DisplayNameFor(model => model.InstitutionName)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.District)
</td>
<td>
#Html.DisplayFor(modelItem => item.InstitutionCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.InstitutionName)
</td>
<td>
<a asp-action="EditMember" class="btn btn-primary" asp-route-memberId="#item.Id">Details</a> | <a asp-action="EditMember" class="btn btn-warning" asp-route-memberId="#item.Id">Edit</a>
</td>
</tr>
}
</tbody>
</table>
Note: Be double confirm in your scenario, it would be #model IEnumerable<YourProjectName.YourClassFolder.Institution>. Because, your problem is here.
Output:
Note: If you still have any concern on this I would highly recommend you to check this official document.

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 get the value of 1st row "Name" from partial view when page first loads in parent view?

I want to get the value of 1st row Name from partial view when page first loads in parent view. Please suggest me the way.
Model
public class ClsA
{
public List<first> firsts{ get; set; }
public List<second> seconds{ get; set; }
}
public class first
{
public string Name { get; set; }
public string Address { get; set; }
}
public class second
{
public string Details{ get; set; }
public string Age{ get; set; }
}
Controller
public ActionResult ABC()
{
string name="abc";// currently I am passing value manually
SDetails sDetails=new SDetails();
var model = new ClsA();
model.firsts = sDetails.Rst();
model.seconds = sDetails.Rs(name); //I want to pass name value from 1st row of table
return View(model);
}
View
#model Aplication.Models.ABC.ClsA
#{ Html.RenderPartial("_Partial", Model.firsts); }
#{ Html.RenderPartial("_PartialB", Model.seconds);}
PartialA
#model IEnumerable<Aplication.Models.ABC.first>
<table>
<tr>
<th>#Html.DisplayNameFor(m => m.Name)</th>
<th>#Html.DisplayNameFor(m => m.Address)</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Address)
</td>
</tr>
}
</table>
_PartialB
#model IEnumerable<Aplication.Models.ABC.second>
<table>
<tr>
<th>#Html.DisplayNameFor(m => m.Details)</th>
<th>#Html.DisplayNameFor(m => m.Age)</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Details)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>
You can try below code in view if you want statically first row from first partial view Model.firsts().FirstOrDefault().Name

Saving an IEnumerable Model

I have a view that has 2 date pickers, one of which is a start date and the other of which is end date. I am able to get the user to select the start and end dates, redirect to a view that will have a list of Time worked where the user could change the date, enter time, and once they are done they should be able to click the save button and it should create a new instance of each time worked to the database. I got the view displaying with no problem, but when the form posts my enumerable model is null, the form collection only has one accessible item, and I am not sure why. Please take a look at the view I am creating below to get an idea of what I am doing and let me know if you are able to help me in any way.
#model IEnumerable<TimeCollection.Models.TimeWorked>
#{
ViewBag.Title = "Create TimeWorked Range";
}
<h2>Create TimeWorked Range</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.WorkDate)
</th>
<th>
#Html.DisplayNameFor(model => model.HoursWorked)
</th>
</tr>
#foreach (var item in Model) {
<tr>
#Html.HiddenFor(modelItem => item.EmployeeId)
<td>
#Html.EditorFor(modelItem => item.WorkDate)
</td>
<td>
#Html.EditorFor(modelItem => item.HoursWorked)
</td>
<td>
#Html.HiddenFor(modelItem => item.BeenSubmitted)
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Save" />
</p>
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TimeCollection.Models
{
public class TimeWorked
{
public int TimeWorkedId { get; set; }
public int EmployeeId { get; set; }
public DateTime WorkDate { get; set; }
public int HoursWorked { get; set; }
public bool BeenSubmitted { get; set; }
public static void CreateTimeWorked(TimeWorked timeWorkedToCreate)
{
string insertQuery = string.Format("insert into time_worked (employee_id, work_date, work_hours, been_submitted) values ('{0}', '{1}', '{2}', '{3}')", timeWorkedToCreate.EmployeeId, timeWorkedToCreate.WorkDate.ToString("yyyy/MM/dd"), timeWorkedToCreate.HoursWorked, (timeWorkedToCreate.BeenSubmitted == true ? "1" : "0"));
SpectrumData.Utility.ExecuteMySqlCommand(SpectrumData.Properties.Resources.SpectrumTSDatabaseConnectionString, insertQuery);
}
public static TimeWorked ReadTimeWorked(int timeWorkedId)
{
string selectQuery = string.Format("select * from time_worked where time_worked_id = '{0}'", timeWorkedId);
return ConvertDataRowIntoTimeWorked(SpectrumData.Utility.FillDataSet(SpectrumData.Properties.Resources.SpectrumTSDatabaseConnectionString, selectQuery).Tables[0].Rows[0]);
}
public static void UpdateTimeWorked(TimeWorked timeWorkedToUpdate)
{
string updateQuery = string.Format("update time_worked set work_date = '{0}', work_hours = '{1}', been_submitted = '{2}' where time_worked_id = '{2}'", timeWorkedToUpdate.WorkDate, timeWorkedToUpdate.HoursWorked, timeWorkedToUpdate.BeenSubmitted, timeWorkedToUpdate.TimeWorkedId);
SpectrumData.Utility.ExecuteMySqlCommand(SpectrumData.Properties.Resources.SpectrumTSDatabaseConnectionString, updateQuery);
}
public static void DeleteTimeWorked(int timeWorkedId)
{
string deleteQuery = string.Format("delete from time_worked where time_worked_id = '{0}'", timeWorkedId);
SpectrumData.Utility.ExecuteMySqlCommand(SpectrumData.Properties.Resources.SpectrumTSDatabaseConnectionString, deleteQuery);
}
private static TimeWorked ConvertDataRowIntoTimeWorked(System.Data.DataRow timeWorkedDataRow)
{
TimeWorked timeWorked = new TimeWorked();
timeWorked.BeenSubmitted = (timeWorkedDataRow["been_submitted"].ToString() == "1" ? true : false);
timeWorked.EmployeeId = int.Parse(timeWorkedDataRow["employee_id"].ToString());
timeWorked.HoursWorked = int.Parse(timeWorkedDataRow["work_hours"].ToString());
timeWorked.TimeWorkedId = int.Parse(timeWorkedDataRow["time_worked_id"].ToString());
timeWorked.WorkDate = DateTime.Parse(timeWorkedDataRow["work_date"].ToString());
return timeWorked;
}
}
}
public ActionResult CreateTimeWorkedRange(DateTime startDate, DateTime endDate)
{
List<Models.TimeWorked> listOfTimeWorked = new List<Models.TimeWorked>();
DateTime beginning = startDate;
DateTime ending = endDate;
while (beginning <= ending)
{
Models.TimeWorked dayWorked = new Models.TimeWorked()
{
EmployeeId = (Session["InventoryReviewUser"] as SpectrumData.SpectrumTS.InventoryReviewUser).EmployeeId,
WorkDate = beginning
};
if (listOfTimeWorked.Contains(dayWorked) == false)
{
listOfTimeWorked.Add(dayWorked);
}
beginning = beginning.AddDays(1);
}
return View(listOfTimeWorked);
}
[HttpPost]
public ActionResult CreateTimeWorkedRange(List<Models.TimeWorked> modelList)
{
foreach (Models.TimeWorked timeWorked in modelList)
{
Models.TimeWorked.CreateTimeWorked(timeWorked);
}
}
I don't know if there's a better way, but one way to do this is to bind your items using the index of the array as follows:
#for (int i = 0; i < Model.Count; ++i) {
<tr>
#Html.HiddenFor(modelItem => Model[i].EmployeeId)
<td>
#Html.TextBoxFor(modelItem => Model[i].WorkDate)
</td>
<td>
#Html.TextBoxFor(modelItem => Model[i].HoursWorked)
</td>
<td>
#Html.HiddenFor(modelItem => Model[i].BeenSubmitted)
</td>
</tr>
}
You'd need a different collection type for your model (IList<TimeWorked> should be fine) to be able to use indexers, but that shouldn't be a problem I'd imagine. When you post, the collection should fill properly.

Grouping in Entity Framework 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>

Resources