ASP MVC 3 prevent multiple inserts on page refresh - asp.net-mvc-3

Let's say I have a simple ASP MVC3 list controller, with an add method, with an id parameter.
List:
http://localhost/MVCAPP/ListFoo/
Add method
http://localhost/MVCAPP/ListFoo/Add?id=1
In my Add method, I update my Viewmodel with the added element, then makes a call to:
return View("ListFoo", viewModel);
The updated list is displayed, and everything's almost fine.
The problem is that with such a return, the URL in the address bar is still
http://localhost/MVCAPP/ListFoo/Add?id=1
And if the user hits F5, another item will be added, which I'd like to prevent.
I know I can filter out such a behavior in the controller, but I'd rather prefer to redirect the browser address bar to:
http://localhost/MVCAPP/ListFoo/
Do you know any way to do this?
By the way, I'm not sure trying to control the address bar content is the right way to look at this issue...

Use the Action.RedirectToAction method to redirect the client after the work is done in the controller.
Besides that, you could use POST as FormMethod to send data to the server.

That is why you need to use PRG: Post-Redirect-Get when you are doing any such form post.
Have a look here.
So the best option is to redirect the user to a GET method to display the page.

Related

Communication between view and controller in mvc 3

Imagine I have a form (Page1.cshtml) with 1 link (LinkBrands). I also have a controller for Page1 (Page1Controller) and one for brands (BrandController). When the user clicks the link what is better to do:
LinkBrands-->Page1Controller-->BrandController (Page1Controller's action will redirect to BrandController)
OR
LinkBrands-->BrandController
Not sure what route is better. Any suggestions?
Usually you don't have a single controller per view. You would use multiple views or partial views all calling actions on the same related controller. I assume Brand is a separate entity from whatever else Page1 is trying to display, therefore it should probably use the BrandController directly but since there really isn't enough information to go on with your example as to what page1's function is I couldn't say what you are trying to relate.
If you need to capture information from the brand link as it relates to page1 then sure have it collect that in page1controller first before redirecting to brandcontroller to display a new view.
What does your Page1Controller do?? It seems as though you are defeating the purpose of the Model-View-Controller architecture and trying to form it back to the WebForms method with code-behind.
So without seeing what exactly your controllers are doing, I'd say your second option is best.
It all depends.
If you have to execute any logic in Page1Controller (saving data for instance) before displaying the second page, then you need to go by Page1Controller, and then go to BrandController:
LinkBrands-->Page1Controller-->BrandController
In case you just need to redirected to the second page (you do not need anything from Page1Controller, you do not need it to perform any action, and you can create a the model for second page in BrandController) then go with the second option:
LinkBrands-->BrandController
Hope this helps.

ASP.NET MVC Redirect to action without a physical redirect

Are it in any way possible to execute another action in the same on in another controller from an action, action filter or in any other way without doing a physical redirect.
The reason for this is that I have a dynamic paging system, where the user will load a url, for an example
/1/some-page-title
This url is maped to the controller “Home” and the action “Element”, this action will then load a row from the database where the element id is “1”. Depending from the data on the element from the database will the page be rendered as a contact form, an image gallery and so on.
Now I could map the paths so
/Page/1/some-title/ will render a normal html page,
/Contact/1/some-title/ will render a contact form
/Gallery/1/some-title/ will render a gallery
But I would prefer the paths to be simple.
There are problems with this answer, it's been a long time since I did anything thing with ASP MVC, so I'm not actually aware of what the problems are.
Unfortunately I can't delete an accepted answer.
So, I'm striking through the answer as it was, if you can actually answer this, or make it better, please do so.
Yes, very simple really :)
Say you're in controller C action A. You want to "redirect" to controller B action Z, just call the other controller action from the current one, returning it's result.
public ActionResult A()
{
return B.Z()
}
You may be looking for Html.RenderAction or Html.Action. However, these are used in the view and not the controller.

Problem showing a messaje to the user using ASP MVC TempData

