How to handle user refresh of page - asp.net-mvc

this sounds quite basic...
I have views that are built in controllers with some input argument (from previous page) and more stuff like getting data from TempData[] and more.
public ActionResult Submit(SubmitDetails submitDetails)
{
var x = (long)TempData["SomeMoreValue"];
// do stuff
return View("NextView", someInputModelThatIHaveBuilt);
}
Everything is working, but when I hit refresh on Next view, got Resource not found...
My Question - what is the practice to keep it up with the info you need in "NextView" to survive user refresh...

Have you tried using:
TempData.Keep();

Related

How to attach a new BrowserWindowOpener to a button, without destroying the button first?

on Vaadin 7 I have the working code :
private void gridAttachmentsClickItemEventAction(ItemClickEvent event) {
// blablabla some code to get the data from the repository
byte[] data = bibocoAttachmentResponseEntity.getBody().getContent();
StreamResource.StreamSource source = convertByteArrayToStreamResource(data);
String filename = "c:\\droppdf\\"
+"temp"+bibocoAttachmentResponseEntity.getBody().getFileName()+LocalDate.now().toString();
StreamResource resource = new StreamResource(source, filename);
resource.setMIMEType("application/pdf");
resource.getStream().setParameter("Content-Disposition", "attachment; filename=" + filename);
BrowserWindowOpener opener = new BrowserWindowOpener(resource);
opener.extend(btnAttachmentPreview);
}
When I click on a grid row, the data is collected from that grid
and code following on it gets the data byte[] from a repository by calling a service.
Afterwards, when the user clicks on btnAttachmentPreview a new browser tab opens
and shows the pdf (that's what's in the data byte[])
This works fine the first time, but when I select a new row in the grid,
the problem is that the second call does not set the listener to the button right.
It show the first data byte[] again in a new tab, not the current data ...
The method is accessed, the correct data[] has been loaded in the array the second time, I checked.
I believe the listener on the btnAttachmentPreview attached due the code
opener.extend(btnAttachmentPreview);
should be binned (empty'ed or nulled) first. But I have no reference to it as for as I can tell.
Problem is that I don't want to destroy the btnAttachmentPreview object.
(The btnAttachmentPreview is a global variable and is set to a layout that I may not change. I know, not nice, but it's a ancient product)
When I close the browser and restart and clicking another row, the right data byte[] is showed.
Anyone a clue ?
Any help appreciated
You can remove an extension using its remove() method, i.e. opener.remove();.
If you cannot easily structure your code to store a reference to the old opener so that you have it available when you want to add a new one, then you can use btnAttachmentPreview.getExtensions() to get a collection of all current extensions and then from that you can find the appropriate extension (if any) and call remove() on it.

Editing a BrowserField's History

I have a BrowserField in my app, which works great. It intercept NavigationRequests to links on my website which go to external sites, and brings up a new windows to display those in the regular Browser, which also works great.
The problem I have is that if a user clicks a link to say "www.google.com", my app opens that up in a new browser, but also logs it into the BrowserHistory. So if they click back, away from google, they arrive back at my app, but then if they hit back again, the BrowserHistory would land them on the same page they were on (Because going back from Google doesn't move back in the history) I've tried to find a way to edit the BrowserField's BrowserHistory, but this doesn't seem possible. Short of creating my own class for logging the browsing history, is there anything I can do?
If I didn't do a good job explaining the problem, don't hesitate for clarification.
Thanks
One possible solution to this problem would be to keep track of the last inner URL visited before the current NavigationRequest URL. You could then check to see whether the link clicked is an outside link, as you already do, and if it is call this method:
updateHistory(String url, boolean isRedirect)
with the last URL before the outside link. Using your example this should overwrite "www.google.com" with the last inner URL before the outside link was clicked.
Here is some half pseudocode/half Java to illustrate my solution:
BrowserFieldHistory history = browserField.getHistory():
String lastInnerURL = "";
if navigationRequest is an outside link {
history.updateHistory(lastInnerURL, true);
// Handle loading of outer website
} else {
lastInnerURL = navigationRequest;
// Visit inner navigation request as normal
}
http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/browser/field2/BrowserFieldHistory.html#updateHistory(java.lang.String, boolean)
I had a similar but a little bit different issue. Special links in html content like device:smth are used to open barcode scanner, logout etc and I wanted them not to be saved in BrowserFieldHistory. I found in WebWork source code interesting workaround for that. All that you need is throw exception at the end like below:
public void handleNavigationRequest( BrowserFieldRequest request ) throws Exception {
if scheme equals to device {
// perform logout, open barcode scanner, etc
throw new Exception(); // this exception prevent saving history
} else {
// standard behavior
}
}

ASP.net MVC - IE9 has an extra item with an empty key in forms collection

I have a bit of an odd problem, and I'm struggling to track down the root cause...
I have an ASP.net MVC site, and recently one of my colleagues started using IE9, and noticed a problem with one of the pages - it wasn't updating on click of save.
I figured that this would probably be a script issue, as there is a fair bit of jQuery used on this page, and it may still be, but:
If I submit this page in Chrome (or in IE8/7/6), then I get a forms collection with 11 items in it, as I would expect. If I submit the same page in IE9, I get an extra item at the end of the collection which has an empty string as key and an empty string as the value. This causes the call to UpdateModel() to not work (but not throw an exception) - none of these values are updated in my object, and the ModelState is still showing as valid.
So far, I've only found this one page, but I'm curious if anybody might know what is causing this?
Update 04/04/2011 - Narrowed down the culprit:
I removed bits of code until this worked and narrowed it down to some code in my validation. I use the jQuery validate plugin, and had the following as a submit handler (some redaction performed on names...):
submitHandler: function (form) {
var submitForm = true;
var newValue, originalValue;
newValue= $("#newValue").val();
originalValue= $("#originalValue").val();
if (newValue!= originalValue) {
//affectedValues is an array populated at the top of the page.
if ($.inArray(originalValue, affectedValues) != -1 &&
$.inArray(newValue, affectedValues) == -1) {
submitForm = confirm("Are you sure you want to do this");
}
}
if (submitForm) {
form.submit();
}
},
Removing this from the code (which I can thankfully do, as it's a bit of legacy code), seems to make this work, my empty item in the forms collection is gone. If anybody has any idea why this might have been happening, that'd be great.
Might be worth checking all the form fields in firebug to see if you have any un-named elements? I know I got caught out by the Select behaviour in IE before.
pdate 04/04/2011 - Narrowed down the culprit:
I removed bits of code until this worked and narrowed it down to some code in my validation. I use the jQuery validate plugin, and had the following as a submit handler (some redaction performed on names...):
submitHandler: function (form) {
var submitForm = true;
var newValue, originalValue;
newValue= $("#newValue").val();
originalValue= $("#originalValue").val();
if (newValue!= originalValue) {
//affectedValues is an array populated at the top of the page.
if ($.inArray(originalValue, affectedValues) != -1 &&
$.inArray(newValue, affectedValues) == -1) {
submitForm = confirm("Are you sure you want to do this");
}
}
if (submitForm) { form.submit(); }},
Removing this from the code (which I can thankfully do, as it's a bit of legacy code), seems to make this work, my empty item in the forms collection is gone. If anybody has any idea why this might have been happening, that'd be great.
I had some problems with my MVC sites due to the caching features introduced for IE9. My work around was to disable caching in my controller by adding an attribute:
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class FaxController : Controller
FF, Chrome, Opera sends just value of FORM elements (button, input,..) with NAME.
IE always sends elements to server, even Submit with empty name and value which causes error.
So to be sure, always name elements.

ie9: annoying pops-up while debugging: "Error: '__flash__removeCallback' is undefined"

I am working on a asp.net mvc site that uses facebook social widgets. Whenever I launch the debugger (ie9 is the browser) I get many error popups with: Error: '__flash__removeCallback' is undefined.
To verify that my code was not responsible I just created a brand new asp.net mvc site and hit F5.
If you navigate to this url: http://developers.facebook.com/docs/guides/web/#plugins you will see the pop-ups appearing.
When using other browsers the pop-up does not appear.
I had been using the latest ie9 beta before updating to ie9 RTM yesterday and had not run into this issue.
As you can imagine it is extremely annoying...
How can I stop those popups?
Can someone else reproduce this?
Thank you!
I can't seem to solve this either, but I can at least hide it for my users:
$('#video iframe').attr('src', '').hide();
try {
$('#video').remove();
} catch(ex) {}
The first line prevents the issue from screwing up the page; the second eats the error when jquery removes it from the DOM explicitly. In my case I was replacing the HTML of a container several parents above this tag and exposing this exception to the user until this fix.
I'm answering this as this drove me up the wall today.
It's caused by flash, usually when you haven't put a unique id on your embed object so it selects the wrong element.
The quickest (and best) way to solve this is to just:
add a UNIQUE id to your embed/object
Now this doesn't always seem to solve it, I had one site where it just would not go away no matter what elements I set the id on (I suspect it was the video player I was asked to use by the client).
This javascript code (using jQuery's on document load, replace with your favourite alternative) will get rid of it. Now this obviously won't remove the callback on certain elements. They must want to remove it for a reason, perhaps it will lead to a gradual memory leak on your site in javascript, but it's probably trivial.
this is a secondary (and non-optimal) solution
$(function () {
setTimeout(function () {
if (typeof __flash__removeCallback != "undefined") {
__flash__removeCallback = __flash__removeCallback__replace;
} else {
setTimeout(arguments.callee, 50);
}
}, 50);
});
function __flash__removeCallback__replace(instance, name) {
if(instance != null)
instance[name] = null;
}
I got the solution.
try {
ytplayer.getIframe().src='';
} catch(ex) {
}
It's been over a months since I last needed to debug the project.
Facebook has now fixed this issue. The annoying pop-up no longer shows up.
I have not changed anything.

Grails web flow problem with browser's back button

I'm having problems to get browser's back button work properly on web flow.
Version of grails is 1.1.2.
Imagine example code:
def someFlow = {
...
fillGroup {
on("addMember"){
...
}.to "fillMember"
}
fillMember {
on("addMember") {
...
}.to "fillMember"
on("goToCart").to "showCart"
}
showCart {
...
}
}
Now, I add group, several (>1) members and go to cart. Problem is that during filling the members the URL remains the same. URL execution parameter changes only if the state (view) changes.
So Firefox remembers fillMember pages as one page because the URL doesn't change. Therefore back button doesn't work properly. If I am on showCart and push back, I get to fillMember page. Further push of back button returns fillGroup. I need it to go through all the fillMember pages.
Is there any way to force Grails web flow to change the execution parameter even though I redirected to the same state? Or can I put my own parameter into the URL?
I found one pretty ugly way how to do that: use two fillMember states - fillMember1 and fillMember2, both doing the same thing, one redirects to another. But I need one more action state to be able to distinguish the actual state when hitting back and forward buttons. This construct works but I'd prefer easier way.
Thanks for any answers
Tom
So far, the only solution I've found is the one I mentioned. Use two view states, both doing exactly the same thing, and one action state to hold some state information (it would be difficult to properly distinguish processed member without it). The code would be something like this:
def someFlow = {
...
fillGroup {
on("addMember"){
...
}.to "fillMemberLogic"
}
fillMemberLogic {
action {
...
flow.stateinf += 1
if(flow.stateinf%2 == 1)
return gotoFillMember1()
else
return gotoFillMember2()
}
on("gotoFillMember1").to "fillMember1"
on("gotoFillMember2").to "fillMember2"
}
fillMember1 {
on("addMember") {
...
}.to "fillMemberLogic"
on("goToCart").to "showCart"
}
fillMember2 {
on("addMember") {
...
}.to "fillMemberLogic"
on("goToCart").to "showCart"
}
showCart {
...
}
}
Since the view is being changed for every member, the execution parameter is also being changed and URL is distinct for every member. Firefox distinguishes viewed pages according to URL, so you can go back and forth through all the members using back and forward buttons.
Web flow is mapping URL with current state of flow object. Therefore it's easily possible to distinguish the current member you are processing after several back button pushes.

Resources