I am getting this error message whenever I try to go to my OrderHistory page.
The parameters dictionary contains a null entry for parameter 'Id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult History(Int32)' in 'Mis324Assignments.Controllers.MusicController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
This is my controller:
public ActionResult History(int Id)
{
return View(mor.GetHistory(Id));
}
This is my Repository:
public List<MusicHistoryModel> GetHistory(int custID)
{
using (IDbConnection db = new SqlConnection(connectString))
{
string sql = #"SELECT OI.OrderId, OI.ASIN, OI.Qty, OI.Title, OI.Artist, OI.Price, O.OrderDate
FROM tblOrders as O join tblOrderItems as OI on O.OrderId = OI.OrderId
Where O.CustId = #custID";
List<MusicHistoryModel> history = db.Query<MusicHistoryModel>(sql,new { custID }).ToList();
return history;
}
}
This is my View:
#model IEnumerable<Mis324Assignments.Models.MusicHistoryModel>
#{
ViewBag.Title = "History";
Layout = "~/Views/Music/_3ColLayout.cshtml";
}
<h2>Order History</h2>
#foreach (var item in Model)
{
<div class="row" style="padding:4px;">
<div class="col-md-2">
<img src="http://images.amazon.com/images//P#(item.ASIN).01._SCTHUMBZZZ_V1115763748_.jpg"
class='productImage' style="margin:0 0 5px 10px;" />
</div>
#item.OrderID
#item.OrderDate
#item.title
#item.artist
#item.price
#item.qty
</div>
}
This is my ActionLink that redirects to the History View:
<form action="~/Music/History" method="post" class="enhancement">
<input type="submit" value="Order History*" /><br />
</form>
I am passing in an int id in my controller and it is using that int id as the custID to get information from my repository. I dont know why the error message is saying I am not passing anything into the int id parameter
When looking at your view implementation, it seems that you are not passing id in the History action which is needed by your History Action.
You can pass id as your parameter in following way :
#using(Html.BeginForm("History", "Music",
new { Id= your_id_should_be_here }, FormMethod.Post, new{ #class="enhancement"})
{
<input type="submit" value="Order History*" /><br />
}
Answer submitted already put it as comment not as answer.
I figured it out!!! ON my Action link I did not pass in the CustID parameter. That is why it did not get any id parameters!
Related
I am using two views 'EmployeeList' and 'Edit' respectively. From the view EmployeeList, i make call to a method called 'Edit' which returns the 'Edit' view in controller named 'Employee'. there is a submit button in 'Edit' view which calls Edit_Employee method in the 'Employee' controller. Respective views are given below.
EmployeeList.cshtml
<tbody>
#{
if (Model.Emp_List != null)
{
foreach (var item in Model.Emp_List)
{
<tr>
<td>#item.row_number</td>
<td style="display:none">#item.Id</td>
<td>#item.Name</td>
<td>#item.Designation</td>
<td>#item.Department</td>
<td>#item.Phone</td>
<td>
#Html.ActionLink("Edit","Edit", "Employee", new { id = item.Id,flag=1},null)
</td>
</tr>
}
}
}
</tbody>
Edit.cshtml
<h2>Edit Employee</h2>
#using (Html.BeginForm("Edit", "Employee", FormMethod.Post))
{
foreach (var item in Model.Emp_List)
{
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputname">Name</label>
<input type="text" class="form-control" value="#item.Name" name="Name" placeholder="name" id="inputname">
</div>
<div class="form-group col-md-6">
<label for="inputDesignation">Designation</label>
<input type="text" class="form-control" value="#item.Designation" name="Designation" placeholder="designation" id="inputDesignation">
</div>
</div>
<input type="submit" value="Submit " formaction="Edit_Employee" class="btn btn-primary" />
}
}
Employee controller methods given
public ActionResult Edit(int id, int flag)
{
IList<Employee> emp_editlist = new List<Employee>();
EmployeeList e = new EmployeeList();
try
{
if (Employeedetailssession.Current.Session["emplist"] != null)
{
emp_editlist = this.GetSession("emplist");
emp_editlist = emp_editlist.Where(x => x.Id == id).ToList();
}
e.Emp_List = emp_editlist;
e.Return_Param = 0;
}
catch (Exception)
{ }
if (flag == 1)
return View("Edit", e);
else
return View("Details", e);
}
[HttpPost]
public ActionResult Edit_Employee(EmployeeList emp)
{
EmployeeList empobj = new EmployeeList();
try
{
string message = string.Empty;
HttpClient hc = new HttpClient();
hc.BaseAddress = new Uri(baseURL);
var EditRec = hc.PostAsJsonAsync<EmployeeList>("EmployeeApi", emp);
EditRec.Wait();
var updatedata = EditRec.Result;
if (updatedata.IsSuccessStatusCode)
{
empobj = updatedata.Content.ReadAsAsync<EmployeeList>().Result;
}
else
{
empobj.Emp_List = null;
empobj.Return_Param = 0;
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout) { }
else throw;
}
return RedirectToAction("Edit",empobj);
}
The issue is, when I call the Edit method from EmployeeList view , details are successfully loaded. but after making few changes and click Submit button, it wont hit Edit_Employee method instead showing error as
'The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32, Int32)' in 'Vidly.Controllers.EmployeeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.'
It seems on button click also it hits 'Edit' method.. Why it doesnt hit the right method?
I want to navigate to Edit_Employee method on submit click. Thanks in advance.
I have cshtml view page with paginations
here view of that page
Once I click any of below number (which is 1 to 10) I should be able to pass that number to POST method of that form
this is the relevant cshtml code snippet to that pagination
#if (Model.Pager.EndPage > 1)
{
<ul class="pagination">
#for (var page = Model.Pager.StartPage; page <= Model.Pager.EndPage; page++)
{
<li class="#(page == Model.Pager.CurrentPage ? "active" : "")">
<input type="submit" value=#page class="btn btn-default" ViewBag.pagenumber=#page/>
</li>
}
</ul>
}
then I try to pass that value like this
#using (Html.BeginForm("method_name", "controller", new { pagenumber = ViewBag.pagenumber} , FormMethod.Post))
{
but pagenumber getting null each time, in this way
EDIT:
[HttpGet]
public ActionResult method_name(int? page,string Product_ID)
{
........
}
[HttpPost]
[ValidateInput(false)]
public ActionResult method_name(AddNewProduct product, string pagenumber)
{
.....
return RedirectToAction("method_name", "controller", new { page = pagenumber});
}
You can do it like
Add class pagerBtn in the pager buttons
<input type="submit" value=#page class="btn btn-default pagerBtn"/>
Make a hidden input field in the form
#using (Html.BeginForm("method_name", "controller" , FormMethod.Post))
{
//Make sure the action parameter same as name of input field
<input type="hidden" name="pagenumber" id="hiddenInput" />
}
Write jquery to get page number
$(document).ready(function(){
$(".pagerBtn").on("click",function(e){
var pageClicked = e.target.value;//Get clicked button page number from attribute value.
$("#hiddenInput").val(pageClicked);//insert clicked value in hidden filed input with name same as controller parameter taking this value.
});
});
in ViewBag value becomes null when redirection occurs.
try to use TempData
<input type="submit" value=#page class="btn btn-default" TempData["pagenumber"]=#page/>
#using (Html.BeginForm("method_name", "controller", new { pagenumber = TempData["pagenumber"]} , FormMethod.Post))
Assign a name tag to each input field. In that way you could retrieve the values in the controller using a FormCollection and don't need the new { pagenumber = ViewBag.pagenumber}:
[HttpPost]
[ValidateInput(false)]
public ActionResult method_name(FormCollection collection){
var inputValue = collection.GetValue("name").AttemptedValue;
return RedirectToAction("method_name", "controller", inputValue);
}
I am having two view pages using the same controller and model as a way to change the page layout but i am having trouble displaying my second page. This is my error message: The parameters dictionary contains a null entry for parameter id of non-nullable type for method system.web.mvc.actionaresult ListView(int32) in UserController
Not sure what is causing the problem i used the same code for the first view page(working) except just changing the view layout.
First View
<div>
Click Here for List view
</div>
<section id="users" data-bind="foreach: Users">
<div id="nameImage">
<figure id="content">
<img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<figcaption>
<a title="Email" id="emailIcon" class="icon-envelope icon-white" data-bind="attr:{'href':'mailto:' + Email()}"></a>
<a title="Profile" id="profileIcon" class="icon-user icon-white"></a>
</figcaption>
</figure>
<p data-bind="text:Name"></p>
</div>
</section>
</section>
List View
<div class="accordion-inner">
<div data-bind="foreach: Users">
<div>
<img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<p data-bind="text:Name"></p>
</div>
</div>
Controller
public ActionResult View(int id)
{
// get the menu from the cache, by Id
ViewBag.SideBarMenu = SideMenuManager.GetRootMenu(id);
ViewBag.UserApiURL = "/api/User/" + id.ToString();
return View();
}
public ActionResult ListView(int id)
{
// get the menu from the cache, by Id
ViewBag.SideBarMenu = SideMenuManager.GetRootMenu(id);
ViewBag.UserApiURL = "/api/User/" + id.ToString();
return View();
}
}
Api controller
private UserService _userService = new UserService();
public IEnumerable<User> Get(int? id)
{
if (id.HasValue)
{
return _userService.GetUsers(id.Value);
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
The URL /Roster/ListView is missing an ID value. You'll need to either:
Change the URL to something like /Roster/ListView/123
Change the action method to allow a nullable integer by changing the type from int to int?. Then in the action method you need to check if the id parameter is null or not and deal with that appropriately, such as by returning an error, or just ignoring the id.
You write following link href="/Roster/ListView" but action ListView require parameter id, which is missing here.
I am using mvcContrib to generate a grid to allow users to filter data by keying in search data. There are several partial views that are rendered in my Index View:
Here is the partial view that handles the searching:
#model CRMNPS.Models.PagedViewModel<CRMNPS.Models.NPSProcessed>
#using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
<label>
Model Number: #Html.TextBox("searchWord" )
<br /><br />From Date: #Html.EditorFor(m => m.FromDate)
</label>
<label>
<Br /><br />To Date: #Html.EditorFor(m => m.ToDate)
</label>
<label>
<br /><br /> <input class="button" value="Search" type="submit" />
<br />
</label>
}
Here is my Index view:
#model PagedViewModel <CRMNPS.Models.NPSProcessed>
#{
ViewBag.Title = "CRM Processed List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Processed List</h2>
#{Html.RenderPartial("SearchBox");}
#{Html.RenderPartial("Pager", Model.PagedList);}
#Html.Grid(Model.PagedList).AutoGenerateColumns().Columns(column =>{
column.For(x => Html.ActionQueryLink(x.ModelNumber, "Edit", new { id = x.Id
})).Named("Id").InsertAt(1);
}).Sort(Model.GridSortOptions).Attributes(#class => "grid-style")
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { FromDate = Model.FromDate, ToDate = Model.ToDate, SearchWord = Model.SearchWord }))
{
<p>
<input class="button" value="Export to Excel" type="submit" />
</p>
}
At the bottom of the Index View I have another submit within the Html.BeginForm with a Formmethod.Post.
The Index ActionResult that calls this view passes a viewmodel with the search criteria and a IQueryable object that the mvcContrib uses.
When the user presses the Export to Excel push button I would like to pass the selected values back to the Index actionresult HttpPost controller. (FromDate, ToDate and SearchWord)
The FromDate, ToDate and SearchWord values always come back null.
I am fairly new to MVC so any constructive comments are welcome.
Thanks
Joe
Since they are not in the form that you are posting - (Export to Excel is in a separate form).
The inputs
FromDate, ToDate and SearchWord
Are in the first form (in the partial view). So those values don't show up in the controller (since they are not part of the http post).
If you want to see all these values being passed back to the controller, they should be under one
Html.BeginForm
One way is to put'em all in the same form as MoXplod suggested or you can use some javascript to send search values as query string by hooking the submit event of second form like
$('#excel-form').live('click', function(){
var action = this.action;
var searchString = $('#SearchWord').val();
var toDateString = $('#ToDate').val();
var fromDateString = $('#FromDate').val();
if(action.indexOf('?')<0)
{
action = action+"?SearchWord="+searchString;
}
else
{
action = action+"&SearchWord="+searchString;
}
action = action + "&ToDate="+toDateString + "&FromDate=" + fromDateString;
$(this).attr('action', action);
return true;
});
it will put these values in querystring and make them available in action method. Alternatively, you can use ajax to post these values to controller rather than full regular post back.
I've got a form where users can edit members of a group.
So they have the possibilty to add members or remove existing members. So the Url goes like
".../Group/Edit/4" Where 4 is the id of the group.
the view looks like this
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm("AddUser", "Group")) %>
<%{%>
<label for="newUser">User</label>
<%=Html.TextBox("username")%>
<input type="submit" value="Add"/>
</div>
<%}%>
<% using (Html.BeginForm("RemoveUser", "Group")) %>
<%{%>
<div class="inputItem">
<label for="groupMember">Bestehende Mitglieder</label>
<%= Html.ListBox("groupMember", from g in Model.GetMembers() select new SelectListItem(){Text = g}) %>
<input type="submit" value="Remove" />
</div>
<%}%>
</asp:Content>
The problem is that after adding or removing one user i lose the id of the group. What is the best solution for solving this kind of problem?
Should I use hidden fields to save the group id?
Thanks in advance.
Hidden fields are a good way of persisting the id during posts.
You could use a hidden field or you could just parse the value into your route. I'm not sure how you're parsing the group id to the view but it would look something like:
<% using (Html.BeginForm("AddUser", "Group", new { groupId = Model.GroupID })) { %>
Then your controller will look something like this using the PRG pattern
[HttpGet]
public ViewResult Edit(int groupId) {
//your logic here
var model = new MyModel() {
GroupID = groupId
};
return View("Edit", model);
}
[HttpPost]
public ActionResult AddUser(int groupId, string username) {
//your logic here
return RedirectToAction("Edit", new { GroupID = groupId });
}
[HttpPost]
public ActionResult RemoveUser(int groupId, string username) {
//your logic here
return RedirectToAction("Edit", new { GroupID = groupId });
}
The advantage to this method is that it's more RESTful