Trying to connect to wwwroot and get a image - image

I work in aspnet core mvc technology,
I manage to add an image, it does go to wwwroot, but the image does not display well in the browser
Example: enter image description here
enter image description here
My Controller:
[HttpPost,ActionName("CreateAnimal")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateAnimal([FromForm] CreateAnimalViewModel model)
{
string wwwPath = _Environment.WebRootPath;
string contentPath = _Environment.ContentRootPath;
ModelState.Clear();
model.Animal!.Category = _context.Categories.Where(c => c.CategoryId == model.Animal.CategoryId).FirstOrDefault()!;
var path = Path.Combine(wwwPath, "Images", model.Photo!.FileName);
if (model.Photo.Length > 0)
{
using var stream = new FileStream(path, FileMode.Create);
await model.Photo.CopyToAsync(stream);
}
model.Animal.PhotoUrl = path;
_context.Add(model.Animal);
if (TryValidateModel(model))
{
_context.Add(model.Animal!);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Manager));
}
ViewBag.CategoryId = new SelectList(_context.Categories, "CategoryId", "Name");
return View();
}
My View:
#model IEnumerable<PetShop.Data.Models.Animal>
<table id="Table">
<thead>
<tr>
<th>#Html.DisplayNameFor(model => model.PhotoUrl)</th>
<th>#Html.DisplayNameFor(model => model.Name)</th>
<th>#Html.DisplayNameFor(model => model.BirthDate)</th>
<th>#Html.DisplayNameFor(model => model.Description)</th>
<th>#Html.DisplayNameFor(model => model.Category.Name)</th>
<th>#Html.DisplayNameFor(model => model.Category)</th>
<th>Edit Animel</th>
<th>Delete Animel</th>
#foreach (var item in Model!) {
<img class="Images" src="~/Images/#Html.DisplayFor(modelItem => item.PhotoUrl)">
</td>
<td>#Html.DisplayFor(modelItem => item.Name)</td>
<td>#Html.DisplayFor(modelItem => item.BirthDate)</td>
<td>#Html.DisplayFor(modelItem => item.Description)</td>
<td>#Html.DisplayFor(modelItem => item.Category.Name)</td>
<td>#Html.DisplayFor(modelItem => item.CategoryId)</td>
<a asp-action="EditAnimel" asp-route-id="#item.AnimalId">
<input type="submit" value="Edit">
</a>
<a asp-action="DeleteAnimel" asp-route-id="#item.AnimalId">
<input type="submit" value="Delete">
</a>
}

Below is a work demo, you can refer to it.
ProductController.cs:
[Route("product")]
public class ProductController : Controller
{
private IWebHostEnvironment webHostEnvironment;
public ProductController(IWebHostEnvironment _webHostEnvironment)
{
webHostEnvironment = _webHostEnvironment;
}
[Route("")]
[Route("index")]
[Route("~/")]
public IActionResult Index()
{
return View("Index", new Product());
}
[Route("save")]
[HttpPost]
public IActionResult Save(Product product, IFormFile photo)
{
if (photo == null || photo.Length == 0)
{
return Content("File not selected");
}
else
{
var path = Path.Combine(this.webHostEnvironment.WebRootPath, "images", photo.FileName);
var stream = new FileStream(path, FileMode.Create);
photo.CopyToAsync(stream);
product.Photo = photo.FileName;
}
ViewBag.product = product;
return View("Success");
}
}
Index.cshtml:
#model SingleFile.Models.Product
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<form asp-controller="product" asp-action="save" method="post" enctype="multipart/form-data">
<table cellpadding="2" cellspacing="2">
<tr>
<td>Id</td>
<td>
<input type="text" asp-for="Id" />
</td>
</tr>
<tr>
<td>Name</td>
<td>
<input type="text" asp-for="Name" />
</td>
</tr>
<tr>
<td>Price</td>
<td>
<input type="text" asp-for="Price" />
</td>
</tr>
<tr>
<td>Photo</td>
<td>
<input type="file" name="photo" />
</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Save" /></td>
</tr>
</table>
</form>
</body>
</html>
Success.cshtml:
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Success</title>
</head>
<body>
<h3>Product Info</h3>
<table cellpadding="2" cellspacing="2" border="1">
<tr>
<td>Id</td>
<td>#ViewBag.product.Id</td>
</tr>
<tr>
<td>Name</td>
<td>#ViewBag.product.Name</td>
</tr>
<tr>
<td>Price</td>
<td>#ViewBag.product.Price</td>
</tr>
<tr>
<td>Photo</td>
<td><img src="~/images/#ViewBag.product.Photo" width="120" /></td>
</tr>
</table>
</body>
</html>
Product
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public string Photo { get; set; }
}

