Displaying Data from different tables in View - c#

Just wanted to ask if there's something I missed here.
I have two tables that I joined together in my controller
using .NET MVC btw
anyway, here's my controller:
namespace Review.Controllers
{
public class ReviewController : Controller
{
ReviewContext db = new ReviewContext();
ReviewItemsContext db2 = new ReviewItemsContext();
MainDataModel db3 = new MainDataModel();
List<UAR_Review> uar_review = new List<UAR_Review>();
List<UAR_ReviewItems> uar_reviewitems = new List<UAR_ReviewItems>();
public ActionResult Index(int? page) {
ViewBag.AccList = (from r in db2.UAR_ReviewItems
select r.Account).Distinct();
/*var entities = from s in db2.UAR_ReviewItems
orderby s.Account
select s;*/
var entities = from s in uar_review
join st in uar_reviewitems on s.ID equals st.ReviewID into st2
from st in st2.DefaultIfEmpty()
select new MainDataModel { UAR_Review = s, UAR_ReviewItems = st };
int pageSize = 15;
int pageNumber = (page ?? 1);
return View(entities.ToPagedList(pageNumber, pageSize));
}
}
}
and here's my view:
#model PagedList.IPagedList<Review.Models.MainDataModel>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("Index", "Review", FormMethod.Get))
{
<h2>Index</h2>
#section NavBar{
<h3>Period: 2 of 2018</h3>
#Html.DropDownList("userAccount", new SelectList(ViewBag.AccList), "Select Account to Filter")
<input type="submit" value="Search" />
}
#section MiddleSection{
<table class="table">
<tr>
<th>
<span class="arrow-link contrast-large light-blue">#Html.DisplayName("Name")</span>
</th>
<th>
<span class="arrow-link contrast-large light-blue">#Html.DisplayName("Role")</span>
</th>
<th>
<span class="arrow-link contrast-large light-blue">#Html.DisplayName("Action")</span>
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
<span class="font-gotham-narrow">#item.UAR_Review.DisplayName</span>
</td>
<td>
<span class="font-gotham-narrow">#item.UAR_ReviewItems.Role</span>
</td>
<td>
#Html.HiddenFor(modelItem => item.UAR_ReviewItems.Response)
<span class="font-gotham-narrow">
#Html.RadioButton("Response", "Retain")#Html.Label("Retain") 
</span>
<span class="font-gotham-narrow">
#Html.RadioButton("Response", "Remove")#Html.Label("Remove")
</span>
</td>
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
}
}
}
The problem is, when I run it there is nothing being displayed in the Site.here's the page.
I just wanted to ask if there's anything I missed.
Also, please disregard the dropdownlist on the left side, I've been planning to use it to sort the shown elements in the page by AccountType(This is stored in my UAR_ReviewItems table). For now, I'm just trying to figure out what's wrong here and why there are no elements being displayed.

Your screen grab does say the PageCount is 0.
Your Model in empty. Check your queries.

Related

How to get paging buttons to function

