Asp.net MVC pass input value from view to controller - asp.net-mvc

I've never worked with both asp.net and mvc.
I need to create simple registration form but I can't pass value from input to controller. I'm not using model and if I just could get values from view to controller there is server side function in my controller which will add inputs to database.
I searched a lot but there is always answers with using razor and html.beginform etc. and I don't have any of them.
Here is my view:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Main.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<table width="100%">
<tbody>
<tr>
<td valign="top" style="width:300px">
<fieldset>
<legend><b>Registration</b></legend>
<table class="submit">
<tr>
<td>Customer Code:</td>
<td style="width: 50%">
<%: Html.TextBox("cbCode")%>
</td>
</tr>
<tr>
<td>Card No:</td>
<td>
<%: Html.TextBox("cardNo")%>
</td>
</tr>
<tr>
<td>E-Code:</td>
<td>
<%: Html.TextBox("pswrd")%>
</td>
</tr>
<tr>
<td>E-Token:</td>
<td>
<%: Html.TextBox("tokenId")%>
</td>
</tr>
<tr>
<td>
<button type="submit" onclick="tokenSubmit('POST');" class="btn">
Submit</button>
</td>
</tr>
</table>
</fieldset>
<legend><b>Result</b></legend>
<div id="Result">
</div>
</fieldset>
</td>
</tr>
</tbody>
</table>
</asp:Content>
My controller:
namespace Branch.Controllers
{
public class CardEcodeController : Controller
{
//
// GET: /CardEcode/
public ActionResult Index()
{
long cbCode = value from input;
long cardNo = value from input;
long tokenId = value from input;
long pswrd = value from input;
//using functions written in server side
RegisterClient reg = new RegisterClient();
reg.InsertToken(cbCode,cardNo,tokenId,pswrd);
return View();
}
}
}
I think my MVC version is 2 or 3.

I strongly recommend you to read up on working with MVC. The version you are using is MVC2 most likely. If you can I would do the project in MVC3 or MVC4 to use Razor syntax. The quick answer to your question is this.
<%using (Html.BeginForm("Index", "CardEcode", FormMethod.Post)){%>
<table width="100%">
<!-- table code here -->
</table>
<% } %>
For your controller you have to make a post action.
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(long cbCode, long cardNo, long tokenId, long pswrd)
{
//using functions written in server side
RegisterClient reg = new RegisterClient();
reg.InsertToken(cbCode,cardNo,tokenId,pswrd);
return View();
}

Related

Pass table Object from view to controller using asp.net mvc

I am new to ASP.net MVC still in learning stage :) Thank you Advance
I have created the View Model to populate the table data based on the PName which I have selected.
Ex: for 1 project we have 10 related Items in , i am displaying all the rows on the screen, and making some updates to those rows to save it back to Database.
I am able to get the data but when I am trying to send the table object to controller to save, it always giving me null
Here is my ViewModel
namespace Application.ViewModel.Projects
{
public class PUpdates
{
public List<FItems> items{ get; set; }
}
}
CSHTML code
#using (Html.BeginForm("PFItems", "Projects", FormMethod.Post))
{
<table id="test">
<tr id="testtr">
<th id="testth"></th>
<th id="testth"></th>
</tr>
#foreach (var item in Model.FItems)
{
<tr id="testtr">
<td id="testtd">
#Html.Label(item.Ftype)
</td>
<td id="testtd">
#Html.TextBox("test", item.AC)
</td>
</tr>
}
<tr> <td><input type="submit" value="Submit" /></td></tr>
</table>
}
Controller Code
[HttpPost]
public PartialViewResult PFItems(PFUviewmodel)
{
return PartialView(viewmodel);
}
I am not able to get my table Object to make the update
Welcome to Stack overflow :)
For model binding to work you need to give you fields an index in the name property. Have a look at this question where I answered a very similar question and explained it.
In your case you need to do something like the following:
#model Application.ViewModel.Projects.ProjectfinanceUpdate
#using (Html.BeginForm("PartialprojectFinanceItem", "Projects", FormMethod.Post))
{
<table id="test">
<tr id="testtr">
<th id="testth">Financial Type</th>
<th id="testth">Actual Cost</th>
</tr>
#var i =0;
#foreach (var item in Model.tblFinanceItems)
{
<tr id="testtr">
<td id="testtd">
#Html.Label(item.FinancialType)
</td>
<td id="testtd">
<input name="ProjectfinanceUpdate.tblFinanceItems[#i].ActualCost" value="#item.ActualCost"/>
</td>
</tr>
#i++;
}
<tr> <td><input type="submit" value="Submit" /></td></tr>
</table>
}
The important part is that model binding works off of the name property, and because it's a list, it needs to have an index property.
Hope that helps.