Related

Display Required Error message IEnumerable Model

On the same view I am returning a list. Also, I have [HttpPost] to create new entry.
When the model is not valid, The ValidationSummary shows that expenseName is Required.
I would like to show Model required error Messages near each field in my View. asp-Validation-for was working when I didn't have IEnumerable model. What I have to do so I can see the validation error messages using IEnumerable model? (etc. for expenseName)
Model
[Key]
public int expenseId { get; set; }
[Column(TypeName = "nvarchar(50)")]
[Required(ErrorMessage = "The field 'Expense Name' is required")]
public string expenseName { get; set;}
public double price { get; set; }
public bool isStandard { get; set; }
public DateTime? date { get; set; }
View
#model IEnumerable<ExpenseTracker.Models.Expenses>
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
#{
ViewData["Title"] = "Index";
}
<form method="post" enctype="multipart/form-data" asp-controller="Expenses" asp-action="Index">
<div>
<label for="files" class="lbl-select-file">Select Expense File</label>
<input id="files" name="postedFiles" class="btn-uploader" type="file">
</div>
<label class="expense-name-lbl" for="expenseName">Expense Name</label>
<input type="text" name="expenseName" class="expense-name-input" id="expenseName" />
**<span asp-validation-for=" " class="text-danger"></span>**
<div class="form-group form-check">
<label class="form-check-label checkbox-isStandard-form">
<input class="form-check-input" type="checkbox" name="chkeco" title="Check this if the bill is monthly/yearly" /> Is Standard?
</label>
</div>
<input type="submit" class="btn btn-success btnColor-expenses" value="Upload" />
<label id="fileName"></label>
<span class="uploaded-file">#Html.Raw(ViewBag.Message)</span>
</form>
<table class="table table-text">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.expenseName)
</th>
<th>
#Html.DisplayNameFor(model => model.price)
</th>
<th>
#Html.DisplayNameFor(model => model.isStandard)
</th>
<th>
#Html.DisplayNameFor(model => model.date)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.expenseName)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
<input type="checkbox" class="checkbox-isStandard" checked="#item.isStandard" />
</td>
<td>
#if (item.date.HasValue)
{
DateTime? datetimeToDate = #item.date;
string FormattedDate = datetimeToDate.Value.ToString("dd-MM-yyyy");
<label>#FormattedDate</label>
}
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.expenseId">Edit</a> |
<a asp-action="Details" asp-route-id="#item.expenseId">Details</a> |
<a asp-action="Delete" asp-route-id="#item.expenseId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Controller
[HttpPost]
[ValidateAntiForgeryToken]
[PreventDuplicateRequest]
public async Task<IActionResult> Index(IFormCollection formCollection, string expenseName,
List<IFormFile> postedFiles, [Bind("expenseName,price,isStandard,date")] Expenses expenses)
{
if (ModelState.IsValid)
{
......
return View(await _context.Expenses.ToListAsync());
}
else
{
return View(await _context.Expenses.ToListAsync());
}
You can create a ViewModel which contains a List<Expenses>(you wanna display in the view) and a Expenses(you wanna upload to the controller).
ViewModel
public class ExpensesViewModel
{
//Pass the value to this parameter in the get method to display on the page
public List<Expenses> ListModel { get; set; }
public Expenses model { get; set; }
}
Then change your view code like:
#model ExpensesViewModel
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
#{
ViewData["Title"] = "Index";
}
<form method="post" enctype="multipart/form-data" asp-controller="Home" asp-action="Show">
<div>
<label for="files" class="lbl-select-file">Select Expense File</label>
<input id="files" name="postedFiles" class="btn-uploader" type="file">
</div>
<div class="form-group">
<label class="expense-name-lbl" for="expenseName">Expense Name</label>
<input type="text" \ class="expense-name-input" asp-for=#Model.model.expenseName />
<span asp-validation-for="#Model.model.expenseName" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label checkbox-isStandard-form">
<input class="form-check-input" type="checkbox" name="chkeco" title="Check this if the bill is monthly/yearly" /> Is Standard?
</label>
</div>
<input type="submit" class="btn btn-success btnColor-expenses" value="Upload" />
<label id="fileName"></label>
<span class="uploaded-file">#Html.Raw(ViewBag.Message)</span>
</form>
<table class="table table-text">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.model.expenseName)
</th>
<th>
#Html.DisplayNameFor(model => model.model.price)
</th>
<th>
#Html.DisplayNameFor(model => model.model.isStandard)
</th>
<th>
#Html.DisplayNameFor(model => model.model.date)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.ListModel)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.expenseName)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
<input type="checkbox" class="checkbox-isStandard" checked="#item.isStandard" />
</td>
<td>
#if (item.date.HasValue)
{
DateTime? datetimeToDate = #item.date;
string FormattedDate = datetimeToDate.Value.ToString("dd-MM-yyyy");
<label>#FormattedDate</label>
}
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.expenseId">Edit</a> |
<a asp-action="Details" asp-route-id="#item.expenseId">Details</a> |
<a asp-action="Delete" asp-route-id="#item.expenseId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Finally, You can validate your expenseName property.
You can try to add this validation js.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>