Hi I'm currently working on a project that needs paging numbers to navigate through products. I am currently using ReflectionIT.Paging.MVC.
My problem is that the paging buttons are showing however, when clicked it doesn't change pages. I've followed pretty much all tutorials and none of them has gotten the paging buttons to work.
Controller Index Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using MVCManukauTech.Models.DB;
using MVCManukauTech.ViewModels;
using ReflectionIT.Mvc.Paging;
using Pagination;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace MVCManukauTech.Controllers
{
public class CatalogController : Controller
{
private readonly F191_Grace_ProjectContext _context;
public CatalogController(F191_Grace_ProjectContext context)
{
_context = context;
}
public async Task<IActionResult> Index(int page = 1 )
{
//140903 JPC add CategoryName to SELECT list of fields
string SQL = "SELECT ProductId, Product.CategoryId AS CategoryId, Name, ImageFileName, UnitCost"
+ ", SUBSTRING(Description, 1, 100) + '...' AS Description, CategoryName "
+ "FROM Product INNER JOIN Category ON Product.CategoryId = Category.CategoryId ";
string categoryName = Request.Query["CategoryName"];
if (categoryName != null)
{
//140903 JPC security check - if ProductId is dodgy then return bad request and log the fact
// of a possible hacker attack. Excessive length or containing possible control characters
// are cause for concern! TODO move this into a separate reusable code method with more sophistication.
if (categoryName.Length > 20 || categoryName.IndexOf("'") > -1 || categoryName.IndexOf("#") > -1)
{
//TODO Code to log this event and send alert email to admin
return BadRequest(); // Http status code 400
}
//140903 JPC Passed the above test so extend SQL
//150807 JPC Security improvement #p0
SQL += " WHERE CategoryName = #p0";
//SQL += " WHERE CategoryName = '{0}'";
//SQL = String.Format(SQL, CategoryName);
//Send extra info to the view that this is the selected CategoryName
ViewBag.CategoryName = categoryName;
}
//150807 JPC Security improvement implementation of #p0
var products = _context.CatalogViewModel.FromSql(SQL, categoryName).AsNoTracking().OrderBy(s=>s.Name);
var model = await PagingList.CreateAsync(products, 6, page);
return View(model);
View Index Code:
#model ReflectionIT.Mvc.Paging.PagingList <MVCManukauTech.ViewModels.CatalogViewModel>
#using ReflectionIT.Mvc.Paging
#addTagHelper*,ReflectionIT.Mvc.Paging
#{
//Are we showing all the products or only one category?
if (ViewBag.CategoryName == null)
{
ViewBag.Title = "Catalog";
}
else
{
ViewBag.Title = "Catalog - " + ViewBag.CategoryName;
}
}
<link href="~/css/StyleSheet.css" rel="stylesheet" />
<div class="bg">
<h2>#ViewBag.Title</h2>
<nav aria-label="Product Paging">
#await this.Component.InvokeAsync("Pager", new { pagingList = this.Model });
</nav>
<div class="text-center">
<button type="button" class="btn btn-lg">All</button>
<button type="button" class="btn btn-lg">Transports</button>
<button type="button" class="btn btn-lg">Gadgets</button>
<button type="button" class="btn btn-lg">Furnitures</button>
<button type="button" class="btn btn-lg">Kitchen</button>
<button type="button" class="btn btn-lg">Entertainment</button>
<button type="button" class="btn btn-lg">Bathroom</button>
<button type="button" class="btn btn-lg"> Technology</button>
</div>
<table class="table" style="background-color:snow">
<tr>
<th>
Name
</th>
<th>
Image
</th>
<th>
Unit Cost
</th>
<th>
Description
</th>
<th>
Category
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr class="d-block">
<td>
#item.Name
</td>
<td>
<img src="~/Images/Product_Images/#item.ImageFileName" style="width:100px" />
</td>
<td style="text-align: right">
#item.UnitCost
</td>
<td>
#item.Description
</td>
<td>
#item.CategoryName
</td>
<td>
<button>Add to Cart</button>
</td>
<td>
<button>Details</button>
</td>
</tr>
<tr></tr>
}
</table>
<nav aria-label="Product Paging">
<vc:pager paging-list=#Model />;
</nav>
For this issue, it is caused by that page is the reserved routing names.
I have submit a pull request, and check change page to pageindex #24.
You could get this pull request and reference it in your project before the author have merged it.
Note, change the page to pageIndex in your Index action like
public async Task<IActionResult> Index(int pageIndex = 1)
{
var qry = _context.Products.AsNoTracking().OrderBy(u => u.Id);
var model = await PagingList.CreateAsync(qry, 6, pageIndex);
return View(model);
}

C# MVC foreach loop in view with model and viewbag

Controller:
public ActionResult SelectPlaats()
{
var one = repository.GetAllReserveringen.Where(x => x.StartDatum >= x.StartDatum
&& x.StartDatum <= x.EindDatum).Select(p => p.Plaats);
var two = repository.GetAllPlekken.Select(p => p.Plaatsnummer);
ViewBag.vrijeplekken = two.Except(one).ToList();
return View(repository.GetAllPlekken);
}
View:
#using Camping.Domain.Entities
#model IEnumerable<Plek>
#{
ViewBag.Title = "Beschikbare campingplekken";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="panel panel-default">
<div class="panel-heading">
<h3>Overzicht van alle klanten</h3>
</div>
<div class="panel-body">
<table class="table table-striped table-condensed table-bordered">
<tr>
<th>Plaatsnummer</th>
<th>Veldnaam</th>
<th>Type</th>
<th>Vierkante meter</th>
<th>Amp</th>
<th>Wifi</th>
<th>Water</th>
<th>Riool</th>
<th>CAI</th>
<th>PPN</th>
<th>Seizoenplek</th>
<th class="text-center">Reserveren</th>
</tr>
#foreach (var item in Model.Where(x => x.Plaatsnummer == ViewBag.vrijeplekken))
{
<tr>
<td>#item.Plaatsnummer</td>
<td>#item.Veldnaam</td>
<td>#item.Type</td>
<td>#item.Vierkantemeter</td>
<td>#item.Amp</td>
<td>#item.Wifi</td>
<td>#item.Water</td>
<td>#item.Riool</td>
<td>#item.CAI</td>
<td>#item.PPN</td>
<td>#item.Seizoenplek</td>
<td class="text-center">
#using (Html.BeginForm("SelectPlek", "Reservering"))
{
#Html.Hidden("Id", item.Plaatsnummer)
<input type="submit"
class="btn btn-default btn-xs"
value="Reserveren" />
}
</td>
</tr>
}
</table>
</div>
</div>
So we have the Model with all the campingsides + details my camping application has. But I only want to display in this view the free campingspots.
I extracted all the free campingsides from my database and put them in my Viewbag.vrijeplekken which holds a list of the sidenumbers (Plaatsnummer).
I can't figure out how to get a table with only the free campingsidenumbers but with the details all the campingsides have.
I hope anyone can help me out. Thanks in advance!
Your View should only concern itself with presenting the data it receives in the (View)model.
It is up to the controller to select which data to display.
As Derek suggests:
public Actionresult SelectPlaats()
{
var one = repository.GetAllReserveringen.Where(x => x.StartDatum >= x.StartDatum && x.StartDatum <= x.EindDatum).Select(p => p.Plaats).ToList();
return View(repository.GetAllPlekken.Where(p => !one.Contains(p.plaatsnummer)).ToList());
}
or
public Actionresult SelectPlaats()
{
var one = repository.GetAllReserveringen.Where(x => x.StartDatum >= x.StartDatum && x.StartDatum <= x.EindDatum);
return View(repository.GetAllPlekken.Except(one).ToList());
}
And in your View:
#foreach (var item in Model)
{
....

Only one 'model' statement is allowed in a file (Pagination)

So my Index view renders the view called StudentWellnessReviews retrieves reviews from the dbo.Review Table. Everything was working until I tried to setup pagination for the StudentWellnessReviews view in the ReviewsController. The error was:
Only one 'model' statement is allowed in a file.
ReviewsController
public class ReviewsController : Controller
{
private SizaData_1Entities db = new SizaData_1Entities();
// GET: Reviews
public ActionResult Index()
{
return View();
}
//Student Wellness Reviews
public ActionResult StudentWellnessReviews(int page = 1, int pageSize = 4)
{
using (var context = new SizaData_1Entities())
{
List<Review> listReviews = context.Reviews.SqlQuery("select * from dbo.Review where WellnessService='Student Wellness Service'").ToList();
PagedList<Review> userreview = new PagedList<Review>(listReviews, page, pageSize);
return View(userreview);
}
}
StudentWellnessReviews View:
#model IEnumerable<Siza.Models.Review>
#{
ViewBag.Title = "Index";
Layout = "";
}
#model PagedList.IPagedList<Siza.Models.Review>
#using PagedList.Mvc;
<table class="table text-center width:50%">
#foreach (var item in Model)
{
<tr>
<td>
<h5>Username</h5>
</td>
<td>
<p>
<div align="left">#Html.DisplayFor(modelItem => item.Username)</div>
</p>
</td>
</tr>
<tr>
<td>
<h5>Wellness Service</h5>
</td>
<td>
<p>
<div align="left">#Html.DisplayFor(modelItem => item.WellnessService)</div>
</p>
</td>
</tr>
<tr>
<td>
<h5>Rating</h5>
</td>
<td>
<p>
<div align="left">#Html.DisplayFor(modelItem => item.Rating)</div>
</p>
</td>
</tr>
<tr>
<td>
<h5>Feedback</h5>
</td>
<td>
<p>
<div align="left"> #Html.TextAreaFor(modelItem => item.Feedback, new {#readonly = true})</div>
</p>
</td>
</tr>
<tr>
<td>
<h5>Date Created</h5>
</td>
<td>
<p>
<div align="left"> #Html.DisplayFor(modelItem => item.Date)</div>
</p>
</td>
</tr>
<tr><td colspan="2"><hr class="active"/></td></tr>
}
#Html.PagedListPager(Model, Page => Url.Action("StudentWellnessReviews",
new { Page, pageSize = Model.PageSize} ))
Showing #Model.FirstItemOnPage to #Model.LastItemOnPage of #Model.TotalItemCount Reviews
</table>
Part of Index view
#using Siza.Controllers
#{
ViewBag.Title = "Index";
}
#{Html.RenderAction("StudentWellnessReviews", "Reviews");}
Assistance would be greatly appreciated.
The problem is you cannot define model for your View multiple times, right n ow you are saying that your view is strongly typed with both IEnumerable<Siza.Models.Review> and PagedList.IPagedList<Siza.Models.Review> which cannot be, so what i see is you just need PagedList.IPagedList<Siza.Models.Review> so remove the top line where you are setting model to IEnumerable<Siza.Models.Review> to be like:
#model PagedList.IPagedList<Siza.Models.Review>
#using PagedList.Mvc;
#{
ViewBag.Title = "Index";
Layout = "";
}
.................
Your rest view

