Wednesday, September 9, 2015

How do I break out of a DevExpress callback in favor of a postback while also carrying some state along for the ride?

To make a CustomButtonCallback event for a DevExpress ASPxGridView as suggested here download a file as suggested here you cannot have the act occur within a callback. Alright, well you can always use ASPxWebControl.RedirectOnCallback to redirect out of the callback (remember, you cannot use the familiar Response.Redirect of web forms land in a callback) and in redirecting you could just redirect to the same page and then put something at the URL line which you might then drink out of their as state in the Page_Load event. The applicable thing for the file download scenario might be a file path to the file, right? But what if someone then manually refreshes the page? That will cause a second download right? How do we wiggle away from that? I recommend doing something like so:

private void CleanAwayUrlLineVariablesAndSessionStateCounterParts()
{
   string filePath = Session["filePath"] as string;
   if (filePath != null)
   {
      Session["filePath"] = null;
      OfferUpDownload(filePath);
   }
   filePath = Request.QueryString["filePath"] as string;
   if (filePath != null)
   {
      Session["filePath"] = filePath;
      RedirectTheReportToItself(null);
   }
}

 
 

Alright, we are going to call this thing from the Page_Load as the very last act in the Page_Load. OfferUpDownload does what you'd expect and it is our end goal to run that method. If we can get that far then all of the hoops we've jumped through along the way were successfully navigated. RedirectTheReportToItself, as I envision it, will not just be called from this method. If we hand in null we are doing either an ASPxWebControl.RedirectOnCallback or Response.Redirect conditionally based upon...

if (Page.IsCallback)
{

 
 

...while not appending a variable at the URL line, but if the CustomButtonCallback event uses the same method it may hand in a string or something else which will signal the method to, yes, redirect while appending a variable at the URL line. Get it? Anyhow, once will have a URL variable there is no way to make it go away without another Response.Redirect, so let's tuck its contents into Session and then redirect the page to itself to clean up the URL. What will we do about the Session variable? If we yet refresh the page, won't the Session variable be there to force a file download a second time? I guess we have to destroy the Session too. Luckily we can do that without another redirect roundtrip. Could we have just put something in Session to begin with and skipped the Request.QueryString heartache. No we cannot. You cannot shove stuff into Session from a callback kids. Bonus: When I do all this, my page seems to retain other state crafted in callbacks, but I cannot explain why. Whatever.

No comments:

Post a Comment