Issue with mvc, partial view dispaying

I have a question about partial view. I want to display in header Login form which i created. In HomeController I have 2 actions: one is Login and other is Login with httppost method.
In partial view (_Layout.cshtml) I have a code - only send footer div:
<td style="text-align:center">
<h3>Bookstore</h3>
#Html.Partial("_LoginPartial")
</td>
In Login view I have:
#using(Html.BeginForm("Login", "Home", FormMethod.Post)){
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<table>
<tr>
<td>#Html.LabelFor(a=>a.Username)</td>
<td>#Html.TextBoxFor(a=>a.Username)</td>
<td>#Html.ValidationMessageFor(a=>a.Username)</td>
</tr>
<tr>
<td>#Html.LabelFor(a=>a.Password)</td>
<td>#Html.PasswordFor(a=>a.Password)</td>
<td>#Html.ValidationMessageFor(a=>a.Password)</td>
</tr>
<tr>
<td>
<input type="submit" value="Login" />
</td>
</tr>
</table>}
Controller
public ActionResult Login()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Users u)
{
if (ModelState.IsValid) {
using (DatabaseLoginEntities dl = new DatabaseLoginEntities()) {
var v = dl.Users.Where(a => a.Username.Equals(u.Username) && a.Password.Equals(u.Password)).FirstOrDefault();
if (v != null) {
Session["LogedUserId"] = v.UserAccountID.ToString();
Session["LogedUserFullName"] = v.FullName.ToString();
return RedirectToAction("AfterLogin");
}
}
}
return PartialView("_LoginPartial", u);
}
When press Login button, mvc switches me to separate page in which Login form is shown. I don't want that to happen. It must stay in header. Functionality is ok but I have issue how to show that only in header. Has anyone have idea where I'm wrong?
you must use ajax
#using (Ajax.BeginForm("Login", "Home",
new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace
,
UpdateTargetId = "div_id"
}
)){
<table>
<tr>
<td>#Html.LabelFor(a=>a.Username)</td>
<td>#Html.TextBoxFor(a=>a.Username)</td>
<td>#Html.ValidationMessageFor(a=>a.Username)</td>
</tr>
<tr>
<td>#Html.LabelFor(a=>a.Password)</td>
<td>#Html.PasswordFor(a=>a.Password)</td>
<td>#Html.ValidationMessageFor(a=>a.Password)</td>
</tr>
<tr>
<td>
<input type="submit" value="Login" />
</td>
</tr>
</table>
}

C# MVC4 Partial View with other ActionResult in Controller

i have a problem.
I have my Controller "DashboardNB2Controller", my View "index.cshtml" and i want to integrate a partial view called "_PartialView.cshtml" in my "index.cshtml". Both Views are in the same folder. In my controller, i have the "ActionResult _PartialView" for a databaseoperation in my partial view.
But if I integrate my partial view in my index view, the action result "_PartialView" didn't work. I get no results. The query for my database is correct. I checked this.
Here are my codes
My Controller with the ActionResult for the Partial View
public ActionResult _PartialView()
{
var lastMessages= (from t in db.view_tbl_message
orderby t.Date descending
select t).Take(10);
ViewModelDashboard model = new ViewModelDashboard();
model.view_tbl_message = lastMessages.ToList();
return PartialView("_PartialView", model);
}
My index.cshtml
#model AisWebController.Areas.Statistics.Models.ViewModelDashboard
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
#{Html.Action("_PartialView", "DashboardNB2");}
<br />
And my _PartialView.cshtml
#model WebApplication.Areas.Stats.Models.ViewModelDashboard
<table class="table table-bordered">
<tr>
<th>
Date
</th>
<th>
User
</th>
<th>
Message
</th>
</tr>
#foreach (var item in Model.view_tbl_message)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Date
</td>
<td>
#Html.DisplayFor(modelItem => item.User)
</td>
<td>
#Html.DisplayFor(modelItem => item.Message)
</td>
</tr>
}
</table>
If someone can help - that would be aweseome!
Change
#{Html.Action("_PartialView", "DashboardNB2");}
to
#Html.Action("_PartialView", "DashboardNB2")
You don't need {} brackets after you have # in view for Html extension methods
Look your #Html.DisplayFor it doesn't have any {} brackets.
Same applies for #Html.ActionLink

