ASP.NET MVC3 URL and hiding Id's - asp.net

I have a heap of entities that are keyed by ID. In one screen I load a "Subject" based on the ID like so: "/Results/Subject/53" On that same screen I have a combo box that maintains a list of all subjects. The user can change the selection in this combo to another subject and I load the results for that subject using ajax. When I do this the URL in the browser is stale as I might be now be looking at /Results/Subject/45 If a user reloads I reload the original document and not the new one.
I would either like to update the URL (which sounds hacky as) or I would like to base my navigation on something else besides the Id as part of the URL. How can I do this? How can I load controllers for specific items without specifying the Id as part of the URL.

You can also pass the id via the HTTP GET parameter: /Results/Subject?id=45 or HTTP POST parameter.
However, I doubt that this will answer your question.
A colleague of mine has encountered the similar problem, and he solved it by altering the browser URL string (by attaching a specific #anchor to it).

Easiest way would be to ditch the ajax when that drop-down changes, and just navigate to a new url (/Results/Subject/NewID).
If you want to keep the ajax, you could just put the key at the end of the url with a # like "/Results/Subject#53", then load it via Ajax (the #53 will not be passed over to the server). That way, when the user changes the drop-down, you can navigate to "/Results/Subject#NewID" without it reloading the page.

Related

Passing values that aren't related to inputs using MVC?

I have page where users can select from one or more images. When they are done I would like them to navigate to the next page and what is displayed would be based on the selection from the previous page.
"Selecting" just means that they click the image and it has a CSS class added to it. When they click the link to navigate to the next page I'd like to collect the images that have been selected and pass that information along using either TempData or Session.
In most of the examples I have seen either inputs or the query string is used to pass information from the View to the Controller. How can I pass which elements have a particular class to my controller when a link is clicked?
If you're using a link click, I'd probably just append the selected images to the query string. I'm assuming you don't mind exposing this query string to end users.
I'm sure that's probably not the answer you were looking for. But as you stated I think you're only to legitimate options are passing the values through the query string or using hidden inputs and posting the page to your action by intercepting the link click event.
You said you do not want to post back to servers. You cannot access TempData or Session without posting back to server, so they are out of scope.
You only have client side option, so you want to collect a user's selected items in array.
Once the user clicks to Next Page, you create a query string like this ?ids=1-2-3-4 and retrieve those value at next page.
Other thoughts: Long URL likes this is a bit ugly, and URL has maximum length limit depending on browser. If I'm you, I'll post back to server to collect the selected values. Then use TempData (or some persistent storage).

Possible to only update part of page and change query string parameters at same time in asp.net?

Is there a way to only update part of the page and update the query string parameters at the same time without completely refreshing the whole page in ASP.NET?
I only need to update the "main" section of my page and not the whole page. I understand I can do a partial page postback (or use asp ajax) to do the partial page update, but then how do I update the query string parameters in the URL at the same time? Is that even possible?
Or is it not possible and I'll have to just do a Response.Redirect in the code behind of the partial page postback redirecting to the same page with new query params and just let the whole page refresh?
Use pushState.
This new feature offers you a way to change the URL displayed in the browser* through javascript without reloading the page. It will also create a back-button event and you even have a state object you can interact with.
window.history.pushState(“object or string”, “Title”, “/new-url”);
Described here
You have absolutely zero programmatic access to the address bar. The only way to change it is to redirect.
You could, however, do it like some sites do and provide a "send a link to this page to your friends" area. Youtube comes to mind - see how it provides a URL, querystring parameters included, for you to copy, should you wish to send someone a link to a video starting from some specific point.
Also check the handy "Share" link right under your question. You could provide a link like that, with the target URL, so for the user it's just a matter of right-clicking and copying from the context menu. A link well structured into your site is more user friendly than having the user copy directly from the bar, or from a text box. Specially for mobile browsers, where the sequence is usually press-and-hold, then copy. Copying from the address bar, on the other hand, may involve selecting the address bar text, which in some Android devices is a pain in the ass.

overwrite parameters passed by querystring

I have the following problem
I have a web framework built with classic asp that saves the page state in hidden textboxes, and then issues a submit to itself.
Before submitting, we have a javascript functions that saves the action in a hidden "action" input, and then performs the submit.
The page loads the state from those hidden texts, reads the action issued, reads extra parameters, like the id of the record to edit, and then builds the page accordingly.
I'd like to make a url link to automatically start the page with "edit" action on a "x" id.
So I was thinking about building the following url, for example
http://myapp/user?action=edit&id=23
the problem is that when the page auto-submits, que url string keeps the parameters.
I'd like to achieve the following:
when the user clicks on
http://myapp/user?action=edit&id=23
my page should receive the posted values action=edit and id=23
but the url should be just http://myapp/user
and both parameters should be kept in the hidden texts... (I wonder if I make myself clear...)
thanks a lot
saludos
sas
ps: I have a couple of ideas about how to solve it, but I'll post them as answers...
The first solution that came to my mind was to save the values in the session, issue a redirect without the parameters, and then load the parameters and remove them from the session...
the other solution, and the easiest one to implement, is that whenever I read parameters I first read them from the querystring (request.queryString) and then overwerite them from the posted values (request.form)
that way I wouldn't care if the parameters from the querystring keep being sent, the only problem left would be the annoying url...

Something like viewstate and session

The problem that I am having is as follows:
I currently have a custom class that generates buttons and places them on a placeholder on a master page.
The events for these buttons put specific values into session that differs values for a database query. In essence, the buttons serve as filters for charts.
After creating all the buttons, I realized that session values will stay constant from page to page, so everytime a user enters a different page while another is open, the filters selected on the open page will remain constant for the new page that is opened.
At first, I wanted to use viewstate rather than session, but then realized that a master page and a content page do not share the same viewstate.
At the current time, I am thinking of using a prefix for the sesson key that will identify what page the filters actually exist for. However, I am not wanting to overload session with numerous values if the user wishes to have many pages open at the same time.
Any solutions that would entail a way to share viewstate (or some other way to store values) between app_code, the master, and the content page?
Use HttpContext.Current.Items, it is a key-value pair collection with a lifetime of a single Http Request.
Have you considered Context.Items?
How many filters are we talking here? Store the filter values in the URL. Have you seen some of the URLs that google or an ecommerce site uses? They are quite long. Here is how I do it:
I store the filter values in the query like, www.chart.com?filter1=val1&filter2=val2 etc.
I user JQuery's query plugin to manipulate the query on the client side, and then request the chart from the server again, using the new query.
This way, I'm not junking up session, cookies, or anything like that, and if the user wants to store a bookmark to a particular chart or email it to a friend, they can and the filters are preserved.
I'm starting to think the answer shown in the following question will work:
ViewState object lost in Master Page Load
Exposing the desired variables via a property.
If the data isn't too long, cookies are a typical solution.
Another option is to use Silverlight isolated storage. The Silverlight control itself could be invisible (no UI).

How in ASP.NET, do you deal with session and multiple tabs?

I have written an application in ASP.net, that is designed to let the user add records to a database. The page is set up that when a user adds a record, the ID number of the newly added record is set in session, the page Response.Redirects to a "Thank you for submitting" page, then redirects back to the original page to allow further edits. Users can also use the Back button on this screen to go back to the original record adding page, which allows them to make edits to the data.
However, I have found that storing the ID in session isn't a terribly good solution, as a user might try to create two documents in different tabs or windows. I have also tried setting the ID in a literal control, but this causes the problem that when the user uses the Back button, the literal control isn't set to the ID, and new records get added instead of one being edited.
Is there any kind of solution for this?
I'd recommend storing your ID in the QueryString. After the record is added, redirect to your "thankyou" page, which then I am guessing contains a link to the edit form which you will generate with the ID in the querystring. When that link is followed, the edit page shouild pull the ID out of the query string in order to load up the correct record to edit.
Your add and edit form can even be the same page, when an ID is provided in the querystring, your form knows to edit that record, otherwise your form adds a new record.
Silly question, why can the user use the back button to edit the data just accepted in a post?
If the edit previously posted data is a common scenario why not just redirect to a page when the data is accepted that lets them edit it. Then if the hit the back button they would be going back to the original "clean" insert/add new data page.
This would give the following flows
Add->[Post]->Edit->.....
Add->[Post]->Edit->[Back button]->Add->[Post]->Edit->[Post]->Edit....
Have you tried adding the ID in the querystring? Then you could read it, and add it to the session as needed (say on a user clicking the back button).
Seems like a lot of problems allowing editing of an object in a page rendered when using the back button. Would it be too much to give them an edit button instead?
The controls save their state in the ViewState. If you choose to use SessionState instead of ViewState to store the information, then the controls will save their state in the session state and it won't work properly with multiple tabs.
I have not yet found a way to bypass this issue while still using SessionState. Our solution was to use the normal ViewState.
I've tried storing the ID in the querystring (which is mostly fine for editing), but the problem with that is when the information is stored in session for when they use the Back button. If the user does the following:
User creates a record (1st record), the ID is passed along in the querystring, and temporarily stored in session.
User creates another record (2nd record), the ID is passed along in the querystring, temporarily stored in session.
User uses the Back button on the first record to go to the page that doesn't have the querystring.
It's probably a far-fetched scenario, but it's one that may happen. The only solution I have is to block the usage of the Back button to go back to the adding page, by using window.history.forward() in JavaScript. But this as a solution is terrible.
My question for you is why are you storing anything in the session to begin with? If you can avoid storing anything in the session, I think you will be better off altogether.
Having thought about this, does the following sound like a decent solution to the problem I outlined above?
When first adding a record, store a timestamp of when the add page was accessed in a hidden field.
This timestamp is passed through session when the user clicks save. Along with the ID.
If the user opens another tab at the same time and saves, then the new page's timestamp gets passed through session.
If the user tries to access the add page of first record (using the back button), the system looks up session, and sees if there is a timestamp, and whether it matches the one in the hidden field for that page.
If it doesn't match, then the user gets a prompt, and told to edit the record properly.
Does this sound reasonable, or too overly complex?

Resources