How to pass search criteria to controller using MVC AJAX PagedList

I'm creating Advanced Search using MVC. What I mean by Advanced Search is user can do combination search, for example, user can search by category = 'Child' and name contains 'A' or age <= 10. then the result is displayed using MVC PagedList.
I followed UnobtrusiveAjax tutorial based on example from PagedList source. I defined 2 files, Index.cshtml for View and _List.cshtml for PartialView. Index contains search criteria and a button to add more clause.
and _List contains table for displaying the result using AJAX
The problem is after I filtered by code for example contains 'A' and click search then navigate to page 2 the filter value is missing and it will display code which not contains 'A'. How to solve this problem?
ViewModel:
public class WorkflowStateListViewModel
{
public IEnumerable<string> FilterField { get; set; }
public IEnumerable<string> FilterOperator { get; set; }
public IEnumerable<string> FilterString { get; set; }
public IEnumerable<string> FilterLogical { get; set; }
public PagedList<WorkflowStateListDetailViewModel> WorkflowStateListDetailVM { get; set; }
public int? Page { get; set; }
}
Controller:
public ActionResult Filter(WorkflowStateListViewModel workflowStateListVM, int? page)
{
var workflowStatesQuery = from ws in db.WorkflowStates
where ws.RowStatus == true
select ws;
if (workflowStateListVM.FilterField != null)
{
for (int i = 0; i < workflowStateListVM.FilterField.Count(); i++)
{
workflowStatesQuery = DoFilter(workflowStatesQuery, workflowStateListVM.FilterField.ElementAt(i), workflowStateListVM.FilterOperator.ElementAt(i), workflowStateListVM.FilterString.ElementAt(i));
}
}
workflowStatesQuery = workflowStatesQuery.OrderBy(ws => ws.Code);
var workflowStateListDetailVM = from ws in workflowStatesQuery
select new WorkflowStateListDetailViewModel()
{
WorkflowStateID = ws.WorkflowStateID,
Code = ws.Code,
Name = ws.Name,
Level = ws.Level,
PIC = ws.PIC
};
int pageNumber = (page ?? 1);
return PartialView("_List", workflowStateListDetailVM.ToPagedList(pageNumber, 5));
}
Index.cshtml
#model ViewModels.WorkflowStateListViewModel
#using (Ajax.BeginForm("Filter", "WorkflowState",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
UpdateTargetId = "workflowStateList"
},
new { #class = "form-inline" }))
{
<div id="clauses">
</div>
<p>
<div class="form-group">
#Html.DropDownList("FilterField", new SelectList(Model.FilterField), new { #class = "form-control" })
</div>
<div class="form-group">
#Html.DropDownList("FilterOperator", new SelectList(Model.FilterOperator), new { #class = "form-control" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.FilterString, new { #class = "form-control" })
</div>
<input type="submit" value="Search" class="btn btn-default" />
</p>
<p>
<div class="form-group">
<span class="glyphicon glyphicon-plus-sign"></span> Add new clause
</div>
</p>
<div id="workflowStateList">
#{ Html.RenderPartial("_List", Model); }
</div>
}
_List.cshtml
#model JOeBilling.ViewModels.WorkflowStateListViewModel
#using PagedList.Mvc;
<div class="table-responsive">
<table class="table table-striped table-hover table-condensed">
<tr>
<th></th>
<th>
Code
</th>
<th>
Name
</th>
<th>
Level
</th>
<th>
PIC
</th>
</tr>
#foreach (var item in Model.WorkflowStateListDetailVM)
{
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
#Html.DisplayFor(modelItem => item.Code)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Level)
</td>
<td>
#Html.DisplayFor(modelItem => item.PIC)
</td>
</tr>
}
</table>
</div>
<br />
Page #(Model.WorkflowStateListDetailVM.PageCount < Model.WorkflowStateListDetailVM.PageNumber ? 0 : Model.WorkflowStateListDetailVM.PageNumber) of #Model.WorkflowStateListDetailVM.PageCount
#Html.PagedListPager(Model.WorkflowStateListDetailVM,
page => Url.Action("Filter", new { page }),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "workflowStateList" }))
UPDATE
UPDATE 2
UPDATE 3 Response tab
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />
<div class="table-responsive">
<table class="table table-striped table-hover table-condensed">
<tr>
<th></th>
<th>
Code
</th>
<th>
Name
</th>
<th>
Level
</th>
<th>
PIC
</th>
<th>
Created By
</th>
<th>
Created Date
</th>
<th>
Modified By
</th>
<th>
Modified Date
</th>
</tr>
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
A06
</td>
<td>
Preparing Task Code
</td>
<td>
6
</td>
<td>
</td>
<td>
JKTWLA
</td>
<td>
28/04/2014 4:24:52 PM
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
A07
</td>
<td>
Closed
</td>
<td>
7
</td>
<td>
</td>
<td>
JKTWLA
</td>
<td>
28/04/2014 4:25:06 PM
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
C01
</td>
<td>
New Invoice
</td>
<td>
1
</td>
<td>
</td>
<td>
JKTWLA
</td>
<td>
13/06/2014 10:49:00 AM
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
</div>
<br />
Page 2 of 2
<div class="pagination-container"><ul class="pagination"><li class="PagedList-skipToPrevious"><a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#workflowStateList" href="/WorkflowState/Filter?page=1" rel="prev">«</a></li><li><a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#workflowStateList" href="/WorkflowState/Filter?page=1">1</a></li><li class="active"><a>2</a></li></ul></div>