Ajax.Beginform updatetarget and partial view

I've looked around, but can't find anything solving my problem with this (common?) issue.
My problem is that the whole site is refreshed instead of just the div tag. It have worked once, but after an update, not anymore...
AddMember.cshtml
#using DBSUSite.ViewModels
#model CommitteeAddMemberModel
<script src='#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")' type="text/javascript"></script>
<h1>
Tilføj medlem</h1>
<p>
Her kan du søge efter brugere og tilføje dem til bestyrelsen eller udvalget.</p>
#using (Ajax.BeginForm("SearchMembers", new AjaxOptions { UpdateTargetId = "searchUsersList", HttpMethod = "POST" }))
{
#Html.HiddenFor(model => model.CommitteeId)
<label for="str">
Søg efter:
</label>
<input id="str" name="str" value="" />
<input type="submit" value="Søg" />
}
<div id="searchUsersList">
#{ Html.RenderPartial("_SearchUserPartial", Model); }
</div>
Action
[Authorize]
[HttpPost]
public ActionResult SearchMembers(int committeeId, string str)
{
//TODO: Put into User model!
var db = new DBEntities();
// Removed lots of code.
var model = new CommitteeAddMemberModel { CommitteeId = committeeId, Users = users.Values.AsEnumerable() };
return PartialView("_SearchUserPartial", model);
}
Partial View
#using DBSUSite.Models
#using DBSUSite.ViewModels
#model CommitteeAddMemberModel
<table>
<thead>
<tr>
<th>
Navn
</th>
<th>Tilføj</th>
</tr>
</thead>
<tbody>
#foreach (User user in Model.Users)
{
<tr>
<td>
#Html.DisplayFor(q => user.FirstName) #Html.DisplayFor(q => user.Surname)
</td>
<td>
#Html.ActionLink("Tilføj", "SaveMember", "Committee", new { committeeId = Model.CommitteeId, userId = user.UserID }, null)
</td>
</tr>
}
</tbody>
</table>
Thanks in advance!
You need to make sure that you included all these libraries:
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

