Is there any way I can implement a convenience method that uses a Controller's protected method(s) without using a base controller, which is recommended against here? For example, I want to return an ActionResult based on whether a returnUrl query string param has been passed. What I really want is an extension method like this:

public static class ControllerExtensions {
    public static ActionResult RedirectReturnUrlOrDefaultAction(this Controller thisController, string returnUrl, string defaultAction) {
        if (!string.IsNullOrEmpty(returnUrl) && thisController.Url.IsLocalUrl(returnUrl)) {
            return thisController.Redirect(returnUrl);
        }
        else {
            return thisController.RedirectToAction(defaultAction);
        }
    }
}

So that I could then say this:

return this.RedirectReturnUrlOrDefaultAction(Request.QueryString["returnUrl"], "Index");

... from within a Controller. But of course that extension method doesn't compile because for some reason, methods like Redirect are protected internal (why are they protected internal, by the way?)

Is there a decent way I can do this without using a base controller? If not, might this be one good reason to actually use a base controller, or is there something flawed with my design?

有帮助吗?

解决方案

What about:

public static class ControllerExtensions {
    public static ActionResult RedirectReturnUrlOrDefaultAction(this Controller controller, Func<string, ActionResult> returnUrlRedirectAction, Func<ActionResult> defaultAction) {
        string returnUrl = controller.Request.QueryString["returnUrl"];
        if (!string.IsNullOrEmpty(returnUrl) && controller.Url.IsLocalUrl(returnUrl)) {
            return returnUrlRedirectAction(returnUrl);
        }
        else {
            return defaultAction();
        }
    }
}

This can then be used in the controller as:

return this.RedirectReturnUrlOrDefaultAction(ret => Redirect(ret), () => RedirectToAction("Index"));
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top