MVC 3 - System.byte[] output instead of showing image - asp.net-mvc

I complete index.cshtml file looks like this...
#model IEnumerable<MvcMyApplication.Models.SubProductCategory2>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.ActionLink("Create New", "Create")
<p>
some javascripts code
</p>
<input type="text" name="search" id="search" style="color: #F5FFFA;
font-family: Constantia, Georgia, serif; font-weight: bold; font-size:
14px; background-color: #D2691E;" size="15" />
<table id="admin_table">
<thead>
<tr>
<th></th>
<th>
CategoryName
</th>
<th>
SubCategoryName
</th>
<th>
Picture
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.ActionLink("Edit", "Edit", new {
id=item.SubProductCategoryID }) |
#Html.ActionLink("Delete", "Delete", new {
id=item.SubProductCategoryID })
</td>
<td>
#item.ProductCategory.CategoryName
</td>
<td>
#item.SubCategoryName
</td>
<td>
<img alt="#Html.Encode(item.SubProductCategoryID)"
src='#(Url.Action(("Image")) + item.SubProductCategoryID)'
width="100" height="100" />
</td>
</tr>
}
Complelte Create.cshtml file looks this...
enter code here
#model MvcMyApplication.Models.ProCat1
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"
type="text/javascript"></script>
<script src="#Url.Content("~/Scripts
/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("Create", "ProductCategoryL2", FormMethod.Post,
new { enctype = "multipart/form-data"}))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>ProCat1</legend>
<div class="editor-label">
#Html.LabelFor(model => model.CategoryName)
</div>
<div class="editor-field">
#Html.DropDownList("ProductCategoryID",
(IEnumerable<SelectListItem>)ViewData["CategoryName"])
#Html.ValidationMessageFor(model => model.CategoryName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SubCategoryName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SubCategoryName)
#Html.ValidationMessageFor(model => model.SubCategoryName)
</div>
<!-- <div class="editor-field">
<img alt="Current image" src='#Url.Action("image", new { id =
Model.SubProductCategoryID } )' />
<input type="file" id="fileUpload" name="fileUpload" size="23"/>
#Html.ValidationMessageFor(model => model.SubProductCategoryID)
</div> -->
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Controller for Create and Image looks like this...
enter code here
public ActionResult Create()
{
PopulateProductCategoryDropDownList(-1);
return View();
}
private void PopulateProductCategoryDropDownList(object selectedCategory)
{
ViewBag.CategoryName = new SelectList ((from d in db.ProductCategories select d).ToList(),
"ProductCategoryID", "CategoryName", selectedCategory);
}
//
// POST: /ProductCategoryL2/Create
[HttpPost]
public ActionResult Create([Bind(Exclude = "SubProductCategoryID")] SubProductCategory2 Createsubcat2, FormCollection values)
{
if (ModelState.IsValid)
{
if (Request.Files.Count > 0)
{
Createsubcat2.Picture1 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[0]);
}
db.AddToSubProductCategory2(Createsubcat2);
db.SaveChanges();
return RedirectToAction("/");
}
PopulateProductCategoryDropDownList(Createsubcat2.ProductCategoryID);
return View(Createsubcat2);
}
public FileResult Image(int id)
{
const string alternativePicturePath = #"/Content/question_mark.jpg";
SubProductCategory2 product = db.SubProductCategory2.Where(k => k.SubProductCategoryID == id).FirstOrDefault();
MemoryStream stream;
if (product != null && product.Picture1 != null)
{
stream = new MemoryStream(product.Picture1);
}
else // If product cannot be found or product doesn't have a picture
{
stream = new MemoryStream();
var path = Server.MapPath(alternativePicturePath);
var image = new System.Drawing.Bitmap(path);
image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
stream.Seek(0, SeekOrigin.Begin);
}
return new FileStreamResult(stream, "image/jpeg");
}
FileHandler class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
public class FileHandler
{
/// <summary>
/// Converts a HttpPostedFileBase into a byte array
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public byte[] uploadedFileToByteArray(HttpPostedFileBase file)
{
int nFileLen = file.ContentLength;
byte[] result = new byte[nFileLen];
file.InputStream.Read(result, 0, nFileLen);
return result;
}
}
}
Thanks tvanfosson.