MVC file uploader returns a null

I am basing my solution on this article;
http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-and-File-Uploads.aspx
However when I try to upload a picture I get a null instead of a filename.
My view looks like this;
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SHP.Models.HrViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Edit Employee
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<fieldset>
<legend>Add details to the selected employee</legend>
<p>The photo you select for an employee will appear on MNet.</p>
<p>The qualifications you add for an employee will appear on their business cards when required.</p>
<% using (Html.BeginForm("EditEmployee", "HumanResources", FormMethod.Post,
new{enctype = "multipart/form-data"}))
{%>
<%: Html.AntiForgeryToken() %>
<%: Html.ValidationSummary(true) %>
<%: Html.EditorFor(model => model.EmployeeSelector) %>
<% if (Model.SelectedEmployee != null)
{ %>
<%: Html.HiddenFor(model => model.SelectedEmployee.EmployeeId) %>
<%: Html.HiddenFor(model => model.EmployeeName) %>
<table class="groupBorder" style="margin-top:15px; width:617px;">
<tbody>
<tr>
<th colspan="2">Add Details for <%: Model.EmployeeName %></th>
</tr>
<tr>
<td style="text-align: right;">
<%: Html.LabelFor(model => model.SelectedEmployee.Photo)%>
</td>
<td>
<input type="file" id="Picture" name="Picture" />
</td>
</tr>
<tr>
<td style="text-align: right;">
<%: Html.LabelFor(model => model.SelectedEmployee.Qualifications)%>
</td>
<td>
<%: Html.TextBoxFor(model => model.SelectedEmployee.Qualifications, new {style = "width:500px;"})%>
</td>
</tr>
<tr>
<td colspan="2" style="text-align: center;padding-top:20px;">
<input type="submit" value="Save" id="btnSubmit" /></td>
</tr>
</table>
<% } %>
<% } %>
</fieldset>
</asp:Content>
When you click on the Save button you go to this controller action;
[HttpPost]
[Authorize(Roles = "Administrator, HumanResources, ManagerAccounts, ManagerIT")]
[ValidateAntiForgeryToken]
[ValidateOnlyIncomingValues]
public ActionResult EditEmployee(HrViewModel hrvm)
{
if (ModelState.IsValid)
{
if (hrvm.SelectedEmployee == null
|| hrvm.EmployeeSelector.SearchTextId != hrvm.SelectedEmployee.EmployeeId)
{
return this.RedirectToAction(
"EditEmployee", new { employeeId = hrvm.EmployeeSelector.SearchTextId });
}
if (hrvm.SelectedEmployee.Picture.HasFile())
{
var destinationFolder = Server.MapPath("/Users");
var postedFile = hrvm.SelectedEmployee.Picture;
var fileName = Path.GetFileName(postedFile.FileName);
var path = Path.Combine(destinationFolder, fileName);
postedFile.SaveAs(path);
hrvm.SelectedEmployee.Photo = path;
}
var emp = Employee.GetEmployee(hrvm.SelectedEmployee.EmployeeId);
this.TryUpdateModel<IEmployeeHrBindable>(emp, "SelectedEmployee");
emp.Update();
this.TempData["Message"] = string.Format(
"At {0} Details updated for {1}", DateTime.Now.ToString("T"), hrvm.EmployeeName);
return this.View(hrvm);
}
return this.View(new HrViewModel());
}
So what am I doing wrong?
By default, MVC3 performs model binding based on the Name attribute of the input elements in your view.
To get file upload data, use the HttpPostedFileBase class as a parameter to your ActionResult and call the parameter 'file'.
[HttpPost]
[Authorize(Roles = "Administrator, HumanResources, ManagerAccounts, ManagerIT")]
[ValidateAntiForgeryToken]
[ValidateOnlyIncomingValues]
public ActionResult EditEmployee(HrViewModel hrvm, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (hrvm.SelectedEmployee == null
|| hrvm.EmployeeSelector.SearchTextId != hrvm.SelectedEmployee.EmployeeId)
{
return this.RedirectToAction(
"EditEmployee", new { employeeId = hrvm.EmployeeSelector.SearchTextId });
}
if (file.ContentLength > 0)
{
hrvm.SelectedEmployee.Picture = file;
var destinationFolder = Server.MapPath("/Users");
var postedFile = hrvm.SelectedEmployee.Picture;
var fileName = Path.GetFileName(postedFile.FileName);
var path = Path.Combine(destinationFolder, fileName);
postedFile.SaveAs(path);
hrvm.SelectedEmployee.Photo = path;
}
var emp = Employee.GetEmployee(hrvm.SelectedEmployee.EmployeeId);
this.TryUpdateModel<IEmployeeHrBindable>(emp, "SelectedEmployee");
emp.Update();
this.TempData["Message"] = string.Format(
"At {0} Details updated for {1}", DateTime.Now.ToString("T"), hrvm.EmployeeName);
return this.View(hrvm);
}
return this.View(new HrViewModel());
}
(So if you could grab the image data using model binding, it would have been located at hrvm.Picture instead of hrvm.SelectedEmployee.Picture)
In your view use the following instead and the default model binding should work:
<%: Html.TextBoxFor(model => model.SelectedEmployee.Photo, new { type = "file" }) %>
That is assuming SelectedEmployee.Photo is of type HttpPostedFileBase.
The reason it isn't working at the moment is that the default model binder will be trying to find a property called Picture directly on the model, because that's the name of your file input. It won't find it, because Picture is a property of SelectedEmployee.
Changing it to what I've suggested above generates the correct id and name for the file input in the markup so when posted back has the correct path. This means the default model binder is then able to map between the form post value and the property.

