Maintain url parameters while navigating - asp.net-mvc

My Index action for a controller takes a page parameter like so:
/Organizations/Index?page=5
Which is used to limit the number of objects displayed. If they choose to "edit" one of those objects after they are finished I would like to return with the same values as before they began editing (e.g. be on the same "page" of the list).
My edit url ends up looking like this:
/Organizations/Edit/487
How do I persist the original page value?
Thanks!

To persist data between calls you can use
Session state,
a hidden field,
render it into the links as a query string,
use a cookie or
TempData (which is Session state kept only for the next call).
If you want to access the route data, you can use the controller context:
ControllerContext.RouteData.Values["action"];
"action" is the name of the route parameter.

I found two options:
1) Use a Source GET parameter all the time. Like this:
/Organizations/Edit/487?Source=/Organizations/Index?page=5
The problem here is that the URL gets ugly.
2) You can do what slfan said using hdden fields (I don't like to use Session for this). First time you enter the edit view, catch the HttpContext.Current.Request.UrlReferrer property and save it to a hidden field. This way, if you do lots of POSTs you won't lose the original UrlReferrer, which is the url with the page parameter.

Related

Store filter state for returning later

I have an app with an index view and a show view, nothing special. The index view has filter options. What I want is that the filter options a user choses are stored in some way, so when a user opens the details screen and returns later, the same filtered records are shown.
The back button is not an option, because there can be done more than just opening the details screen and returning. I could add the filter params to every request made afterwards until returning to the index page, but that seems to be a bit cumbersome. What are my options?
I solved this in the controller by creating a private method called manage_filter_state. This method is called in the index action, just before retrieving all records based on the value of the filter params. The mothod looks like this:
private
def manage_filter_state
if params[:company]
cookies[:company] = { value: params[:company], expires: 1.day.from_now }
else
if cookies[:company]
params[:company] = cookies[:company]
end
end
end
Basically, if the param value is set, it sets a cookie for keeping state. When visiting the page again later with another value of the param, it overwrites the cookie. Visiting later without a param value, it sets the param with the cookie value.
There is normally no need to use a cookie for it. Store it in an session[ :name ]
A good place is inside a controller. To generalize the problem you could store anything QUERY inside a session variable and append when receiving a link.
Then reset when leaving a controller.

MVC checkbox checked state issue

Good morning,
I have a view that display's search results for customers. On top of the view i have a filter that has a few checkboxes. The user can select multiple checkbox items and press the filter results button. When the user presses the button it calls an action that filters the result. The page is also refreshed. My question now, how can i make the page remember what checkboxes are checked. Because when the results are returned the filter elements are reset.
Thanks in advance.
you can use TempData. TempData VS ViewBag VS ViewData
you used ViewData, After the redirect, the ViewBag & ViewData objects are no longer available
TempData is also a dictionary derived from TempDataDictionary class
and stored in short lives session and it is a string key and object
value. The difference is that the life cycle of the object. TempData
keep the information for the time of an HTTP Request. This mean only
from one page to another. This also work with a 302/303 redirection
because it’s in the same HTTP Request. Helps to maintain data when you
move from one controller to other controller or from one action to
other action. In other words when you redirect, “Tempdata” helps to
maintain data between those redirects. It internally uses session
variables. Temp data use during the current and subsequent request
only means it is use when you are sure that next request will be
redirecting to next view. It requires typecasting for complex data
type and check for null values to avoid error. generally used to store
only one time messages like error messages, validation messages.
TempData["CheckedList"] = YourCheckBoxListValues; //in your controller
in your View
#{
var tempchkboxList = TempData["CheckedList"] as yourStronglyTypeClass;
//or
var tempchkboxList = TempData["CheckedList"].ToString();
}
Depends on how long the input criteria should be remembered.
You could also save it in your session via Session["customerCriteria"] = yourCriteria, but it would be easier to give an example if you had provided some code.
You can keep your selected/checked checkbox details in session variable when you post the form (by clicking on the search button). In the HttpPost action,read the checkboxes which were checked and add that to a collection property of your viewmodel and send it back to the view. set the session variable values to null once you are done with it (after reading). in the view, use your viewmodel value to set the checked status of those checkboxes.
Another option is using ajax. When you click on search.Read your search criteria and make an ajax request to the action method. Return a partial view back and update only the div/table which shows the results of the search.