Your URL is totally wrong; you want to call Url.Action with an action name and a parameter.
Your alt text is also wrong; you're effectively calling ToString() on a byte array, which returns "System.Byte[]".
Since your incorrectly generated URL doesn't exist, it's showing the incorrect alt text instead.

If Picture1 is image data, #Html.EditorFor(model => model.Picture1) isn't what you want. You probably want to call the Image action to display the picture inline.
...code sample coming
<div class="editor-field">
<img alt="Current image" src='#Url.Action("image", new { id = Model.PictureID } )' />
<input type="file" id="fileUpload" name="fileUpload" size="23"/>
#Html.ValidationMessageFor(model => model.PictureID)
</div>
Then change the create GET method so that it populates the PictureID instead of the Picture on the model.

Related

ASP.NET MVC Send List from View to controller

I'm trying to create a product model with ID,Name and a list of specifications like above:
My model:
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public virtual List<Spec> Specifications { get; set; }
}
public class Spec
{
public int SpecID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
My Controller:
public ActionResult Create(Product product,List<Spec> Specifications)
{
......
}
My View:
using (Html.BeginForm("Create", "Products", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Product</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-2"><h3>Specifications</h3></div>
<div class="col-md-10">
<table id="tblSkills" cellpadding="0" cellspacing="0" class="table table-responsive">
<thead>
<tr>
<th style="width:150px">Name</th>
<th style="width:150px">Description</th>
<th></th>
</tr>
</thead>
<tbody></tbody>
<tfoot>
<tr>
<td><input type="text" id="Name1" /></td>
<td><input type="text" id="Description" /></td>
<td>
<input type="button" id="btnAdd" class="btn btn-success btn-sm" value="Add" />
</td>
</tr>
</tfoot>
</table>
<br />
<input type="button" id="btnSave" value="SaveAll" class="bntbtn-block btn-success" />
<br />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
so it should looks like this:
I also added some Scripts so that I can enter or remove specifications, the information will be displayed inside a tbody tag in a table.
The problem is that I don't really know how to pass my list of specifications to my controller, or should I try another way of input multiple specifications instead of using table. I'm looking for a way to input it using HTMLHelper like the one I did with Product's Name.
I apologize if my question is unclear. If you have any question to understand more, feel free to ask me. Thanks for any advise or solution.
To pass the model to a view from controller you need to:
public ActionResult Create(List<Spec> Specifications)
{
return View(Specifications);
}
and in your view add these to on top of the view:
#using PathOfYourSpecificationsModel
#model List<Spec>
using (Html.BeginForm("Create", "Products", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Product</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-2"><h3>Specifications</h3></div>
<div class="col-md-10">
<table id="tblSkills" cellpadding="0" cellspacing="0" class="table table-responsive">
<thead>
<tr>
<th style="width:150px">Name</th>
<th style="width:150px">Description</th>
<th></th>
</tr>
</thead>
<tbody></tbody>
<tfoot>
<tr>
<td><input type="text" id="Name1" /></td>
<td><input type="text" id="Description" /></td>
<td>
<input type="button" id="btnAdd" class="btn btn-success btn-sm" value="Add" />
</td>
</tr>
</tfoot>
</table>
<br />
<input type="button" id="btnSave" value="SaveAll" class="bntbtn-block btn-success" />
<br />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
After user clicks add button you need another [HttpPost] method for Create. Which should look like this:
[HttpPost]
public ActionResult Create(List<Spec> Specifications)
{
// Specifications should be filled with view values.
// Do your logic here. Ex: Save the data to database
}
For adding dynamic control fields, it is advised to use helper methods.
The AddNewRow helper method will return the html elements can one can make changes like changing the html attributes.
the html attributes should be unique and it is advised to use increment value for each element.
the attributes of html elements returned from helper method are changed in addNewRow() of javascript function.
Detailed steps are provided below.
In Product Model
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public List<Spec> Specifications { get; set; }
}
public class Spec
{
public int SpecID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsRemoved { get; set; }
}
In Controller
public class ProductController : Controller
{
// GET: Product
public ActionResult AddProduct()
{
Product product = new Product();
product.Specifications = new List<Spec>()
{
new Spec()
};
return View(product);
}
[HttpPost]
public ActionResult AddProduct(Product product)
{
return View(product);
}
}
In AddProduct.cshtml
#model Product
#using WebApplication3.Models
#{
ViewBag.Title = "AddProduct";
}
#helper AddNewRow()
{
<tr id="trRow_0">
<td>
#Html.HiddenFor(x => Model.Specifications[0].IsRemoved, new { id = "hdnSpecIsRemoved_0" })
#Html.TextBoxFor(x => Model.Specifications[0].Name, new { id = "txtSpecName_0" })
</td>
<td>
#Html.TextBoxFor(x => Model.Specifications[0].Description, new { id = "txtSpecDesc_0" })
</td>
<td>
Remove Row
</td>
</tr>
}
<h2>AddProduct</h2>
#using (Html.BeginForm("AddProduct", "Product", FormMethod.Post))
{
<div>
#Html.LabelFor(x => x.Name)
#Html.TextBoxFor(x => x.Name)
</div>
<table>
<thead>
<tr>
<th>
#Html.LabelFor(x => x.Specifications[0].Name)
</th>
<th>
#Html.LabelFor(x => x.Specifications[0].Description)
</th>
<th>
Action
</th>
</tr>
</thead>
<tbody id="tBody">
#for (int i = 0; i < Model.Specifications.Count; i++)
{
string trRow = "trRow_" + i;
<tr id="#trRow">
<td>
#Html.HiddenFor(x => Model.Specifications[i].IsRemoved, new { id = "hdnSpecIsRemoved_" + i })
#Html.TextBoxFor(x => Model.Specifications[i].Name, new { id = "txtSpecName_" + i })
</td>
<td>
#Html.TextBoxFor(x => Model.Specifications[i].Description, new { id = "txtSpecDesc_" + i })
</td>
<td>
Remove Row
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="2">
<br />
<button type="button" onclick="addNewRow()">Add New Row</button>
</td>
</tr>
</tfoot>
</table>
<br />
<button type="submit">Save All</button>
}
<script type="text/javascript">
function addNewRow() {
var totalSpecCount = $('#tBody tr').length;
var newRowData = `#(AddNewRow())`;
newRowData = newRowData.replaceAll("Specifications[0]", "Specifications[" + totalSpecCount + "]")
newRowData = newRowData.replaceAll("txtSpecName_0", "txtSpecName_" + totalSpecCount);
newRowData = newRowData.replaceAll("txtSpecDesc_0", "txtSpecDesc_" + totalSpecCount);
newRowData = newRowData.replaceAll("trRow_0", "trRow_" + totalSpecCount);
newRowData = newRowData.replaceAll("removeRow(0)", "removeRow(" + totalSpecCount+")");
newRowData = newRowData.replaceAll("hdnSpecIsRemoved_0", "hdnSpecIsRemoved_" + totalSpecCount);
$('#tBody').append(newRowData);
}
function removeRow(recordId) {
var trId = "#trRow_" + recordId;
var hdnSpec = "#hdnSpecIsRemoved_" + recordId;
$(hdnSpec).val(true);
$(trId).hide();
}
</script>
Here, the method addNewRow will call the helper methods and change the html attributes of the element based on row count.
In strongly typed view, the index values should unique for the list so that it can be posted using model binding
Final Result
Note: In remove row method we have to hide the element instead of removing the element completely. This is used to achieve post the list directly. To know what the rows that are removed a flag called IsRemoved is to true.
If we remove the element, the index value will not be in sequence and one cannot post the form.

How to Solve this error when I m uploading image in MVC?

I m working with MVC with SQL server management studio?
Error: No parameterless constructor defined for this object
I won't know what is the error?
I change in 3 places
1.Index.cshtml
2.create.cshtml
3.CrudManuallyController.cs
public string Image { get; set; } varchar(50)
CrudManually Controller:
public class CrudManuallyController : Controller
{
public ActionResult Create()
{
return View();
}
// POST: CrudManually/Create
[HttpPost]
public ActionResult Create(manage manages,HttpPostedFileBase image)
{
try
{
var folderPath = Server.MapPath("~/Images/");
image.SaveAs(Path.Combine("~/Images/", image.FileName));
manages.Image = Path.Combine("~/Images/", image.FileName);
// TODO: Add insert logic here
db.manages.Add(manages);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View(manages);
}
}
}
create.cshtml
<h2>Create</h2>
#using (Html.BeginForm("Create", "CrudManually", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="editor-label">
#Html.LabelFor(model => model.Image)
</div>
<div class="editor-field">
<input id="Image" title="Image Uploading" type="file" name="image" />
</div>
}
Index.cshtml
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Image)
</th>
</tr>
<tr>
#foreach (var item in Model)
{
<td>
<img src="#Url.Content(item.Image)" alt="Image not display" width="20%" height="20%" />
</td>
}
</tr>
</table>
Image:
enter image description here
How to solve this error?
I won't know what is the error?
any code adds in my program and runs my image uploading successfully What Can I DO?
Image1:
enter image description here
Controller Code
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(manages manages, HttpPostedFileBase image)
{
try
{
if (image != null)
{
//using System.IO;
var folderPath = Server.MapPath("~/Images/");
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
//Path.Combine for concate folder path and image name together
var imagePathName = Path.Combine(folderPath, image.FileName);
image.SaveAs(imagePathName);
manages.Image = image.FileName;
//TODO: Add insert logic here
//db.manages.Add(manages);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View(manages);
}
}
create.cshtml code
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="editor-label">
Image
</div>
<div class="editor-field">
<input id="Image" title="Image Uploading" type="file" name="image" />
</div>
<input type="submit" value="button" />
}
Index.cshtml
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Image)
</th>
</tr>
<tr>
#foreach (var item in Model)
{
<td>
<img src="#Url.Content('~/Images/' + item.Image)" alt="Image not display" width="20%" height="20%" />
</td>
}
</tr>
</table>
CrudManually Controller
//replace HttpPostedFile with HttpPostedFileBase object
//please add server.Mappath function into code for exact foler structure to save file
public class CrudManuallyController : Controller
{
public ActionResult Create()
{
return View();
}
// POST: CrudManually/Create
[HttpPost]
public ActionResult Create(manage manages,HttpPostedFileBase image)
{
try
{
var folderPath = Server.MapPath("~/Images/");
image.SaveAs(Path.Combine(folderPath, image.FileName));
manages.Image= Path.Combine(folderPath, image.FileName);
// TODO: Add insert logic here
db.manages.Add(manages);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View(manages);
}
}
}
create.cshtml
//encytype is wrong please replace it with enctype
//input file name="file" so it will not set on controller side as its name on controller side is 'image', so you need to repalce name='file' with name='image'
<h2>Create</h2>
#using (Html.BeginForm("Create", "CrudManually", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="editor-label">
#Html.LabelFor(model => model.Image)
</div>
<div class="editor-field">
<input id="Image" title="Image Uploading" type="file" name="image" />
</div>
}
Index.cshtml
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Image)
</th>
</tr>
<tr>
#foreach (var item in Model)
{
<td>
<img src="#Url.Content('~/Images/' + item.Image)" alt="Image not display" width="20%" height="20%" />
</td>
}
</tr>
</table>
Explaination :
ASP.NET C# MVC provides the facility of HttpPostedFileBase class is an abstract class that contains the same members as the HttpPostedFile class. so we can use this abstract class while work with uploading file onto server.
Step 1: For that, we need to use input type of file with name attribute.
Step 2: Form must be POST with enctype = "multipart/form-data"
Step 3: On the controller side we need to get HttpPostedFileBase object value with the same name which we already gave to input file type
public ActionResult Create(manage manages,HttpPostedFileBase image)
Step 4: After follow all the steps on Form post you will get the value of file in the image object of type HttpPostedFileBase and then you need to check the nullable condition and simply code foe save the file.
var virtualPath = StaticValues.AdvertisementImagePath;
var physicalPath = Server.MapPath(virtualPath);
Utilities.SaveFile(fileObject, virtualPath, physicalPath, "FILE PATH");