Navigating back to search results having clicked on item detail MVC 3 / C#

I am currently writing a simple MVC 3 application that displays a list of items and allows the user to filter the items (on the same page). The user can then click on an item and will be redirected to a details page.
The problem I have is that when the user clicks 'back to list' the search criteria is lost and so is the current page (search results are paged).
I am new to MVC and cannot seem to figure out how this should be done.
Controller
....
public ActionResult Index(PacketSearch search)
{
const int pageSize = 20;
var allPackets = this.repository.GetAllPackets().Where(p => (string.IsNullOrEmpty(search.FromIp)) || p.FromIp == search.FromIp);
var pagedPackets = new PaginatedList<RawPacket>(allPackets, search.Page ?? 0, pageSize);
search.SearchResults = pagedPackets;
return View(search);
}
public ActionResult Details(int id)
{
var packet = this.repository.GetPacket(id);
return View(packet);
}
Main page
....
#if (Model.SearchResults != null && Model.SearchResults.Count > 0)
{
<table>
<tr>
<th>
Timestamp
</th>
<th>
From IP
</th>
</tr>
#foreach (var item in Model.SearchResults) {
<tr>
<td>
#Html.ActionLink(item.TimestampString, "Details", "Packets", new { id = item.Id }, null)
</td>
<td>
#Html.DisplayFor(modelItem => item.FromIp)
</td>
</tr>
}
</table>
}
<br />
#if (Model.SearchResults.HasPreviousPage)
{
#Html.RouteLink("<<<", "Packets", new { page = (Model.SearchResults.PageIndex - 1) })
}
Page #(Model.SearchResults.PageIndex + 1) of #Model.SearchResults.TotalPages
#if (Model.SearchResults.HasNextPage)
{
#Html.RouteLink(">>>", "Packets", new { page = (Model.SearchResults.PageIndex + 1) })
}
Details Page
<h2>Packet Details</h2>
<fieldset>
<legend>RawPacket</legend>
<div class="display-label">Timestamp</div>
<div class="display-field">
#Html.DisplayFor(model => model.TimestampString)
</div>
<div class="display-label">FromIp</div>
<div class="display-field">
#Html.DisplayFor(model => model.FromIp)
</div>
</fieldset>
<p>
#Html.ActionLink("Back to List", "Index")
</p>
Any help would be much appreciated, thanks.
You must persist the input somewhere and the best place is url(because it can be cached and remembered by user).
Define another Action in controller which will do the main job of searching and send the search parameters through a query string to it.

Categories

Resources