Calling PostMethod from HTML.Actionlink

Hi I am fairly new to MVC and facing a issue.
I have a View which lists all the countries having just 2 columns
I want column headers clickable and should sort on clicking on it
I have shown my Controller & view code below and I expect that when I click on the column header it should hit Index action method decorated with [HttpPost]
When I click the header link page just refreshes without hitting Action method I expect it to hit
Any help would be appreciated.
Here is my controller code
[HttpPost]
public ActionResult Index(string sortcolumn)
{
return View(SortedList(sortcolumn));
}
private List<Country> SortedList(string sortcol)
{
List<Country> sortedlist = new List<Country>();
switch (sortcol)
{
case "idCountry":
if ((SortOrder)ViewData["sortorder"] == SortOrder.Ascending)
{
sortedlist = db.Countries.OrderByDescending(c => c.idCountry).ToList<Country>();
ViewData["sortorder"] = SortOrder.Descending;
}
else
{
sortedlist = db.Countries.OrderBy(c => c.idCountry).ToList<Country>();
ViewData["sortorder"] = SortOrder.Ascending;
}
break;
case "Countryname":
if ((SortOrder)ViewData["sortorder"] == SortOrder.Ascending)
{
sortedlist = db.Countries.OrderByDescending(c => c.Countryname).ToList<Country>();
ViewData["sortorder"] = SortOrder.Descending;
}
else
{
sortedlist = db.Countries.OrderBy(c => c.Countryname).ToList<Country>();
ViewData["sortorder"] = SortOrder.Ascending;
}
break;
}
return sortedlist;
}
Here is my view
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<eduSmart.Data.Entities.Country>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
List of Countries</h2>
<p>
Manage list of countries on this page. You can choose your action creating, editing,
removing the country data.
</p>
<% using (Html.BeginForm("Index","Country")) { %>
Total Countries : <%: Model.Count() %>
<table>
<tr>
<th>
<%: Html.ActionLink("CountryID","Index",new { sortcolumn = "CountryID" }) %>
</th>
<th>
<%: Html.ActionLink("CountryName ", "Index", new { sortcolumn = "CountryName" })%>
</th>
<th>
</th>
</tr>
<% if (Model != null)
{ %>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%: item.idCountry%>
</td>
<td>
<%: item.Countryname%>
</td>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id = item.idCountry })%>
|
<%: Html.ActionLink("Details", "Details", new { id = item.idCountry })%>
|
<%: Html.ActionLink("Delete", "Delete", new { id = item.idCountry })%>
</td>
</tr>
<% }
}%>
</table>
<%} %>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
</asp:Content>
You can't hit a post method with an Action link. One thing you could do, if all you're doing is sorting here, is change your post method to a get and change the name
Instead of
[HttpPost]
public ActionResult Index(string sortcolumn)
Have something like
public ActionResult Sort (string sortColumn)
And point your actionlink to Sort.

Resources