Model Binding is not working, parameter "model" is showing null in the Create Method while debugging [duplicate]

I am just trying to learn MVC and facing some issues.When I am submitting my partial view, I am getting null in Model Blog inside Create Method.
What I am doing wrong and what is the right approach?
View(Index.cshtml)
#model IEnumerable<Samples.Controllers.Blog>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>Sample</th>
<th>URL</th>
<th>Name</th>
</tr>
#foreach (var item in Model) {
<tr>
<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>
<td>
#item.URL
</td>
<td>
#item.Name
</td>
</tr>
}
</table>
#Html.Partial("_CreateBlog", new Samples.Controllers.Blog())
Partial View(_CreateBlog.cshtml)
#model Samples.Controllers.Blog
#using (Html.BeginForm("Create","Sample",FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Blog</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
#Html.LabelFor(model => model.URL)
#Html.EditorFor(model => model.URL)
</div>
<div class="row">
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
SampleController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Samples.Controllers
{
public class SampleController : Controller
{
List<Blog> lstBlogs;
public SampleController()
{
lstBlogs = new List<Blog>
{
new Blog{ Name="Domnic", URL= "www.google.com"},
new Blog{ Name="Tom", URL= "www.YAHOO.com"},
new Blog{ Name="Cat", URL= "www.facebook.com"},
new Blog{ Name="Bob", URL= "www.twitter.com"}
};
}
// GET: Sample
public ActionResult Index()
{
return View(lstBlogs);
}
public ActionResult IndexWithDynamicView()
{
return View(lstBlogs);
}
[HttpPost]
public void Create(Blog blog)
{
}
}
public class Blog
{
public string Name;
public string URL;
}
}
Your class Blog only contains fields, not properties so the DefaultModelBinder cannot set their values. Change it add getters/setters
public class Blog
{
public string Name { get; set; }
public string URL { get; set; }
}
Maybe this answer relates to your question: Is there a reason why the default modelbinder doesn't bind to fields?
Pay attention at DefaultModelBinder, ModelBinderContext, ModelMetadata. This explains it all.

