4

My page has a submit button on it (server-side button).

Here's my code for the click event:

protected void SubmitButton_Click(object sender, EventArgs e)
{
    db.SaveSomething();
    Page.ClientScript.RegisterStartupScript("someScriptWhichReliesOnServerData");
    Response.Redirect("SomeOtherPage.aspx");
}

Now, the problem is, i register the JavaScript using Page.ClientScript.RegisterStartupScript, but this will have no effect as the page is not being re-rendered on postback (which is where the script WOULD be executed), because instead a Response.Redirect happens.

The only solution i can think is to make the page i redirect to "aware" that im trying to execute some JavaScript, be it QueryString, HttpContext.Current.Items, or (gulp) Session.

  • QueryString - not an option, as it's JavaScript im trying to execute.
  • HttpContext.Current.Items - also not an option because im doing a Response.Redirect (which loses the request-level data, and i also cannot use Server.Transfer because this doesn't play nice with URL Rewriting).
  • Session - of course, but not ideal.

Any other ideas/suggestions?

EDIT for Clarification:

The JavaScript im executing is a call to a Facebook client-side API to publish to the user's wall. It has to be done client-side. I pass to the script things like "title", "message", "action links", etc. Basically a bunch of JSON. But the key here is that this data is created on postback, so i cant just execute this function on client-side click.

So what im trying to accomplish is on submit button click, execute some javascript and do a redirect (does not have to be in that order, just both need to happen).

RPM1984
  • 72,246
  • 58
  • 225
  • 350
  • It would be nice if you could describe "what" you were trying to accomplish as there might be a better solution to the problem. There are many ways to solve the problem, but also many that may be unsuitable to your particular situation. – Josh Aug 25 '10 at 02:15
  • @Josh - question expanded. Any better? – RPM1984 Aug 25 '10 at 02:19
  • Is cross-page postback not an option? – Joseph Yaduvanshi Aug 25 '10 at 02:33
  • @Jim If you've ever worked with ASP.NET Forms, you'll understand that cross-page postbacks are not a simple solution for any situation in ASP Forms :-/ – Dan Herbert Aug 25 '10 at 02:40
  • @Dan I do use Web Forms daily, but I've never had this issue or similar constraints. Also, I've never used cross-page postback, but I was wondering why that wasn't listed as a possibility. Whenever my javascript has relied on some server-side data, I've used AJAX.NET Pro or page methods. I doubt either would be useful in this situation since user information is involved. – Joseph Yaduvanshi Aug 25 '10 at 02:49
  • @Jim, @Dan - cross page post back is not an option, as i dont want to have to try and retrieve Page 1 form values from Page 2. Keep in mind before my changes, Page1 posted back to itself, then redirected to another page (which has no relation to page1). So im trying to avoid Page2 doing work which isnt really its job. – RPM1984 Aug 25 '10 at 02:58
  • Please see my comments on my answer below regarding registering client script and partial page postbacks. – Josh Aug 25 '10 at 03:40

3 Answers3

5

I think what you are experiencing is the unfortunate clashing of two different paradigms here. On the one side you have an AJAX style API you want to take advantage of, and on the other side you have the ASP.Net page postback model.

Now, while these two are not mutually exclusive, it can present some challenges. I agree with Dan that your best bet is to bend a little more towards the AJAX approach instead of the other way around.

A nice feature in ASP.Net is the ability to turn a single static method in your page into a pseudo web service. You can then use the ScriptManager to generate client-side proxy classes to call that method for you, but you can use whatever client side library you want.

A very simple example:

In your codebehind for you Page

[WebMethod]
public static Person GetPerson(Int32 id, String lastName)
{
    return DataAccess.GetPerson(id, lastName);
}

If you were using the ASP.Net AJAX library to handle this for you, then you would need to enable page methods to generate the client-side proxies.

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>

Then you could call that from client-side script like so:

function CallGetPerson() 
{
     var id = $get("txtPersonId").value;
     var lastName = $get("txtLastName").value;
     // PageMethods is a class that is part of the ASP.Net AJAX
     // client-side libraries and will contain your auto-generated
     // proxy methods for making XHR requests.
     PageMethods.GetPerson(id, lastName, OnGetPersonComplete);
}

function OnGetPersonComplete(result)
{
    faceBookApi.DoSomeStuffWithJson(result);
    window.location = "NewPage.aspx";
}

Now again, this is a contrived example, and what you are posting to the server may be very complicated, but you get the general idea of what can be accomplished using the built in framework components.

I hope this helps.

Community
  • 1
  • 1
Josh
  • 44,706
  • 7
  • 102
  • 124
  • thanks. Yeah i know how to use ajax page methods, but the problem is, the form is quite complicated (a lot of fields, a lot of other logic). I would have to encapsulate all of this logic in the web method - not ideal. What im leaning towards at the moment is wrapping the form in an UpdatePanel, and doing it that way (old school ajax, vs the proper way, which is what you've stated). That being said, this is a nice answer (which the upvotes show), so ill give the answer to you. – RPM1984 Aug 25 '10 at 03:29
  • I feared that the form was perhaps too complicated for this, but perhaps that is good motivation to do some refactoring. Using partial page postbacks is a low friction way of doing this, but be advised you will need to use ScriptManager.RegisterStartupScript as Page.ClientScript will not work during a partial postback since only the update panel contents get refreshed. – Josh Aug 25 '10 at 03:39
2

If you use Response.Redirect, the java script you registered at the previous line will not executed. I think what you want to do after clicking the submit button is:

  1. Save something
  2. Execute javascript
  3. Redirect to another page

Here you can use:

protected void SubmitButton_Click(object sender, EventArgs e)
{
    db.SaveSomething();
    Page.ClientScript.RegisterStartupScript("someScriptWhichReliesOnServerData");
    Page.ClientScript.RegisterStartupScript("window.location.href=XXXXXX");
}

That is, using javascript to redirect the page instead of Response.Redirect.

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • I thought of that, but that would re-render the page, then do a redirect after the page has loaded. Not good UX IMO – RPM1984 Aug 25 '10 at 02:21
  • When you click the submit button, of course it will refresh the page. So you want no refreshing? – Cheng Chen Aug 25 '10 at 02:26
  • you're not understanding. On Submit button click of the first page, this posts back to the server, which then does a Response.Redirect - so the SECOND page is rendered. So it doesnt refresh the same page (which would happen by default, if i did not a Response.Redirect), it renders the second page. Know what i mean? – RPM1984 Aug 25 '10 at 02:28
  • so you want the javascript to be executed in the second page, not the first one? You are finding a way to TELL the second page to execute the js? – Cheng Chen Aug 25 '10 at 02:32
  • thats right. I just need to execute some javascript on postback of Page1 and redirect to Page2. As my question states, i cannot register the script on postback of Page1, as the Response.Redirect will ignore that. Therefore i have to somehow execute it on Page2. The question is how to give Page2 enough info to do this. – RPM1984 Aug 25 '10 at 02:35
0

Could you run the JavaScript on the second page?

Other than that, your options are somewhat limited. You could use AJAX to get the data you need from the server and then redirect. That would improve the UX since at the very least you wouldn't have extra page loads to run your intermediary JavaScript.


Another option would be to use Server.Transfer(...), which works similarly to Response.Redirect, but it doesn't send a redirect header to the client. It simply tells the server "stop running the current page and start executing a new page". Context.Items will remain in scope between the 2 classes because you're only transferring the responsibility of responding to the request, not the entire context of the request.


You could also combine these 2 solutions. Use Server.Transfer to keep Context.Items values in scope and then render the JS on the second page using whatever values you kept from the first page.

Dan Herbert
  • 99,428
  • 48
  • 189
  • 219
  • thanks. I've tried Server.Transfer and HttpCOntext.Current.items (as my question stated), but i ran into problems with URL rewriting (Server.Transfer wouldnt work with "~/somecleanurl", it had to be "~/pages/somepage.aspx". But i didnt think of AJAX, might give that a go. – RPM1984 Aug 25 '10 at 03:00