ASP MVC3 Pass additional params with "return View(model)"

I'm in serious need of passing url params with View class. Here's code:
if (!ModelState.IsValid)
{
return View(model);
}
This should not only return model based view, but also add specific param to URL (param won't change view details, but is needed as it's one of few automatically generated SessionKeys (one for each tab/window used to view app) and I know no other way to get to it, different than passing as param (it can't be generated everytime, 'cos params will change; it can't be global variable because it'll reset its value each refresh; it can't be static, because static is evul).
Oh this action is called with use of form and submit button, not actionLink or something like this.
EDIT1: I need params to stay in URL after refresh, or I need some other form of keeping data that persists through refresh/validation fail.
If I understand you correctly you have data that you need to use in generating Urls on your page? This just forms part of your ViewModel - or at least it should, since it's data that the View needs in order to render.
You can use ViewData to add any extra data that isn't part of your view model. Or, better still, add the data as members to it. Equally, if different views with different View Models require this data, add a ViewModel base class and derive from that so you can share that data.
use
RedirectToAction("actionName","controller",
new RouteValueDictionary(new {param1="value",param2="value2"});
or you can use hidden field to store the values in your page and then pass this down as and when you need them..

Switching Controller Context in ASP.NET MVC for AJAX Calls

Perhaps this is impossible, but I figured I would ask anyway. I'm working on an ASP.NET MVC application that uses jquery/AJAX extensively. One of the AJAX tasks that gets performed is a call to controller action that returns a URL to redirect the user to.
What I would like to do is to have the same controller context when making an AJAX call as I do on the current page. The reason for this is because the controller action called by AJAX makes use of the Url.Action() method and I need it to use the same route values as what is currently being used on the current page.
So for example, if a user is currently on: /Site/Search/Advanced/Widgets/Black and Blue/1/Descending, mapping to a route of Site/Search/Advanced/{objectType}/{query}/{pageNum}/{displayMethod}, with {objectType} defaulting to "Cars" (not "Widgets").
I would like a call to Url.Action("Advanced", "Search", new {query="Something else"}) to generate /Site/Search/Advanced/Widgets/Something else/1/Descending.
As it stands, the call will generate /Site/Search/Advanced/Cars/Something else, because the controller does not what context it is in.
My alternative is to specify the additional parameters directly in the Url.Action call, but that would require a lot more complexity with values coming in and out of jquery AJAX through various hidden fields, which would be a huge mess...
Any ideas?
Assuming that you on every ajax call want the route values you haven't specified to be the same as in the original non-ajax request, you could always make use of ViewContext.RouteData to add the extra parameters to the ajax call. When the ajax call is returned, you use the route data to add to any new links in the asynchronously loaded results.
Another way is to use the Session object to keep track of the last request, and change the values if new ones are sent.
On the other hand, I would like to question your goal (if this search scenario is your actual scenario): If I search for something, browse to page 4, and then enter a new search term, I don't expect to go to page 4 of the new search results - I expect the first page (although I do expect that my chosen sorting order is preserved...).

Post/Redirect/Get: Redirect to specific route

I have the following scenario:
I have an edit page, which can be called from different pages. These pages could be the detail view for the current entity, or the list view for the entities (with or without a search in the route).
HOW do I cleanly redirect to the original calling page using the MVC framework? Of course I could simply pass the HttpContext.Request.Url value by holding it in my TempData, but that sort of smells, in my eyes (or, err, nose). It's on a lower level than the rest of the code.
Is there a way to get the routevalues for the previous page in a controller context? If I have that, I could store that temporarily and pass that to the redirect.
Do not use TempData when not redirecting. One AJAX request from your edit page, and the TempData will go away.
Tomas is right that a hidden element or query string parameter is the way to go. But make sure you sanitize the value submitted. You don't want to redirect any old site on the web; you need to ensure that the page to which you redirect is part of your sites.
you can always have a hidden form element telling the controller where to redirect when posting a form. when using a get request, you could use a querystring in a similar way. it might not be the most beautiful solution, but it's quite a lot safer than trusting httpreferrer or other headers that could easily be changed (or ommitted) by the browser.

Resources