I'm using TempData to show a message to the user. I put a string in the TempData and later I read the string, and if it is not empty, then I show a DIV that contain the message.
All works fine, and if the user refresh the page the message are not shown (Thats what I want). The problem is that if the user navigate to other page and then press the back button in the browser, then the message are shown again, and I do not want this.
What could I do to avoid this behaviour?
Thanks.
This is the code I use to read the TempData (Razor + VB). There is a DIV #commonMessage, with this code I put the string inside the div and show it. As I said before, it's working, but the only problem is that the TempData is still there if the user click back in the browser.
#If Not IsNothing(TempData("MessageUser")) AndAlso TempData("MessageUser") <> String.Empty Then
Dim str As String = TempData("MessageUser")
#<script type="text/javascript">
$(document).ready(function () {
$('#commonMessage').html("#str");
$('#commonMessage').delay(400).slideDown(400).delay(4000).slideUp(400);
})
</script>
End If
EDIT: Seems like the TempData are being catched, because if I Disable the cache for the action where I'm showing the message (Using the Attribute System.Web.Mvc.OutputCache(NoStore:=True, Duration:=0, VaryByParam:="*")) the problem dissapears. But It would be better I we could find a method that not involve disabling the cache...
REQUESTED EDIT: I'm very newby in ASP, so I try to clarify what i'm triying to do. When an user performs an action (edit a client, for example), I redirect the client to the client list page, and I show a message that tell to the user "The client data was update susessfully". I'm triying to do it in a way that makes the message to be show only once. Maybe the TempData is not the right way (I don't know, 'cos i'm learning yet), but the target is to show a message to an user only once (no matter if the urser refresh or if the user go to other page and then press back in the browser)... using TempData or using something more adequate to our purpose.
Essentially, you are wanting TempData to do what you want, rather than using the right tool for what you want.
TempData is, by design, intended to be used for caching data across HTTP redirections. That is what it exists for. It is not clear from your post if this is the scenario that you are using.
Ie:
Page redirection, with data in TempData, that is then displayed to the user. Refresh the page you have arrived on, and the TempData is no longer there (there has been no redirection, just a refresh).
If the user then navigates to another page, then uses the back button, the browser will have cached the html of your page and will redisplay that. That is the correct behaviour.
I also think that in your testing, you are getting it wrong. Ie, by disabling the caching, you are just knocking out TempData altogether and you will not get the correct behaviour. Ie, the message will NEVER appear, not just when you hit the back button.
Your jQuery looks inefficient. You are making it do things it doesn't need to do. You could use razor to populate your div with your message. Set the div to not display, ie:
<div id="commonMessage" style="display:none;">
Then use jQuery to show it:
$('#commonMessage').show();
Your post isn't that clear, but in summary, I would say you are seeing what you should.
Maybe you should describe, in an Edit, what you want your app to do. That way it would be easier to answer. As things stand, you have told us what happens and what you put in your view, but it is not clear what you expect.
You should also understand TempData better: it only persists between Controller actions, ie, when a redirect occurs. It stores its data in the Session store, which I believe is affected by the caching attribute you mention.

CodeIgniter jQueryUI dialog form example

I am trying to use CodeIgniter and jQuery-ui dialog to create a modal window with form to update user information.
The process should be like:
1. Press a button on a view page.
2. A modal window pops up.
3. Inside the window is a form that a user can fill.
4. If the user filled something before, the information should be shown in corresponding field
5. Click the update button on the modal window to save the changes to database.
Can anyone provide a good sample of this process?
I used ajax to pass the data but it didn't work when I was trying to update the data to the database. It would be nice if an example of how to pass data from ajax to php and how php handle that.
Thanks,
Milo
well the jquery bit for post(), get(), ajax() works the same in any measure you would normally use it.. key difference here is with CI you can't post directly to a file-name file-location due to how it handles the URI requests. That said your post URL would be the similar to how you would access a view file normally otherwise
ie: /viewName/functionName (how you've done it with controllers to view all along. post, get, ajax doesnt have to end in a extension. I wish I had a better example then this but I can't seem to find one at the moment..
url = '/home/specialFunction';
jQuery.get(url, function(data) {
jQuery("#div2display").html(data);
});
in the case of the above you notice despite it not being a great example that. you have the url with 2 parameters home and specialFunction
home in this case is the controller file for home in the control folder for the home file in views the specialFunction is a "public function" within the class that makes the home controller file. similar to that of index() but a separate function all together. Best way I have found to handle it is through .post() and a callback output expected in JSON cause you can form an array of data on the php side json_encode it and echo out that json_encode and then work with that like you would any JSON output. or if your just expecting a sinlge output and not multiples echoing it out is fine but enough of the end run output thats for you to decide with what your comfortable doing currently. Hopefully all around though this gives you some clairity and hopefully it works out for you.

How can I add a URL parameter but hide others in a POST - Spring MVC

I'm trying to add a URL parameter within a Spring MVC application. It's a basic search page that shows results.
In the search page, there is a form that is set to POST. There are many hidden fields and other fields I don't want in the URL. So, I don't want to do a GET.
I do want the search query in the URL. So after clicking the search button, the resulting search results page needs to have a URL like /search?query=hello
To get it to work, I'm creating a RequestMapping method in the Spring MVC Controller and doing a redirect: tacking on the query parameter. However, I'm not sure using a redirect is the best answer, seems there could be performance concerns redirecting as well.
I looked around and noticed folks using javascript and the location object, but setting the location object obviously relaunches the URL you set it to. I also looked at the HTTPServletResponse & HTTPServletRequest objects, but couldn't find much.
Any thoughts on how I can force the search parameter to be added to the URL?
Your form will have an 'action' specified telling it where to POST to. I'd have thought you could attach an onclick event to your submit button (or an onsubmit event to your form) that updates the action url by appending "?query=" to it.
document.<form name>.action += "?query=...";
Then you just have to worry about someone posting your form without JavaScript enabled - in this case you could fall back to your redirect.
I don't know how the server technology so I can't say if it will be happy giving you both GET and POST parameters, if not you'll have to manually strip the GETs out of the URL.
But anyway, this seems like a rather odd situation to be in - is it really that big a deal to show the parameters in the URL? Anything that gets posted by an HTML form can still be inspected with the right tools, it's just ever so slightly more difficult.
I wanted to provide a more complete answer to my question with code. The previous user helped me down this path, so I'll keep it as the accepted answer. However, there is one item to note:
If you add on to the action, and you have an input text box with the same name, the page posts a duplicate value like: query=hello,hello.
So, I needed to remove the name on the input box, and use the following javascript. Note, I am using the prototype.js framework:
Event.observe(window, 'load', function(event) {
Event.observe('searchForm', 'submit', function(event) {
$('searchForm').action += "?query="+$('searchBox').value;
});

Resources