Mvc 5 pagination using view model

Hi i am newbie to Mvc i have a json service which returns a list of walletstatementlogs based on fromdate and todate. I have a controller TopUpReqLogController every time when i hit the action index of the controller it will go to service and fetch the data and returns to view as Ipagedlist and genrates pagelinks. How do i prevent servicecall everytime in TopUpReqLogController index action i just want to load service data once and pass it to index and display data in pages using int ? page please suggest
public class WalletTopUpRequest
{
public string SlNo { get; set; }
public string Sequence { get; set; }
public string Merchant { get; set; }
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
public string BankName { get; set; }
public string TransactionDate { get; set; }
public string Reference { get; set; }
public string Amount { get; set; }
public string ApprovalStatus { get; set; }
public string ApproveUser { get; set; }
public string ApprovalDate { get; set; }
public string RemarKs { get; set; }
}
public ViewResult Index(int? page)
{
int pageSize = 3;
int pageNumber = (page ?? 1);
List<WalletTopUpRequest> wallettoprq = new List<WalletTopUpRequest>();
if (page == null)
{
AgentBusiness business = new AgentBusiness();
var result = business.Topuprequestlog("99910011010", "99810001110", "jBurFDoD1UpNPzWd/BlK4hVpV8GF+0eQT+AfNxEHHDKMB25AHf6CVA==", "25052017000000", "01062017000000");
wallettoprq = result.wallettopuprequest.ToList();
var viewmodel = wallettoprq.ToPagedList(pageNumber, pageSize);
return View(viewmodel);
}
return View(wallettoprq.ToPagedList(pageNumber, pageSize));
}
#using PagedList;
#using PagedList.Mvc;
#model IPagedList<HaalMeer.MVC.Client.Models.WalletTopUpRequest>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<html>
<head>
</head>
<body>
<div id="page-wrapper">
<div class="page-title-container">
#*<div class="container-fluid">*#
<div class="page-title pull-left">
<h2 class="entry-title">Topup Request Log</h2>
</div>
<ul class="breadcrumbs pull-right">
<li>Home</li>
<li class="active">Topup Request Log</li>
</ul>
</div>
</div>
<section id="content" class="gray-area">
<div class="container">
<div class="row">
<div class="col-md-3">
</div>
#using (Html.BeginForm("Index", "TopUpReqLog", FormMethod.Get))
{
<div class="col-md-3">
<div class="form-group">
<label>From Date</label>
<div class="datepicker-wrap blue">
#*<input type="text" name="date_from" class="input-text full-width" placeholder="mm/dd/yy" style="background-color: #fff" />*#
#Html.TextBox("Fromdate", ViewBag.fromdate as string, new { #class = "input-text full-width", #placeholder = "mm/dd/yyy",#style = "background-color: #fff" }) <br />
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label>To Date</label>
<div class="datepicker-wrap blue">
#*<input type="text" name="date_from" class="input-text full-width" placeholder="mm/dd/yy" style="background-color: #fff" />*#
#Html.TextBox("Todate", ViewBag.todate as string, new { #class = "input-text full-width", #placeholder = "mm/dd/yyy", #style = "background-color: #fff" }) <br />
</div>
</div>
<button type="submit">Submit</button>
</div>
}
<div class="col-md-3">
</div>
</div>
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="table-responsive">
<table class="table">
<tr class="info" style="text-align: center; font-weight: bold; color: #000">
<td class="col-md-1">Sl</td>
<td class="col-md-2">Date</td>
<td class="col-md-1">Bank Ref.</td>
<td class="col-md-1">Bank Name</td>
<td class="col-md-2">Remarks</td>
<td class="col-md-1">Amount</td>
<td class="col-md-1">Status</td>
<td class="col-md-2">Action Date</td>
</tr>
#foreach (var item in Model)
{
<tr>
<td class="hmcenter">#Html.DisplayFor(modelItem => item.SlNo)</td>
<td class="hmcenter">#Html.DisplayFor(modelItem => item.TransactionDate)</td>
<td class="hmcenter">#Html.DisplayFor(modelItem => item.Reference)</td>
<td class="hmcenter">#Html.DisplayFor(modelItem => item.BankName)</td>
<td class="hmleft">#Html.DisplayFor(modelItem => item.RemarKs)</td>
<td class="hmright">#Html.DisplayFor(modelItem => item.Amount) </td>
<td class="hmcenter">#Html.DisplayFor(modelItem => item.ApprovalStatus)</td>
<td class="hmcenter">#Html.DisplayFor(modelItem => item.ApprovalDate)</td>
</tr>
}
</table>
<br/>
Page #(Model.PageCount<Model.PageNumber? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",new { page
}))
#*<div class="form-group">
<ul class="pagination">
<li>1</li>
<li class="active">2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>*#
</div>
</div>
</div>
</div>
</section>
So, from what I understand you want just make it work only on client side. If your model is not empty this code should work. If you want to load data as one result and make pagination on client side, then IPageList is not what you are looking for. Because, it is used only on the server side, and always returns ONE page of data to brake large results. You also can try to pass list of data to the view and turn it to IPageList result in the view and display each
page in tab, but is not a good practice. I would use datatables in this situation to make pagination only on the client side using regular data list:
https://datatables.net/.
Hint to improve current code:
Controller:
public ViewResult Index(int? page = 1)
{
AgentBusiness business = new AgentBusiness();
var result = business.Topuprequestlog("99910011010", "99810001110", "jBurFDoD1UpNPzWd/BlK4hVpV8GF+0eQT+AfNxEHHDKMB25AHf6CVA==", "25052017000000", "01062017000000");
return View(result.wallettopuprequest.ToPagedList(pageNumber, 3));
}
View:
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }), PagedListRenderOptions.ClassicPlusFirstAndLast)
Below example shows the paging to be done at server side and Client Side :
Here is my Model :
public partial class Employee
{
public int Id { get; set; }
public string FName { get; set; }
public string Lname { get; set; }
}
Action:
public ActionResult Index(int? Page)
{
return View();
}
/// returns Partial View
public ActionResult _PartialIndex(int? Page)
{
return PartialView(db.Employees.ToList().ToPagedList(Page ?? 1, 10));
}
Views :
1.Index View :Index.cshtml
#{
ViewBag.Title = "Index";
}
<script src="https://cdn.jsdelivr.net/jquery.ajax.unobtrusive/3.2.4/jquery.unobtrusive-ajax.min.js"></script>
<script>
$(document).ready(function () {
$('#loading').show();
debugger;
var Page = '';
$.ajax({
url: '/Employees/_PartialIndex',
contentType: "application/json; charset=utf-8",
type: 'get',
datatype: 'html'
}).success(function (result) {
$('#main').html(result);
$('#loading').hide();
});
});
</script>
<h2>Index</h2>
<div class="col-md-8 col-md-offset-2">
<center>
<div id="loading" style="display:none; z-index:200; position:absolute; top:50%; left:45%;">
<img src="~/Content/loading.gif" />
</div>
</center>
<div id="main">
</div>
</div>
2.Partial View :_PartialIndex.cshtml
#using PagedList.Mvc
#using PagedList;
#model IPagedList<samplePaging.Models.Employee>
#{
ViewBag.Title = "Index";
}
<h2>Employee List</h2>
<table class="table">
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Lname)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</table>
<center>
#Html.PagedListPager(Model, page => Url.Action("_PartialIndex", new { page }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new PagedListRenderOptions() { DisplayPageCountAndCurrentLocation = true }, new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "main", LoadingElementId = "loading" }))
</center>
If you want to do the paging at client side then follow below steps:
Action:
public ActionResult JsonIndex(int? Page)
{
return Json(db.Employees.ToList(), JsonRequestBehavior.AllowGet);
}
View:
#{
ViewBag.Title = "Index2";
}
<h2>Index2</h2>
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css">
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
//Call EmpDetails jsonResult Method
$.getJSON("/Employees/JsonIndex",
function (json) {
var tr;
//Append each row to html table
for (var i = 0; i < json.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + json[i].FName + "</td>");
tr.append("<td>" + json[i].LName + "</td>");
$('table').append(tr);
}
$('#EmpInfo').DataTable();
});
});
</script>
<hr />
<div class="form-horizontal">
<table id="EmpInfo" class="table table-bordered table-hover">
<thead>
<tr>
<th>Fname</th>
<th>LName</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
Hope this help you !

