I have such an action method:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Search(String filter, String value, Int32? page) {
var set = new List<Employee>();
switch(filter) {
case "by-name": {
set = this.repository.Get(
e => (e.LastName + " " + e.FirstName + " " + e.MiddleName) == value
).ToList();
break;
}
case "by-empn": {
set = this.repository.Get(
e => e.EmployeeNumber == value
).ToList();
break;
}
default: return RedirectToAction("Search", "Employee");
}
ViewBag.SearchedEmployees = set.Count();
return View(set.ToPagedList(page ?? 1, PageSize));
}
Search view is like this:
#if(Model.Count > 0) {
foreach(var item in Model) {
Html.RenderPartial("Employee.Card", item);
}
#Html.PagedListPager(
Model,
page => Url.Action("Search", new { page = page }),
new PagedListRenderOptions {
LinkToFirstPageFormat = "<< Beginning",
LinkToPreviousPageFormat = "< Back",
LinkToNextPageFormat = "Forth >",
LinkToLastPageFormat = "End >>"
}
)
}
Search form is presented as a partial view:
#using(Html.BeginForm("Search", "Employee", FormMethod.Get, new { #class = "search-form" }))
{
<p>
#Html.TextBox("value")
</p>
<p>
#Html.RadioButton("filter", "by-name", true) By name <br/>
#Html.RadioButton("filter", "by-empn") By empn <br/>
</p>
<p>
<input type="image" src="#Url.Content("~/Content/Images/Search.png")" />
</p>
}
Problem: I have N page links. When I try to go to the second page I face an infinite loop of redirects. That's the way I implemented my action - default case is fired. So filter/value values are null on the second action call? Why?
How do I refactor my search action?
Also how should I configure route for such an action?
Thanks!
EDIT
So should route for the search action look like:
routes.MapRoute(
null,
"{controller}/{action}/Page{page}/filter{filter}/val{value}",
new { controller = "Employee", action = "Search" }
);
?
EDIT 2
So it is possible to write next:
page => Url.Action("Search", new { filter = ViewBag.SearchFilter, value = ViewBag.SearchValue, page = page }),
And inside a controller:
public ActionResult Search(String filter, String value, Int32? page) {
ViewBag.SearchFilter = filter;
ViewBag.SearchValue = value;
// ...
}
Is this right?
So filter/value values are null on the second action call? Why?
Because their corresponding input fields are inside a separate form and are never sent to the server.
You seem to be using some custom Html.PagedListPager helper (the code for which you haven't shown) but I guess that this helper generates the page links as anchors and it simply doesn't take into account any current query string or POSTed values when generating those links. So the href of your pagination link looks like this /SomeController/Search?page=5 instead of the correct one which would take into account those parameters which is /SomeController/Search?page=5&filter=somefilter&value=somevalue.
You can now easily understand why the filter and value parameters in your controller action are always null. It's because you never send them to the server when clicking on the pagination links.
So in order to resolve this issue you could modify this custom HTML helper that you are using to generate the pagination links to include those additional parameters. Or maybe the helper allows you to pass additional parameters? Check the documentation if this is some third party plugin that you are using.
Related
I want to redirect to a certain div of a webpage after handling some data in a controller. Is their any way to add the '#' to the end of the url? Or should I handle it with javascript?
Example:
[HttpPost]
public async Task<IActionResult> Edit(ViewModel model){
....
return RedirectToAction("Info", new { id = model.Id, "#" = "item_55" });
}
=> Should redirect to /Info/id=4#item_55
RedirectToAction has an overload that allows you to specify the fragment. Here's an example:
return RedirectToAction("Info", "Controller", new { id = model.Id }, "item_55");
Note that you also need to specify the controller as one of the arguments, as I've done above.
In my web site I'm getting data from xml in first controller action method and display as dropdown (html select and option).When a user selects an item in first dropdown, selected item sent to the next view's controller as a parameter using jquery $.post. I have keep breakpoints and see what is going on. Data trasfer is success until second view . But display nothing. I have attached screenshot of my break points and codes.
This is my controllers.
public ActionResult First()
{
//get the location data
var Loc = getData("Location", "", "", "");
List<FirstData> Ilc = new List<FirstData>();
foreach(var val in Loc)
{
Ilc.Add(new Firstdata
{
Destination = val
});
}
ViewBag.Loc = Ilc;
return View();
}
this is how I pass data from first view to second action controller method
<script type:"text/javascript">
$(document).ready(function() {
$("#chk a").addCIass("btn btn-default");
$("#chk a").click(function () {
var url = '#Url.Action("Check","Cruise")';
$.post(url, { LocNane: $("#desti").val() }, function (data) {
//alert("succes");
});
});
});
</script>
this is how my second controller gets pass data[I made a breakpoint here]
public ActionResult Check(string LocName)
{
string d = LocNane;
var Nan = getData('Location',"Name",d,"");
List<Seconddata> nf = new List<Seconddata>();
foreach (var val in Nam)
{
nf.Add(new Seconddata
{
Naneof = val
});
}
ViewBag.Nn = nf;
}
and this is my second view and display data in break point
<body>
<div>
#foreach( var item in #VieuBag.Nm)
{
<h3>one</h3>
}
</div>
</body>
I put "#item.Nameof" inside the header tags , but it didn't work. so just to chek I put one. after go through the loop nothing display.what's the wrong.please help me with this.
The problem here is the success handler of $.post does not append/insert the returned html in any element. You can do something like this in success handler where divId is element Id in page where you want to show the returned html.
$("#divId").append(data);
I'm trying to dynamically set the StudentIds by letting the user select check boxes for the reports they want. When they click the ActionLink, I use jQuery to set the values of the ids in a hidden field. I need the Action Link to read the ids from hidden field.
The values are getting set in the hidden field, but they are not being passed to the controller from the actionLink.
I need to pass the ReportIds to the controller.
#Html.ActionLink("PrintMed", "GetMedEdVerificationReport", "Student", new { studentIdList = Model.ReportIds }, new { #class = "button print_selected print_selectedMedEd disabled" })
#Html.HiddenFor(model => model.ReportIds)
javascript
$('.print_selectedMedEd').bind('click', function () {
var ids = getPrintIds();
if (ids.length == 0) {
return false;
}
$('#ReportIds').val(ids.toString());
return true;
});
When the asp.net mvc render your ActionLink it will generate a link with a parameter that you have on the model. Event you change the value of the model, it will not change the value on the output generated by ActionLink.
Given this, you have to se again the value, try to generate an ACtionLink without the argument:
#Html.ActionLink("PrintMed", "GetMedEdVerificationReport", "Student", null, new { #class = "button print_selected print_selectedMedEd disabled" })
On the javascript side, you could try using the on method to bind a event handler and call the preventDefault method from the event argument, for sample:
$('.print_selectedMedEd').on('click', function (e) {
e.preventDefault();
var ids = getPrintIds();
if (ids.length > 0) {
$('##Html.IdFor(model => model.ReportIds)').val(ids.toString());
// make an url to redirect
var url = $(this).prop("href") + "?studentIdList=" + ids.toString();
// redirect using the generated url
window.location.href = url;
}
});
Remember to use the Html.IdForm() to make sure you have the right id for a specific property.
That is because #Html.ActionLinkdoesn't use the hidden fields to make the request. Once the action link renders it becomes
PrintMed
so you would need to modify the html on the anchor tag.
You should be using Html.Beginform instead in order to pass along the model.
#using (Html.BeginForm("GetMedEdVerificationReport", "Student", FormMethod.Post, null))
{
#Html.HiddenFor(model => model.ReportIds)
<input type="submit" value="PrintMed" />
}
#Html.HiddenFor(modelItem => item.OrderId)
<td>
<input type="button" value="Pickup" onclick="location.href='#Url.Action("Edit", "Assignment", new { ID = item.OrderId })'" />
I have the following situation:
Into a view I define a link in this way:
<a href="#Url.Action("Edit", "Vulnerability", new { id = Model.Id })" data-mini="true" data-inline="true" data-role="button" >Annulla</a>
As you can see when the user click the link it is executed the Edit() method ot the VulnerabilityController class passing and Id value
Ok, this works fine but in this view I want have something like I have in a controller, this thing:
return new RedirectResult(Url.Action("Edit", "Vulnerability", new { id = vulnId }) + "#tab-2");
As you can see in this second version I always call the Edit() method of the VulnerabilityController class but the value of Id variable is something like "1234#tab-2"
Can I do something like this in my view and not only in my controller?
If you want to render (include) the results of some action inside your View you can use Html.Action:
#Html.Action("Edit", "Vulnerability", new { id = vulnId + "#tab-2" })
See MSDN
For doing this using Razor Syntax, you can try like this:
#Html.ActionLink("Annulla", "Edit", "Vulnerability", new { id = Model.Id },
new{ #data_mini="true", #data_inline="true", #data_role="button"})
I am working in ASP.NET MVC 4 with C#, and i'm trying to turn the parameter of one ActionResult method into a variable for use in another method. So I have this for example:
public ActionResult Index(int ser)
{
var invoice = InvoiceLogic.GetInvoice(this.HttpContext);
// Set up our ViewModel
var pageViewModel = new InvoicePageViewModel
{
Orders = (from orders in proent.Orders
where orders.Invoice == null
select orders).ToList(),
Callouts = (from callouts in proent.Callouts
where callouts.Invoice == null
select callouts).ToList(),
InvoiceId = ser,
InvoiceViewModel = new InvoiceViewModel
{
InvoiceId = ser,
InvoiceItems = invoice.GetInvoiceItems(),
Clients = proent.Clients.ToList(),
InvoiceTotal = invoice.GetTotal()
}
};
// Return the view
return View(pageViewModel);
}
I need that int ser to somehow become "global" and its value become available to this method:
public ActionResult AddServiceToInvoice(int id)
{
return Redirect("/Invoice/Index/");
}
As you can see in my return statement just above, I get an error as I am not passing the variable "ser" back to Index, but I need it to be the same value that was passed to Index when the action was called. Can anyone assist?
When you construct your link to that method, you need to ensure you are passing your variable ser to the method along with any other parameters that it needs (it is unclear if the id in the AddServiceToInvoice method is actually the ser parameter or not. This assumes it is not)
Action Link In View
#Html.ActionLink("Add Service", "Invoice", "AddServiceToInvoice", new {id = IdVariable, ser = Model.InvoiceId})
AddServiceToInvoice Action Method
public ActionResult AddServiceToInvoice(int id, int ser)
{
//Use the redirect to action helper and pass the ser variable back
return RedirectToAction("Index", "Invoice", new{ser = ser});
}
You need to create a link with that ID:
if you're doing a get-request that would be something like this:
#Html.ActionLink("Add service to invoice", "Controller", "AddServiceToInvoice",
new {id = Model.InvoiceViewModel.InvoiceId})
Otherwise if you want to do a post you need to create a form:
#using Html.BeginForm(action, controller, FormMethod.Post)
{
<input type="hidden" value="#Model.InvoiceViewModel.InvoiceId" />
<input type="submit" value="Add service to invoice" />
}