2

Question: what am I missing to get this hack to work?

For the MVC app I'm working on, I've hit an 'unusual' case.

We generate certain reports using ActiveReports, and for users who are allowed, present an ActionLink on our layout that allows access to these reports, which open in a new window. The direction for this project is that all reports shall open in a new window.

However, there's one outlier that I can't apply the easy ActionLink fix to, because we access this report using an overlay that consists of pretty much a dropdown and a textfield. The combination of these is fed to a controller, which returns a redirect to an action based on the given conditions (there are some specific checks that should only occur on the server, thus why we don't just do this in JavaScript on this overlay dialogue.)

Now, I'm not one to let a little limitation like MVC not (directly) allowing me to Redirect to a new Window stop me, so I tried the given JavaScriptResult hack, because this is already a one-offish situation, and it seemed much the easiest and most maintainable solution to my problem, despite being a hack:

public ActionResult GenerateFooReport(string someInfo)
{
    // HACK: MVC does not allow redirects to open a new window, so
    //       return some JavaScript that forces a new window open.
    string script = "window.open('/controller/action?param=" + someInfo + "');";
    return JavaScript(script);
}

Of course, when I run the actions (input of Foo, the correct dropdown option) that lead to this method firing, I see the following output:

window.open('/controller/action?param=foo')

...and not the report that that piece of JavaScript is supposed to be automatically opening.

While I understand that this usage is (in most circumstances) considered an antipattern, I am not free to modify the UI to accomodate a more acceptable usage.

Question: what am I missing to get this hack to work?

EDIT: Attempted an alternate implementation which also did not work:

private ActionResult GenerateFooReport(string someInfo)
{
    // HACK: MVC does not allow redirects to open a new window, so
    //       return some JavaScript that forces a new window open.
    string script = "<script>window.open('/controller/action?param=" + someInfo + "');</script>";
    return Content(script);
}

This similarly had no effect.

EDIT: Another unsuccessful attempt at the hack:

private ActionResult GenerateFooReport(string someInfo)
{
    // HACK: MVC does not allow redirects to open a new window, so
    //       return a redirect to a url that executes javascript that
    //       opens the new window.
    string script = "javascript:window.open('/controller/action?param=" + someInfo + "');";
    return Redirect(script);
}

EDIT: The evil of this situation has had great influence! New direction has come to avoid these evil operations in the controller and instead do them in JavaScript. That being said, I am still curious to the actual way to get the hack to work, just for my own edification.

AstroCB
  • 12,337
  • 20
  • 57
  • 73
Andrew Gray
  • 3,756
  • 3
  • 39
  • 75
  • 3
    Why is your controller doing this work? It should really just be a click event on an action link. – Mathew Thompson Mar 05 '13 at 15:45
  • This is a rewrite of an older application, which had this 'dashboard' that, if a certain dropdown action was selected, would open a report instead of an input form. The directive is that the web app shall behave like the legacy app, thus why I have to do it this (evil, awful) way. If I had my way, I'd add ActionLinks where appropriate and wash my hands of this. – Andrew Gray Mar 05 '13 at 15:46
  • 1
    Yeah that's fine, but couldn't you replace the controller action with just a JavaScript function? Something that just calls `window.open` given a parameter? – Mathew Thompson Mar 05 '13 at 15:48
  • There are some other conditions that need to be evaluated on the server, and in any event are outside the purview of my question. The restriction here is not so much a technological one as a business one, thus the evil hack. – Andrew Gray Mar 05 '13 at 15:51
  • Fair enough, then you're best off using a jQuery ajax method to call it, have your action method return json containing the url to go to (as a string), then on the success of your ajax method, call `window.open` using the returned URL. – Mathew Thompson Mar 05 '13 at 15:54
  • Aaaah, but that's why this situation is evil. If everything this dialogue were responsible for were reports, I'd do just that (or, forget the 'overlay that communicates with the server', and just have an overlay consisting of report links.) In two of the three dropdown conditions, the correct behavior is to open some other view; the report is a similarly business-essential one-off that pretty much forced this question in the first place. I know you're trying to find smart ways around this (too), but I've already asked those questions. My shop wants it done a weird way. – Andrew Gray Mar 05 '13 at 15:57
  • Classic case of business rules destroying beautifully crisp logic :). That aside, what exactly is your question? Is it broken? Does it need fixing? – Mathew Thompson Mar 05 '13 at 16:02
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/25611/discussion-between-andrew-gray-and-mattytommo) – Andrew Gray Mar 05 '13 at 16:04
  • 2
    Popup could be blocked.. – Bharath Mar 05 '13 at 16:11
  • Popup appears just fine. When I execute the actions, I get the raw text. Please *actually read the post*. Thank you. – Andrew Gray Mar 05 '13 at 16:13
  • post the client-side script that request this action – Bharath Mar 05 '13 at 17:16
  • it sounds to me like mattytommo's suggestion will work. you say that the overlay dialog is doing other things, so you can't really change it's behaviour. Jquery is pretty powerful - you should be able to code something in Jquery for the overlay that essentially does "for conditions x and y, do what you normally do, but for condition z, do as 'mattytommo' suggests" – StanK Mar 06 '13 at 04:14
  • That's what we wound up doing. Upon my shop being faced with the stark truth of the situation, they agreed that doing like mattytommo said, and when the dropdown box is 'x', suppress the default behavior of the button, perform an AJAX call to figure out the URL of the report, then do a window.open() on that URL. So problem solved a more correct way than what I was originally led to believe I had to do. :) Everyone wins! (Sort of, it's still messier than I would like, but eh. I'll take this victory.) – Andrew Gray Mar 06 '13 at 15:30

1 Answers1

1

Try calling the jquery .load function directly instead.

return JavaScript("$('#targetdiv').load('controller/action?param="+someInfo+"');");
  • Didn't know about that - the next time I go back to playing with the hack situation (resolved long ago, fortunately), I'll give that a try! – Andrew Gray May 09 '13 at 19:30