How To Send List Of Data From View To Controller With Ajax Form in Mvc4

How To Send List Of Data From View To Controller With Ajax Form In Mvc4 :
My Model Sample :
public class Food
{
public string name { get; set; }
public int quantity { get; set; }
}
public class CustomerModel {
public string CustomerName { get; set; }
public List<Food> ListFoods { get; set; }
}
[HttpPost]
public ActionResult AddCustomer(CustomerModel model)
{
//Add New Person
return Json(new { Result = "OK" });
}
My View :
#using (Ajax.BeginForm("AddCustomer", "Resturant", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "Success"
}, new { #id = "frmaddCustomer" }))
{
<p>
<label>Customer Name </label>
</p>
<p>
#Html.CH_TextBox("CustomerName").size(TextBoxSize.Medium)
</p>
<p>
Food List
</p>
<table id="FoodList" class="static-table" data-bind='visible: gifts().length > 0'>
<thead>
<tr>
<td style="width: 250px;">Name</td>
<td>Quantity</td>
<td />
</tr>
</thead>
<tbody data-bind='foreach: gifts'>
<tr>
<td>
#Html.CH_TextBox("Food.name").size(TextBoxSize.Medium)
</td>
<td>
#Html.CH_TextBox("Food.quantity").size(TextBoxSize.Medium)
<td>
<a id="deleteRow">Delete</a>
</tr>
</tbody>
</table>
<button data-bind='click: addGift' type="submit">New Food</button>
<button data-bind='enable: gifts().length > 0' type="submit">Send Data</button>
}
I use the following method to post data to controller model :
<tr>
<td>
#Html.CH_TextBox("Food[0].name").size(TextBoxSize.Medium)
</td>
<td>
#Html.CH_TextBox("Food[0].quantity").size(TextBoxSize.Medium)
</td>
<td>
<a id="deleteRow">Delete</a>
</td>
</tr>
<tr>
<td>
#Html.CH_TextBox("Food[1].name").size(TextBoxSize.Medium)
</td>
<td>
#Html.CH_TextBox("Food[1].quantity").size(TextBoxSize.Medium)
</td>
<td>
<a id="deleteRow">Delete</a>
</td>
</tr>
<tr>
<td>
#Html.CH_TextBox("Food[2].name").size(TextBoxSize.Medium)
</td>
<td>
#Html.CH_TextBox("Food[2].quantity").size(TextBoxSize.Medium)
</td>
<td>
<a id="deleteRow">Delete</a>
</td>
</tr>
by using this method, my problem was solved.
Thanks .

Partial view renders as full view

MVC 3 , ajax, c#
My partial view is rendering as a new page instead of replacing the search results table.
Controller:
public class SearchController : Controller
{
//
// GET: /Search/
private myEntities db = new myEntities();
private Repository repo = new Repository();
[HttpGet]
public ActionResult Index()
{
var model = new List<PersonViewModel>();
model = repo.GetPeople();
return View(model);
}
public PartialViewResult _SearchResult(string fname, string lname)
{
var personResult = repo.GetSearchResult(fname, lname);
return PartialView("_SearchResult", personResult);
}
}
The view:
<div class="page">
<div class="middle-col-comment-mod">
<h2>Search Existing Trespassers</h2>
<div id="search">
#using (Ajax.BeginForm("_SearchResult", "Search", null, new AjaxOptions { HttpMethod = "Post", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace, UpdateTargetId = "indexSearchResults" }))
{
<div class="editor-field">
<label>First Name:</label>
#Html.TextBox("FirstName")
<label style = "margin-left: 15px;">Last Name:</label>
#Html.TextBox("LastName", "", new { style = "margin-right: 15px;" })
<input type="submit" name="submit" class="skbutton" value="Search" />
</div>
}
</div>
<table id="indexSearchResults" class="data-table">
<tr>
<th>
FirstName
</th>
<th>
LastName
</th>
<th>
Gender
</th>
<th>
City
</th>
<th>
DOB
</th>
<th>
IsStudent
</th>
<th>
Actions
</th>
</tr>
#if (Model.Count() == 0)
{
<tr>
<td colspan=7>
There are currently no trespassers in the trespass database.
</td>
</tr>
}
else
{
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.Gender)
</td>
<td>
#Html.DisplayFor(modelItem => item.DOB)
</td>
<td>
#Html.DisplayFor(modelItem => item.School)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsStudent)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.PersonId }) |
#Html.ActionLink("Details", "Details", new { id = item.PersonId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.PersonId })
</td>
</tr>
}
}
</table>
</div>
</div>
And the partial view:
#model IEnumerable<TrespassTracker.Models.PersonViewModel>
<table>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Gender
</th>
<th>
Date of Birth
</th>
<th>
Is a Student?
</th>
<th>
Actions
</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.Gender)
</td>
<td>
#Html.DisplayFor(modelItem => item.DOB)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsStudent)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</table>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
From my research I found the usual suspect to be the missing link to the jquery script in the partial, but I had that. I checked the network tab on my wed dev tools and found it is being called. What else could the problem be?
the script won't cause any problem and the only thing I see wrong here is the table. you are trying yo fill the table with other table which returns a table, use a div instead to update the ajax form (search result):
<div id="indexSearchResults">
<table>
..........
</table>
</div>
Try this
<div class="page">
<div class="middle-col-comment-mod">
<h2>Search Existing Trespassers</h2>
<div id="search">
#using (Ajax.BeginForm("_SearchResult", "Search", null, new AjaxOptions { HttpMethod = "Post", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace, UpdateTargetId = "indexSearchResults" }))
{
<div class="editor-field">
<label>First Name:</label>
#Html.TextBox("FirstName")
<label style = "margin-left: 15px;">Last Name:</label>
#Html.TextBox("LastName", "", new { style = "margin-right: 15px;" })
<input type="submit" name="submit" class="skbutton" value="Search" />
</div>
}
</div>
#if (Model.Count() == 0)
{
<label>There are currently no trespassers in the trespass database. </label>
}
else
{
foreach (var item in Model)
{
#Html.Partial("__SearchResult",item)
}
</div>
</div>
How 'bout to use jQuery do reload your result content, instead Post from your form? You can named some div with an ID and uses it as reference do jQuery.load() (considering you're using that ViewModel you passed into Index action):
1.View
#model YourModel
<!-- ... -->
<div id="search">
#using (Ajax.BeginForm("MainPostAction", "ControllerName", FormMethod.Post, new { id = "yourFormID" })
{
<div class="editor-field">
<label>First Name:</label>
#Html.TextBoxFor(model => model.FirstName)
<label style = "margin-left: 15px;">Last Name:</label>
#Html.TextBoxFor(model => model.LastName, new { style = "margin-right: 15px;" })
<input type="button" name="submit" id="searchButton" class="skbutton" value="Search" />
</div>
<div id="results"></div>
}
</div>
Javascript:
$(document).ready(function() {
$('#searchButton').click(function(event) {
$('#results').load('#Url.Action('_SearchResult', 'Search')', $('#yourFormID').serialize());
});
}
Your action remains the same.
How 'bout it?

MVC3 IPagedList in ViewModel

I want to have a page that has a form on the top of the page to enter movies in a system, and on the bottom of the page I want to have a table to display all of the movies in inventory. I am getting an error saying: Value cannot be less than 1. Parameter name: Page Size.
I have a viewmodel that currently looks like this:
public class InventoryViewModel
{
public Inventory Inventory { get; set; }
public IPagedList<Inventory> InventoryList { get; set; }
}
In my controller I have:
public ActionResult Index(int? page)
{
ViewBag.MoviesList = new SelectList(inventoryRepository.Movies, "MovieId", "Title");
InventoryViewModel vm = new InventoryViewModel
{
Inventory = new Inventory(),
InventoryList = inventoryRepository.GetInventory.ToPagedList(page.HasValue ? page.Value - 1 : 0, defaultPageSize)
};
return View(vm);
}
In my view I have:
<div class="well">
<h4>Enter Movie in System:</h4>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true, "Movie was not entered in system. Please correct the errors and try again.")
<div>
<div class="input-prepend">
<span class="add-on"><i class="icon-film"></i></span>
#Html.DropDownListFor(m => m.Inventory.MoviesId, (SelectList)ViewBag.MoviesList)
#Html.ValidationMessageFor(m => m.Inventory)
</div>
<div class="input-prepend">
<span class="add-on"><i class="icon-calendar"></i></span>
#Html.TextBox("Quantity")
</div>
<p><button class="btn btn-primary" type="submit" value="Submit">Submit</button></p>
#Html.ValidationSummary()
</div>
}
</div>
<div>
<h3>Current Inventory:</h3>
</div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th style="width: 15%;">Checkout Number</th>
<th style="width: 15%;">Title</th>
<th style="width: 23%;">Availability</th>
<th style="width: 17%;"></th>
</tr>
</thead>
<tbody>
#foreach (var vm in Model.InventoryList.OrderBy(m => m.CheckoutNum))
{
<tr>
<td>#vm.CheckoutNum</td>
<td>#vm.Movies.Title</td>
<td>#vm.isAvail</td>
<td>
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="4">
#Html.Pager(Model.InventoryList.PageSize, Model.InventoryList.PageNumber, Model.InventoryList.TotalItemCount).Options(o => o
.DisplayTemplate("BootstrapPagination").RouteValues(new { q = ViewBag.Query, area = "" } )
.AlwaysAddFirstPageNumber().MaxNrOfPages(5))
</td>
</tr>
</tfoot>
</table>
I figured it out. I was setting the defaultPageSize in the wrong constructor, so the variable was never getting set, causing the page size to be 0.
int defaultPageSize;
private IInventoryRepository inventoryRepository;
public InventoryController()
{
this.inventoryRepository = new InventoryRepository(new MovieContext());
this.defaultPageSize = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["defaultPageSize"]);
}
public InventoryController(IInventoryRepository inventoryRepository)
{
this.inventoryRepository = inventoryRepository;
this.defaultPageSize = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["defaultPageSize"]);
}

Resources