I am trying to open or view an attachment(not save!) that a user uploaded into the Uploads folder on my website. The attachment feature will mainly be used for screen shots of bugs on the current website. I have a Bug Index view that shows all the bugs users have submitted and I would like to be able to view the attachment by clicking on the paper clip like a link. I just don't understand how to do something like this, do I need to use a partial view or some other helper method? I have attempted to write some methods to View the attachment but I don't think I am calling it correctly in my view. I have included the View Code and the controller code for the upload method and view attachment method. Please let me know if you need any other code for diagnosis. Thanks for your help!
Bug Index View
#model PagedList.IPagedList<DBFirstMVC.Models.bug>
#{
ViewBag.Title = "BugIndex";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using PagedList;
<h2 class="corporate sifr">#ViewBag.Title</h2>
<div class="crossband">
#using (Html.BeginForm())
{
<div class="lefty">
Search Bugs Index: #Html.TextBox("SearchString", "", new { #class = "text" })
</div>
<input type = "submit" value = "Search" class = "button1" />
}
<div class="righty">
#Html.ActionLink("Report a Bug", "ReportBugs", "Support", null, new { #class = "button1" })
</div>
</div>
<div class="crossband">
<div class="lefty">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink(">>", "", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
<div class="righty">
Showing Records #Model.FirstItemOnPage to #Model.LastItemOnPage from #Model.TotalItemCount records
</div>
</div>
<table>
<tr>
<th>
#Html.ActionLink("Date Submitted", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "date_submitted"})
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "date_submitted"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "date_submitted"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Submitted By", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "submitted_by"})
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "submitted_by"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "submitted_by"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Description", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "Description" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "Description"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "Description"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Priority", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "Priority" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "Priority"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "Priority"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Estimated Completion Date", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "estimated_completion_date" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "estimated_completion_date"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "estimated_completion_date"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Status", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "status" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "status"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "status"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Developer Comments", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "developer_comments" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "developer_comments"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "developer_comments"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Attachment", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "attachment" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "attachment"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "attachment"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th></th>
</tr>
#{
var row_class = "odd";
}
#foreach (var item in Model)
{
row_class = row_class == "odd"? "even" : "odd";
<tr class="#row_class">
<td>
#Html.DisplayFor(modelItem => item.date_submitted)
</td>
<td>
#Html.DisplayFor(modelItem => item.submitted_by)
</td>
<td>
#Html.DisplayFor(modelItem => item.description)
</td>
<td>
#ViewBag.Priorities[(item.priority-1)].PRIORITY
</td>
<td>
#Html.DisplayFor(modelItem => item.estimated_completion_date)
</td>
<td>
#Html.DisplayFor(modelItem => item.status)
</td>
<td>
#Html.DisplayFor(modelItem => item.developer_comments)
</td>
<td>
#if (item.attachment != null){<img id="success" src="#Url.Content("~/Images/attach.png")" alt = "attachment" />}
#Url.Action("", "ViewAttachment", new { id = item.bug_pk}) <!--<----- I think this is the problem-->
</td>
<td>
#Html.ActionLink("Edit", "EditBugs", new { id = item.bug_pk }) |
#Html.ActionLink("Delete", "DeleteBugs", new { id = item.bug_pk })
</td>
</tr>
}
</table>
Controller Methods
[Authorize]
public String Uploadfile(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Uploads"), fileName);
string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(file.FileName);
int iteration = 1;
while (System.IO.File.Exists((path)))
{
fileName = string.Concat(fileNameWithoutExtension, "-", iteration, System.IO.Path.GetExtension(file.FileName));
path = Path.Combine(Server.MapPath("~/Uploads"), fileName);
iteration++;
}
file.SaveAs(path);
}
return file.FileName;
}
public ActionResult ViewAttachment(HttpPostedFileBase file)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Uploads"), fileName);
return View(file.FileName);
}
Have an action method which accepts an ID to that purtiular Image resource. After uploading the image, you will have an id / path to the image, Show that in the grid as the HREF like this
#Html.ActionLink("View","ViewAttachment","Bugs",null,new { #id="SomeIdofImage"})
that will produce the HTML markup of an anchor tag like
View
The hardcoded SomeIdofImage should be replaced with your dynamic value ( the image Identifier)
Now have an action method in your Bug controller to read the Id as the parameter and return the image
public ActionResult ViewAttachment(string id)
{
var imgPath=SomeMethodtoGetTheFullPathToImg(id);
return File(imgPath, "image/jpeg")
}
Assuming you have a method SomeMethodtoGetTheFullPathToImg which accepts the ID and return the path to the Image stored in your server.
So I got this working and this is how I did it.
The ViewAttachment Controller was changed to allow system.IO methods
public ActionResult ViewAttachment(string fileName)
{
try
{
var fs = System.IO.File.OpenRead(Server.MapPath("~/Uploads/" + fileName));
return File(fs, "application/jpg", fileName);
}
catch
{
throw new HttpException(404, "Couldn't find " + fileName);
}
}
The View was modified to allow a paperclip image to be used for the link instead of the words download
<td>
#if (item.attachment != null)
{
<a href = #Url.Action("ViewAttachment", new { fileName = item.attachment }) > <img src = "#Url.Content("~/Images/attach.png")" alt = "attachment" /> </a>
}
</td>
The model went unmodified since I was using an existing database.
This is how I solved the problem that I was having viewing the images that were uploaded to the upload folder. This solution completely works with MVC 3 and MS SQL server 2008 R2.
Related
I have a little problem with my paging ("double TotalPage = #ViewBag.TotalPages; on Partial View"), after submiting on Create or Edit the paging throws the following error: "Cannot convert null to 'double' because it is a non-nullable value type". I have created a partial view that contains the list (Crud Operations using Ajax), all works fine, I can go to different pages in the list but when I submit a new row or edit an existing one it displays that error. Here is the code for it:
public ActionResult IndexApp(string Page)
{
var appc = objBs.appointmentdiaryBs.GetALL();
appc = from ac in db.tbl_Appoiment_Diary
select ac;
ViewBag.TotalPages = Math.Ceiling(objBs.appointmentdiaryBs.GetALL().Count() / 5.0);
int page = int.Parse(Page == null ? "1" : Page);
ViewBag.Page = page;
appc = appc.Skip((page - 1) * 5).Take(5);
ViewBag.Count = db.tbl_Appoiment_Diary.SqlQuery("SELECT * FROM dbo.tbl_Appoiment_Diary").Count();
return View(appc.ToList());
}
here is the partial view:
#model IEnumerable<BOL3.tbl_Appoiment_Diary>
<div class="table-responsive">
<table class="table" id="tbl" style="border-collapse: separate; border: solid grey 1px; border-radius: 6px; -moz-border-radius: 6px;">
<thead>
<tr style="background-color:aqua">
<th>
#Html.ActionLink("Title", "Title", "IndexApp", new { SortOrder = ViewBag.SortOrder == null ? "Asc" : (ViewBag.SortOrder == "Asc" ? "Des" : "Asc"), SortBy = "Title", page = (ViewBag.Page == null ? "1" : ViewBag.Page) })
</th>
<th>
#Html.ActionLink("Scheduled Date and Time", "DateTimeScheduled", "IndexApp", new { SortOrder = ViewBag.SortOrder == null ? "Asc" : (ViewBag.SortOrder == "Asc" ? "Des" : "Asc"), SortBy = "DateTimeScheduled", page = (ViewBag.Page == null ? "1" : ViewBag.Page) })
</th>
<th>
#Html.ActionLink("Appointment Lenght", "AppointmentLenght", "IndexApp", new { SortOrder = ViewBag.SortOrder == null ? "Asc" : (ViewBag.SortOrder == "Asc" ? "Des" : "Asc"), SortBy = "AppointmentLenght", page = (ViewBag.Page == null ? "1" : ViewBag.Page) })
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateTimeScheduled)
</td>
<td>
#Html.DisplayFor(modelItem => item.AppointmentLenght)
</td>
<td style="align-content:center">
Edit |
#Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</tbody>
</table>
#{
double TotalPage = #ViewBag.TotalPages;
}
<ul class="pagination pagination-sm">
#for (int i = 1; i <= TotalPage; i++)
{
if (i == ViewBag.Page)
{
<li class="active">#Html.ActionLink(i.ToString() + " ", "IndexApp", new { SortOrder = (ViewBag.SortOrder == null ? "Asc" : ViewBag.SortOrder), SortBy = (ViewBag.SortBy == null ? "Title" : ViewBag.SortBy), Page = i })</li>
}
else
{
<li>#Html.ActionLink(i.ToString() + " ", "IndexApp", new { SortOrder = (ViewBag.SortOrder == null ? "Asc" : ViewBag.SortOrder), SortBy = (ViewBag.SortBy == null ? "Title" : ViewBag.SortBy), Page = i })</li>
}
}
</ul>
</div>
and here is the Index view:
<div id="main-div">
<div class="clearfix"> </div>
<div class="clearfix"> </div>
<div class="container">
Adauga
<br />
<div id="div-record1">
#Html.Partial("_Detail")
</div>
</div>
</div>
I am trying to allow the users of my site to view a file in the web browser that they have just uploaded by clicking on an attachment image. I have already written the code for the upload function and now I just need some help viewing the image after the upload is complete. Below I have included the upload function from the controller and the index view that the view attachment function will be located on. Please let me know if you need more code to help with this issue and Thank you for taking the time out of you day to help me!
Controller
[Authorize]
public String Uploadfile(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetRandomFileName();
var path = Path.Combine(Server.MapPath("~/Uploads"), fileName);
file.SaveAs(path);
}
return file.FileName;
}
View
#model PagedList.IPagedList<DBFirstMVC.Models.bug>
#{
ViewBag.Title = "BugIndex";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using PagedList;
<h2 class="corporate sifr">#ViewBag.Title</h2>
<div class="crossband">
#using (Html.BeginForm())
{
<div class="lefty">
Search Bugs Index: #Html.TextBox("SearchString")
</div>
<input type = "submit" value = "Search" class = "button1" />
}
<div class="righty">
#Html.ActionLink("Report a Bug", "ReportBugs", "Support", null, new { #class = "button1" })
</div>
</div>
<div class="crossband">
<div class="lefty">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink(">>", "", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
<div class="righty">
Showing Records #Model.FirstItemOnPage to #Model.LastItemOnPage from #Model.TotalItemCount records
</div>
</div>
<table>
<tr>
<th>
#Html.ActionLink("Date Submitted", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "date_submitted"})
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "date_submitted"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "date_submitted"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Submitted By", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "submitted_by"})
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "submitted_by"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "submitted_by"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Description", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "Description" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "Description"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "Description"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Priority", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "Priority" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "Priority"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "Priority"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Estimated Completion Date", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "estimated_completion_date" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "estimated_completion_date"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "estimated_completion_date"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Status", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "status" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "status"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "status"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Developer Comments", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "developer_comments" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "developer_comments"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "developer_comments"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th>
#Html.ActionLink("Attachment", "BugIndex", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "attachment" })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "attachment"){<img id="asc" src="#Url.Content("~/Images/ico_tablesortoffset_asc.gif")" alt = "Asc Arrow" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "attachment"){<img id="desc" src="#Url.Content("~/Images/ico_tablesortoffset_desc.gif")" alt = "Desc Arrow" />}
</th>
<th></th>
</tr>
#{
var row_class = "odd";
}
#foreach (var item in Model)
{
row_class = row_class == "odd"? "even" : "odd";
<tr class="#row_class">
<td>
#Html.DisplayFor(modelItem => item.date_submitted)
</td>
<td>
#Html.DisplayFor(modelItem => item.submitted_by)
</td>
<td>
#Html.DisplayFor(modelItem => item.description)
</td>
<td>
#Html.DisplayFor(modelItem => item.priority)
</td>
<td>
#Html.DisplayFor(modelItem => item.estimated_completion_date)
</td>
<td>
#Html.DisplayFor(modelItem => item.status)
</td>
<td>
#Html.DisplayFor(modelItem => item.developer_comments)
</td>
<td>
#if (item.attachment != null){<img id="success" src="#Url.Content("~/Images/ico_confirmation_sml.gif")" alt = "attachment" />}
#if (item.attachment == null) {<img id="failure" src="#Url.Content("~/Images/ico_error_sml.gif")" alt = "no attachment" />}
<img src = "#Url.Content(string.Format("~/Uploads/{0}", item.attachment))" alt = "download" />
</td>
<td>
#Html.ActionLink("Edit", "EditBugs", new { id = item.bug_pk }) |
#Html.ActionLink("Delete", "DeleteBugs", new { id = item.bug_pk })
</td>
</tr>
}
</table>
Files stored in App_Data will be inaccessible. In order to show them on a web page, you have to move them to a different folder like ~/content or ~/images.
You could then get away with something like this:
<img src="#Url.Content(string.Format("~/images/{0}", Model.RandomFileName))" />
Why is it it gives error in return View(contacts.ToPagedList(pageNumber, pageSize)); statement the error in the Index method :
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PhoneBook.Models;
using PagedList;
namespace PhoneBook.Controllers
{
public class ContactsController : Controller
{
private PhoneDBContext db = new PhoneDBContext();
//
// GET: /Contacts/
public ViewResult Index(string searchString, string sortOrder, Contact model, string currentFilter, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.FNameSortParm = sortOrder == "FName asc"? "FName desc" : "FName asc";
ViewBag.DateSortParm = sortOrder == "Date asc" ? "Date desc" : "Date asc";
ViewBag.LNameSortParm = sortOrder == "LName asc" ? "LName desc" : "LName asc";
ViewBag.CompSortParm = sortOrder == "Company asc" ? "Company desc" : "Company asc";
ViewBag.MobSortParm = sortOrder == "Mob asc" ? "Mob desc" : "Mob asc";
ViewBag.TelSortParm = sortOrder == "Tel asc" ? "Tel desc" : "Tel asc";
if (Request.HttpMethod == "GET") { searchString = currentFilter; }
else {page = 1;}
ViewBag.CurrentFilter = searchString;
var contacts = from m in db.Contacts
select m;
switch (sortOrder)
{
case "FName desc":
contacts = contacts.OrderByDescending(s => s.FirstName);
break;
case "FName asc":
contacts = contacts.OrderBy(s => s.FirstName);
break;
case "LName desc":
contacts = contacts.OrderByDescending(s => s.LastName);
break;
case "LName asc":
contacts = contacts.OrderBy(s => s.LastName);
break;
case "Company desc":
contacts = contacts.OrderByDescending(s => s.Company);
break;
case "Company asc":
contacts = contacts.OrderBy(s => s.Company);
break;
case "Date desc":
contacts = contacts.OrderByDescending(s => s.DateAdded);
break;
case "Date asc":
contacts = contacts.OrderBy(s => s.DateAdded);
break;
case "Mob desc":
contacts = contacts.OrderByDescending(s => s.MobileNumber);
break;
case "Mob asc":
contacts = contacts.OrderBy(s => s.MobileNumber);
break;
case "Tel desc":
contacts = contacts.OrderByDescending(s => s.TelephoneNumber);
break;
case "Tel asc":
contacts = contacts.OrderBy(s => s.TelephoneNumber);
break;
}
if (!String.IsNullOrEmpty(searchString))
{
contacts = contacts.Where(s => s.LastName.ToUpper().Contains(searchString)||s.FirstName.ToUpper().Contains(searchString)||s.Company.ToUpper().Contains(searchString));
}
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(contacts.ToPagedList(pageNumber, pageSize));
}
//
// GET: /Contacts/Details/5
public ViewResult Details(int id)
{
Contact contact = db.Contacts.Find(id);
return View(contact);
}
//
// GET: /Contacts/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Contacts/Create
[HttpPost]
public ActionResult Create(Contact contact)
{
if (ModelState.IsValid)
{
db.Contacts.Add(contact);
contact.DateAdded = DateTime.Now;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(contact);
}
//
// GET: /Contacts/Edit/5
public ActionResult Edit(int id=0)
{
Contact contact = db.Contacts.Find(id);
if (contact == null) { return HttpNotFound(); } // returns blank page if id is not valid
return View(contact);
}
//
// POST: /Contacts/Edit/5
[HttpPost]
public ActionResult Edit(Contact contact)
{
if (ModelState.IsValid)
{
db.Entry(contact).State = EntityState.Modified;
contact.DateAdded = DateTime.Now;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(contact);
}
//
// GET: /Contacts/Delete/5
public ActionResult Delete(int id)
{
Contact contact = db.Contacts.Find(id);
if (contact == null) { return HttpNotFound(); }
return View(contact);
}
//
// POST: /Contacts/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
Contact contact = db.Contacts.Find(id);
if (contact == null) { return HttpNotFound(); }
db.Contacts.Remove(contact);
db.SaveChanges();
return RedirectToAction("Index");
}
public ActionResult SearchIndex(string searchString)
{
var contacts = from m in db.Contacts
select m;
if (!String.IsNullOrEmpty(searchString))
{
contacts = contacts.Where(s => s.LastName.Contains(searchString));
}
return View(contacts);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
below is the Index.cshtml code:
#model PagedList.IPagedList<PhoneBook.Models.Contact>
#{
ViewBag.Title = "Phone Book";
}
<p>
#using (Html.BeginForm()){
<p> Search: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Go" /></p>
}
</p>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.ActionLink("First Name", "Index", new { sortOrder=ViewBag.FNameSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LNameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Mobile Num", "Index", new { sortOrder = ViewBag.MobSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Tel Num", "Index", new { sortOrder = ViewBag.TelSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Company", "Index", new { sortOrder = ViewBag.CompSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Date Added/Updated", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.MobileNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.TelephoneNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.Company)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateAdded)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.ID })
#Html.ActionLink("Edit", "Edit", new { id=item.ID })
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
<div>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "Index", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "Index", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "Index", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink(">>", "Index", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
Try the following three changes.
Put this code before the switch statement:
if (!String.IsNullOrEmpty(searchString))
{
contacts = contacts.Where(s => s.LastName.ToUpper().Contains(searchString)||s.FirstName.ToUpper().Contains(searchString)||s.Company.ToUpper().Contains(searchString));
}
Add a default case in your switch statement, and make it throw.
switch (sortOrder) {
case ...:
...
default:
throw new ArgumentException("Bad sort order specified", "sortOrder");
}
Use the type IOrderedQueryable<T>.
IOrderedQueryable<T> orderedContacts;
switch (sortOrder)
{
case "FName desc":
orderedContacts = contacts.OrderByDescending(s => s.FirstName);
break;
...
}
...
return View(orderedContacts.ToPagedList(pageNumber, pageSize));
return View(orderedContacts.ToList().ToPagedList(pageNumber, pageSize));
I am trying to create a search function that allows the user to search a column that is specified by a dropdown, I have been able to get the search to work but only by using a specific column and a contains method. Can anyone help?
Below I have included my controller and my view, please let me know if you need any other code. Thanks for your time and help!
I am almost positive that this is the code that I have to alter to use the dropdown to search instead of a specific column.
if (!String.IsNullOrEmpty(searchString))
{
IAMP = IAMP.Where(p => p.PA.ToUpper().Contains(searchString.ToUpper()));
}
Controller
public class PaController : Controller
{
PaEntities db = new PaEntities();
// Index Method
public ViewResult Index(string CurrentField, string sortField, string sortOrder, string currentFilter, string searchString, int? page, string Versions, string VPS, string Directors, string IAMP_SEARCH)
{
ViewBag.CurrentOrder = sortOrder = String.IsNullOrEmpty(sortOrder) ? "asc" : sortOrder; // Provides the order to sort
ViewBag.CurrentField = sortField = String.IsNullOrEmpty(sortField) ? "IAMP_PK" : sortField; // Provides the field to sort
var IAMP = from p in db.iamp_mapping select p;
var ISER = from s in db.iamp_search_string select s;
if (Versions != null && Versions != String.Empty) // Version Dropdown Sort Function
{
IAMP = IAMP.Where(v => v.VERSION.Contains(Versions));
}
var VIAMP = from x in db.version_number select x;
var VPIAMP = from v in db.vp_table select v;
var DIAMP = from d in db.director_table select d;
ViewData["SelectedVersion"] = Versions;
ViewData["Versions"] = new SelectList(VIAMP.Select(x => x.VERSION));
ViewData["VPS"] = new SelectList(VPIAMP.Select(x => x.VP));
ViewData["Directors"] = new SelectList(DIAMP.Select(x => x.DIRECTOR));
ViewData["currentFilter"] = currentFilter;
ViewData["IAMP_SEARCH"] = IAMP_SEARCH;
ViewData["IAMP_SEARCH"] = new SelectList(ISER.Select(x => x.IAMP_SEARCH));
if (Request.HttpMethod == "GET") {
searchString = currentFilter; //sets the currentFilter equal to Searchstring
IAMP_SEARCH = sortField;
}
else {
page = 1; // defaults to page 1
}
ViewBag.CurrentFilter = searchString; // Provides the view with the current filter string
if (!String.IsNullOrEmpty(searchString))
{
IAMP = IAMP.Where(p => p.PA.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortField) {
default: IAMP = sortOrder == "asc" ? IAMP.OrderBy(p => p.PA) : IAMP.OrderByDescending(p => p.PA); break;
case "VERSION": IAMP = sortOrder == "asc"? IAMP.OrderBy(p => p.VERSION) : IAMP.OrderByDescending(p => p.VERSION); break;
case "MAJOR_PROGRAM": IAMP = sortOrder == "asc" ? IAMP.OrderBy(p => p.MAJOR_PROGRAM) : IAMP.OrderByDescending(p => p.MAJOR_PROGRAM); break;
case "INVESTMENT_AREA": IAMP = sortOrder == "asc" ? IAMP.OrderBy(p => p.INVESTMENT_AREA) : IAMP.OrderByDescending(p => p.INVESTMENT_AREA); break;
case "VP": IAMP = sortOrder == "asc" ? IAMP.OrderBy(p => p.VP) : IAMP.OrderByDescending(p => p.VP); break;
case "DIRECTOR": IAMP = sortOrder == "asc" ? IAMP.OrderBy(p => p.DIRECTOR) : IAMP.OrderByDescending(p => p.DIRECTOR); break;
}
int pageSize = 15; // number of records shown on page view
int pageNumber = (page ?? 1); // start page number
return View(IAMP.ToPagedList(pageNumber, pageSize)); // uses pagedList method to return correct page values
}
VIEW
#model PagedList.IPagedList<DBFirstMVC.Models.iamp_mapping>
#{
ViewBag.Title = "Index";
}
#using PagedList;
<h2 class="corporate sifr">PA Mapping</h2>
#using (Html.BeginForm())
{
<p>
Show Version: #Html.DropDownList("Versions","All")
<input type = "submit" value = "Go" />
</p>
}
#using (Html.BeginForm())
{
<div class="lefty">
Find by #Html.DropDownList("IAMP_SEARCH","All"): #Html.TextBox("SearchString")
<input type = "submit" value = "Search" />
</div>
}
<div class="righty">
#Html.ActionLink("Add a new PA to the database", "Create")
</div>
<br /><br />
<div>
<div class="lefty">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink(">>", "", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
<div class="righty">
Showing Records #Model.FirstItemOnPage to #Model.LastItemOnPage from #Model.TotalItemCount
</div>
</div>
<table>
<tr>
<th>
#Html.ActionLink("PA", "", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "PA", Versions = ViewBag.SelectedVersion })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "PA"){ <img src="../../Images/ico_tablesortoffset_asc.gif" alt = "table sort arrow asc"/>}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "PA"){ <img src="../../Images/ico_tablesortoffset_desc.gif" alt = "table sort arrow desc"/>}
</th>
<th>
#Html.ActionLink("MAJOR PROGRAM", "", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "MAJOR_PROGRAM", Versions = ViewBag.SelectedVersion })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "MAJOR_PROGRAM"){ <img src="../../Images/ico_tablesortoffset_asc.gif" alt = "table sort arrow asc" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "MAJOR_PROGRAM"){ <img src="../../Images/ico_tablesortoffset_desc.gif" alt = "table sort arrow desc"/>}
</th>
<th>
#Html.ActionLink("INVESTMENT AREA", "", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "INVESTMENT_AREA", Versions = ViewBag.SelectedVersion })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "INVESTMENT_AREA"){ <img src="../../Images/ico_tablesortoffset_asc.gif" alt = "table sort arrow asc"/>}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "INVESTMENT_AREA"){ <img src="../../Images/ico_tablesortoffset_desc.gif" alt = "table sort arrow desc" />}
</th>
<th>
#Html.ActionLink("Version", "", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "VERSION", Versions = ViewBag.SelectedVersion })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "VERSION"){ <img src="../../Images/ico_tablesortoffset_asc.gif" alt = "table sort arrow asc" />}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "VERSION"){ <img src="../../Images/ico_tablesortoffset_desc.gif" alt = "table sort arrow desc"/>}
</th>
<th>
#Html.ActionLink("VP", "", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "VP", Versions = ViewBag.SelectedVersion })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "VP"){ <img src="../../Images/ico_tablesortoffset_asc.gif" alt = "table sort arrow asc"/>}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "VP"){ <img src="../../Images/ico_tablesortoffset_desc.gif" alt = "table sort arrow desc"/>}
</th>
<th>
#Html.ActionLink("DIRECTOR", "", new { sortOrder = ViewBag.currentOrder == "asc" ? "desc" : "asc", sortField = "DIRECTOR", Versions = ViewBag.SelectedVersion })
#if (ViewBag.currentOrder == "asc" && ViewBag.CurrentField == "DIRECTOR"){ <img src="../../Images/ico_tablesortoffset_asc.gif" alt = "table sort arrow asc"/>}
#if (ViewBag.currentOrder == "desc" && ViewBag.CurrentField == "DIRECTOR"){ <img src="../../Images/ico_tablesortoffset_desc.gif" alt = "table sort arrow desc"/>}
</th>
<th></th>
</tr>
#{
var row_class = "odd";
}
#foreach (var item in Model) {
row_class = row_class == "odd"? "even" : "odd";
<tr class="#row_class">
<td>
#Html.DisplayFor(modelItem => item.PA)
</td>
<td>
#Html.DisplayFor(modelItem => item.MAJOR_PROGRAM)
</td>
<td>
#Html.DisplayFor(modelItem => item.INVESTMENT_AREA)
</td>
<td>
#Html.DisplayFor(modelItem => item.VERSION)
</td>
<td>
#Html.DisplayFor(modelItem => item.VP)
</td>
<td>
#Html.DisplayFor(modelItem => item.DIRECTOR)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.PA}) |
#Html.ActionLink("Delete", "Delete", new { id = item.PA})
</td>
</tr>
}
</table>
<div>
<div class="lefty">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
#Html.Raw(" ");
#Html.ActionLink(">>", "", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, Versions = ViewBag.SelectedVersion })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
<div class="righty">
Showing Records #Model.FirstItemOnPage to #Model.LastItemOnPage from #Model.TotalItemCount
</div>
</div>
<br /><br />
<div>
#Html.ActionLink("Download in Excel Format", "PaExcelOutput", new {Versions = ViewBag.SelectedVersion, currentFilter = ViewBag.currentFilter})
</div>
You could use Dynamic Query which allows you to use dynamic column names.
I am trying to add a grid to a table of data in my MVC application but keep getting the following error message:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[AssociateTracker.Models.Associate]', but this dictionary requires a model item of type 'PagedList.IPagedList`1[AssociateTracker.Models.Associate]'.
View:
#model PagedList.IPagedList<AssociateTracker.Models.Associate>
#{
ViewBag.Title = "ViewAll";
}
<h2>View all</h2>
<table>
<tr>
<th>First name</th>
<th>#Html.ActionLink("Last Name", "ViewAll", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })</th>
<th>Email address</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.Email</td>
<td>
#Html.ActionLink("Details", "Details", new { id = item.AssociateId }) |
#Html.ActionLink("Edit", "Edit", new { id = item.AssociateId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.AssociateId })
</td>
</tr>
}
</table>
<div>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "ViewAll", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "ViewAll", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "ViewAll", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink(">>", "ViewAll", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
I have checked against Microsoft's Contosos University example but can't spot any differences. Can anyone else see what the issue might be?
The error message seems pretty self explanatory. Your view expects an IPagedList<Associate> instance but you are passing a List<Associate> from your controller action.
So inside your controller action you need to provide the proper model to the view:
public ActionResult Index(int? page)
{
List<Associate> associates = GetAssociates();
IPagedList<Associate> model = associates.ToPagedList(page ?? 1, 10);
return View(model);
}
I used the extension method from here. The IPagedList<T> is not a standard type built in ASP.NET MVC so you will have to reference the proper assemblies.