PageReference from embedded Visualforce page becomes inlined

I managed to hack my way around it by using JavaScript in the command button oncomplete to do the redirection from the top level window.

Simplified Page:

My reality is a bit more complicated as the Command button is a dynamic Visualforce component.

E.g. public PageReference stubAction() { return null; }

public PageReference editDynamicProperties() {
    PageReference editpr = Page.AnotherPage;

    Map<string, string> params = editpr.getParameters();
    params.put('oppId', opportunityFromController.Id);

    editpr.setRedirect(true);
    return editpr;
}

public Component.Apex.OutputPanel getDynamicPropertyControls() {
    //...

    Component.Apex.PageBlockButtons pbButtons = new Component.Apex.PageBlockButtons();
    pb.childComponents.add(pbButtons);

    Component.Apex.CommandButton editCommandButton = new Component.Apex.CommandButton();
    editCommandButton.value='Edit';
    //editCommandButton.expressions.action = '{!editDynamicProperties}';
    editCommandButton.expressions.action = '{!stubAction}';

    editCommandButton.rerender= new Set<string>{'dynamicForm'};
    editCommandButton.oncomplete= 'window.top.location.href = \''+editDynamicProperties().getUrl()+'\'';
    pbButtons.childComponents.add(editCommandButton);

    //...
}

UPDATE: Apparently I've come across this problem before. See Visualforce Page embedded in a detail page that needs to redirect to other page That question had a very similar answer by JCD, but the redirection was handled by the rerendered component.


As a simpler alternative to the first answer, you could also start using a simple <apex:outputLink> without an action attribute, but simply using the value attribute. Like so

<apex:outputLink value="{!$Page.somePage}?oppId={!opportunityFromController.Id}" target="_top">click here</apex:outputLink>

That will give you a URL without the inline part in it.