Showing posts with label redirect. Show all posts
Showing posts with label redirect. Show all posts

Wednesday, March 28, 2012

Why Response.Redirect() opens up a new browser window in AJAX?

I have an AJAX enabled page displayed in amodal dialog, When I click on a button that has a Response.Redirect() code, a new browser window gets opened, which is weird and not the behavior that I expect.

I should note that this page worked properly before adding the AJAX related stuff.

I highly appreciate any insight into this problem.

try use server.transfer


I had already tried the Server.Transfer but I got a client side alert: "Sys.WebForms.PageRequestManagerParserErrorException: The message recieved from the server could not be parsed,..."
Try to navigate to next page in Javascript instead of on Server side. I think this can solve the issue.

hello.

i think the problem is that submitting a page on a popup will open another window by default. you can workaround this by adding an iframe to your popup window which loads the page you need.


Thanks, I think the only workaround to my problem was to use the IFrame in the modal window, but still, I'm wondering why the use of Server.Transfer() caused the error in AJAX, and, why the Response.Redirect() would open up a new window, was I missing somthing or it's just the way AJAX works!

May I ask that Response.Redirect is logical/possible at all during a partial postback (for example in an updatepanel's button click event)?!

Simply move that specific button which yield Response.Redirect outside of the updatepanel, maybe it helps.


Yes, the button which yielded the Response.Redirect() or Server.Transfer() for that matter, was inside the UpdatePanel, I moved it outside the UpdatePanel and my problem was solved. Actually the UpdatePanel was inside a Container UserControl, I think I should make use of UpdatePanel more narrowly focused.

Thank you very much indeed.


response.redirect will be correctly interpreted by the ajax platform. you can check this by using ?a "normal" page. the problem that was happening here was related with modal dialogs and the issue described is not an ajax problem.

server.transfer won't work correctly with ajax and shouldn't be used from controls placed inside the updatepanel. this is understandable because partial postbacks expect to receive a predefined message from the server and whe you do a server.transfer you end up retunring a new page to the user which doesn't conform to the expected message.

So response.redirect works with ajax.

If ajax open the redirected page via javascript (maybe using window.open( ... ) ), that can be a problem.

Modern tabbed browsers are configurable how to treat popup pages from normal links or from javascript (new window, same window, new tab, disable totally javascript popups etc.)

I recommend for Robert to try the page in firefox, and play with advanced firefox settings (type about:config in the address bar, and play with "browser.link.open_newwindow.restriction" and similar settings, you can google for help how it works)

ps:

If the button must be in the updatepanel, maybe it is possible to register a script in the server side which open the new window by javascript (a more controlled way.)


I am also running into this problem and am unable to place the control outside of the Update Panel. I am not clear as to how an IFrame would be implemented. Is it meant that an IFrame should be used in place of the AJAX update panel or in addition to? How would this implementation work specifically?

Thanks for any information in advance.


MaybeScriptManager.RegisterPostBackControl could be used to eliminate this problem in some cases.

So leave your button (which has the codebehind redirect logic) in the updatepanel, but use the RegisterPostBackControl method so it will cause a full normal postback. That way you have a normal redirect, not the ajax client side redirect.


Thanks for the responses.

I did try the following on the control that is being clicked to fire the Redirect:

ScriptManager1.RegisterPostBackControl(this.testButton);

Unfortunately, this still launches a new window during the redirect.

Does anyone have any other ideas as to how i can do this? I would be open to attaching some javascript to the button in order to perform the redirect, however, I have already tried adding the following with no success:

ScriptManager.RegisterClientScriptBlock(this.buttonTest,this.buttonTest.GetType(),"Redirect","window.location = 'http://www.testpage.com'",true);


jriell:

I have already tried adding the following with no success:

ScriptManager.RegisterClientScriptBlock(this.buttonTest,this.buttonTest.GetType(),"Redirect","window.location = 'http://www.testpage.com'",true);

If you choose that way (custom client side redirect), I recommend the following to try:

Put a regular input button, link etc. in the updatepanel, for example:

<input type="button" value="test" onclick="window.location.replace( 'http://www.testpage.com' );" />

If that works, try the script withthe RegisterClientScriptBlock stuff.

Monday, March 26, 2012

Will Application_Error catch any unhandled exception during atlas postback ?

Looks like atlas postback unhandled exception is not comming to Application_Error handler.

Is this right ? or is there any way to redirect any atlas postback unhandled exception to "Application_Error" ?

Thanks,

Perhaps you can utilize the Error Template tag as well as OnPageError event to handle exceptions you encounter in your application.

<atlas:ScriptManager EnablePartialRendering="true"OnPageError="Page_ErrorHandler" runat="server">
<ErrorTemplate>
<div style='width: 450px; height: 300px; padding: 10px; border: solid 3px black; background: #ffd; text-align: left;'>
<h1>Server Error</h1>
<p>Oops looks like we're still working on some code. Administrators have been notified and this emerging issue will be fixed.</p>
<p><input id="okButton" type="button" value="OK" runat="server"/></p>
</div>
</ErrorTemplate>
</atlas:ScriptManager>

Here is the handler for the error.

Import System.Net.Mail

C#

protectedvoid Page_ErrorHandler(object sender, PageErrorEventArgs e)
{

MailMessage mail = new MailMessage();
mail.From = new MailAddress("me@.mycompany.com");
mail.To.Add(you@.yourcompany.com);

mail.Subject = "Error Occured My Application";
mail.Body = "Error Message: e.Error.Message<br /><br />Stack Trace: e.Error.StackTrace<br /><br />Source: e.Error.Source<br /><br />Help Link: e.Error.HelpLink";
mail.IsBodyHtml = true;
smtp.Credentials = new NetworkCredential("username", "secret");
SmtpClient smtp = new SmtpClient("127.0.0.1");
smtp.Send(mail);

//Or perhaps insert it into a database. Or if you feel like it... perhaps the Windows Event Viewer

}

VB

SubPage_ErrorHandler (sender As Object, e As PageErrorEventArgs)

Dim mail As MailMessage = New MailMessage
mail.From = New MailAddress("me@.mycompany.com")
mail.To.Add("you@.yourcompany.com")
mail.Subject = "Error Occured My Application"
mail.Body = "Error Message: e.Error.Message<br /><br />Stack Trace: e.Error.StackTrace<br /><br />Source: e.Error.Source<br /><br />Help Link: e.Error.HelpLink"
mail.IsBodyHtml = True
smtp.Credentials = New NetworkCredential("username", "secret")
Dim smtp As SmtpClient = New SmtpClient("127.0.0.1")
smtp.Send(mail)

End Sub

You can also throw the credentials into the web.config inside the <System.Net> tag like so.

<system.net>
<mailSettings>
<smtpfrom="me@.mycompany.com">
<networkhost="127.0.0.1" port="25" userName="myUsername" password="secret" defaultCredentials="true" />
</smtp>
</mailSettings>
</system.net>

Hopefully that will help a little bit.

JoeWeb


Proposed solution is great. But it requires to create Page_ErrorHandler in every Page whereScriptManager is present. It leads to duplication of code. And it very easy to miss it somewhere.

We're logging all unhandled exception in ASP.NET application onproduction environment and regulary analyze them. Errors that occur during Atlas post-back are not handled because Application_Error is not fired.

Is there any solution to exception handling during Atlas post-backs like Application_Error which is global for all application?

Thanks in advance


What about this? Implement your error handling method for the script manager event as static in a class, and onload of any page with the script manager, all you have to do is assign that static method to the event handler... then you won't be duplicating any code, and its only 1 line of code to add per page.


The ErrorTemplate is no longer supported with Ajax and these are two methods you can use..

In codebehind - I always pull in the scriptmanager so that I can ref it and manage it.

( on your page init)

SM = (ScriptManager)GetControl(skin,"SM");
SM.AsyncPostBackError +=new EventHandler<AsyncPostBackErrorEventArgs>(SM_AsyncPostBackError);

then new event...

void SM_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
{
SM.AsyncPostBackErrorMessage = e.Exception.Message;
bllLogging.RecordError("GridViewModal ScriptManager Error", e.Exception, Severity.Severe, "", "");
}

The BllLogging is my custom error recording routine I use to track error - replace with your own or re-throw it if you have a global exception handler...

In the example above - I use this in a base class which all of my other classes derive from so I only have to code it once...

Alternatively you can also do this on your pages or include in a mycustom.js

<ajax:ScriptManager ID="SM" EnablePartialRendering="true" ScriptMode="Auto" runat="server" />
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(OnEndRequest);

function OnEndRequest(sender,args)
{ // *** Check for errors

if (args.get_error() != undefined /* && args.get_error().httpStatusCode == '500' */)
{
//debugger;
var errorMessage = args.get_error().message
alert("Custom Error Handling:\r\n" + args.get_error().message);
args.set_errorHandled(true);
//var ErrorDisplay = $get("ErrorDisplay_Message");
//ErrorDisplay.innerHTML = "Custom Error Handling:\r\n" + args.get_error().message;
}

}
}
</script>

There also some additional things you can do with assigning custom errors and the likes and is well documented on their documentation site under scriptmanager references...

However, be careful when using the custom error feature - the code behind version does quite well logging actual messages but when in custom mode - whatever is provided as the error text is used (which hides the actual error message...)