Parameters dictionary contains a null entry for parameter - c#

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.

Related

How to retain search results when clicking browser's back button - ASP.NET Core MVC

I am creating an ASP.NET Core 3 MVC application that has a Customers tab in addition to the Home tab. On the Customers tab there is an input box where the user adds a search criterion (number of days) and a Search button. When the button is clicked then a list of Customer Ids is shown underneath (using jQuery and a Partial View). When the user clicks on a customer Id then the customer information is shown in a different page. However when I click on the browser's back button or on the 'Customers' tab then the criterion added and the search results disappear.
I have tried using the ResponseCache attribute to retain the search results but I could not make it work. I have also tried using the Cache Tag Helper but again was not successful. Anyone can help?
CustomersController
public class CustomersController : Controller
{
private readonly DbContext _context;
public CustomersController(DbContext context)
{
_context= context;
}
public IActionResult Index()
{
return View();
}
public IActionResult DisplayCustomerIdList(string searchText)
{
List<CustomerDetailViewModel> customers = _context.GetAll().ToList();
CustomerIndexViewModel model = new CustomerIndexViewModel()
{
Customers = customers
};
return PartialView("_CustomerIdListView", model);
}
public IActionResult Detail(decimal? Id)
{
Customer customer = _context.GetCustomerById(Id);
CustomerDetailViewModel model = new CustomerDetailViewModel(customer);
return View(model);
}
}
Index.cshtml
#{
ViewData["Title"] = "Customers Page";
}
#section Scripts {
<script type="text/javascript" src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
var url = '#Url.Action("DisplayCustomerIdList", "Customers")';
$('#search').click(function () {
var keyWord = $('#NumberOfDays').val();
$('#searchResults').load(url, { searchText: keyWord });
return false;
})
</script>
}
<body>
<div class="input-group mb-3 w-50">
<input type="text" class="form-control mr-2" placeholder="Number of days" autocomplete="off" id="NumberOfDays">
<button id="search" class="btn btn-outline-info mb-2">Search</button>
</div>
<div id="searchResults"></div>
</body>
_CustomerIdListView.cshtml
#model MyProject.Models.CustomerIndexViewModel
<div class="card border-info mb-3 shadow" style="width:220px; height: 625px; overflow-y: scroll;">
<div class="card-header">Customer Ids</div>
<div class="list-group">
#foreach (CustomerDetailViewModel customerdetails in Model.Customers)
{
<a asp-controller="Customers" asp-action="Detail" asp-route-id="#customerdetails.CustomerId" class="list-group-item list-group-item-action">
#customerdetails.CustomerId
</a>
}
</div>
</div>
Detail.cshtml
#model MyProject.Models.CustomerDetailViewModel
<h3>Customer Information</h3>
<ul>
<li>#Model.CustomerId</li>
<li>#Model.FullName</li>
</ul>
Do the search via a GET request (rather than post). That way, the actual URL the user is sent to includes the query.
<form action="/foo" method="get">
I have figured out why this was not working and thought to add it here in case someone else has the same issue.
It turns out that the jQuery .load() method creates a POST request when the input parameter is an object (and a GET request when it is a String). So, because the ResponseCache attribute does not work with POST requests, the caching was not working.

Passing input value to a controller method, not the whole model in Asp.Net Core 3

I have a ToDo items dashboard page where I display the ToDo's, their status and some other app info.
I want to have one input where I can add a string value (the ToDo title) and on the button click
have that passed to the controllers Create get method, so it populates the Create views Title input field with that value.
I want to it without a form if that is possible as the dashboard page already has a model which is an IEnumerable, just pass that value as a querystring parameter to the Create pages get view (or is it doable in javascript?).
Im not an MVC expert and also not as familiar with the new tag helper methodologies. Any help in how to structure thiswould be helpful.
Here is the html
<!-- Add Task -->
<div class="input-group input-group-lg">
<input class="form-control" type="text" placeholder="Add task and press enter..">
<span class="input-group-addon">
<a asp-controller="ToDoItems" asp-action="Create" ><i class="fa fa-plus"></i></a>
</span>
</div>
<!-- END Add task -->
here is the new model
public Class MyModel{
public IEnumerable<your old model> Old Model {get; set;}
public string Title {get;set;}
}
You can create a form like so in html with razor syntax
#model MyModel
...
<form action="/Controller/PostTitle/" method="post">
#Html.TextBoxFor(m => m.Title,new {#class = "...", #placeholder="...",
#requried="required"})
<input id="export-btn" type="submit" value="Download" class="btn btn-info" />
</form>
The #TextBoxFor will create a textbox and the lambda lets you use your strongly typed model.
Here is the controller
[HttpPost]
public IActionResult PostTitle(string Title) {
...
}

ASP.NET MVC Repository and Controller Error

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!

Assign a value to ViewBag varible inside the <input> tag

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);
}

mvc httppost href parameters

I'm currently working in ASP.NET MVC 4 with EF 4.0.
I have an unordered list with listitems. Each listitem contains a name and address and is clickable. Now I want to make it so that, when I click the listitem, I go to a new View. This view is called UitgebreidPersoonScherm and is in thesame controller RelatieZoekenController.
Here's the code I currently have:
Controller:
[HttpPost]
public ActionResult UitgebreidPersoonScherm(int psnID)
{
ViewBag.Message = "UitgebreidPersoonScherm";
return View("UitgebreidPersoonScherm");
}
View:
#model MobileApp.Models.ZoekModel
#{
ViewBag.Title = " Resultaten";
}
#using (Html.BeginForm("UitgebreidPersoonScherm", "RelatieZoeken", FormMethod.Post, new { id = "resultForm" }))
{ <ul data-role="listview" data-filter="true" data-inset="true" data-theme="g">
#foreach (var adres in Model.AdresList)
{
<li>
<a href='#Html.Action("UitgebreidPersoonScherm", "RelatieZoeken")'><b>#adres.Naam </b>
<br />#adres.Adres
</a></li>
}
</ul>
}
Now I wouldn't have a clue on how this is possible. I tried to make it with an actionlink, but it wouldn't show my data. If I remove the httppost I can get it to work, but without parameters. Currently it also doesn't give any parameters.
If you need any extra information, just ask.
Thanks.
but since you simply return the link, I advise you to substitute it somehow that way:
<a href='#Url.Action("UitgebreidPersoonScherm", "RelatieZoeken", new { psnID = adres.Id })'>

Categories

Resources