How to call a method from the View? MVC

I have a View with a <input type="submit" value="Create" /> when a User click create the Action Method should be activated and the Result written in the db.
At the moment when a User click Create Button in the View nothing happen. Could you tell me what I'm doing wrong? thanks
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestGuestBook.Models;
using TestGuestBook.Models.Repositories;
using TestGuestBook.ViewModels;
namespace TestGuestBook.Controllers
{
[HandleError]
public class HomeController : Controller
{
ICommentRepository _repository;
public HomeController()
{
_repository = new CommentRepository();
}
// Dependency Injection enabled constructors
public HomeController(ICommentRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
// Get all Comments
List<Comment> commentItems = _repository.FindAll().ToList();
// Create the ViewModel and associate the list of comments
CommentListCreateViewModel viewModel = new CommentListCreateViewModel();
viewModel.CommentItems = commentItems;
return View(viewModel);
}
public ActionResult Create()
{
CommentListCreateViewModel createViewModel = new CommentListCreateViewModel();
return View(createViewModel);
}
[HttpPost]
public ActionResult Create(CommentListCreateViewModel createViewModel)
{
if (ModelState.IsValid)
{
Comment comment = new Comment
{
Nominative = createViewModel.Nominative,
Email = createViewModel.Email,
Content = createViewModel.Content
};
_repository.Add(comment);
_repository.Save();
}
return View();
}
}
}
View
#model TestGuestBook.ViewModels.CommentListCreateViewModel
#{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>ListAddCommentsViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Nominative)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Nominative)
#Html.ValidationMessageFor(model => model.Nominative)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Content)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Content)
#Html.ValidationMessageFor(model => model.Content)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<table>
<tr>
<th>
Nominative
</th>
<th>
Email
</th>
<th>
Content
</th>
<th>
</th>
</tr>
#foreach (var item in Model.CommentItems)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Nominative)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Content)
</td>
<td>
</td>
</tr>
}
</table>
You need to direct the form to your Create controller method:
#using (Html.BeginForm("Create", "Home"))
You can leave it as Html.BeginForm() and after the save, call return RedirectToAction("Index"); The added item should now show in the list. It was probably saving all along, it just wasn't being re-directed to the Index view afterwards.

Resources