MVC extending controller to have ajax-aware Redirect functionality
Asked Answered
M

2

6

Hi I am learning Ajax + MVC. I figured it would be nice for the Controller to automatically handle ajax-aware Redirect(). After some digging, I found the code from this link. The code below is totally transparent to user, a user can just call Redirect(someUrlString) without needing to worry about difference between normal/ajax calls. Makes it very neat and cool.

public abstract class BaseController : System.Web.Mvc.Controller {
    //turn into ajax aware redirect
    protected override RedirectResult Redirect(string url) {
        return new AjaxAwareRedirectResult(url);
    }
}

and ...

public class AjaxAwareRedirectResult : RedirectResult {
    public AjaxAwareRedirectResult(string url) : base(url) { }
    public override void ExecuteResult(ControllerContext context) {
        if (context.RequestContext.HttpContext.Request.IsAjaxRequest()) {
            string desturl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);
            JavaScriptResult result = new JavaScriptResult() { 
                                      Script = "window.location='" + desturl + "';" };
            result.ExecuteResult(context);
        }
        else { base.ExecuteResult(context); }
    }
}

However, it is not complete. Challenge is:

RedirectToRouteResult RedirectToAction(ActionResult result)

is not there yet (Very handy especially for T4MVC).

As I am still new to MVC, I tried, but I am not knowledgeable enough to sufficiently figure out how to write this myself. Could any of you experts please help me with this? so I can learn it from your code? Thank you very much.

Mano answered 24/6, 2012 at 6:52 Comment(0)
G
7

Here is the quick simple solution I use for Ajax aware redirection in my project..

  1. Create a class AjaxRedirectAttribute for action.

        public class AjaxRedirectAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                var result = filterContext.Result as RedirectResult;
                if (result != null && filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    string destinationUrl = UrlHelper.GenerateContentUrl(result.Url, filterContext.HttpContext);
                    filterContext.Result = new JavaScriptResult()
                    {
                        Script = "window.location = '" + destinationUrl + "';"
                    };
                }
            }
        }
    
  2. User this attribute as below to either redirect to other page or to return some result from action.

    [AjaxRedirect]
    public ActionResult MyAction(FormCollection frmcol)
    {
        // some code here
        if (UserId != 0)
        {
            return Redirect(this.Url.Action("Action", "Controller"));
        }
        else
        {
            return Content("Error message here.");
        }
    }
    
Guerin answered 25/6, 2012 at 10:58 Comment(0)
R
0

This is a good solution that work with MVC exception handling for Ajax (Ajax.BeginForm or jquery.ajax) call.

So, as you know there is an Application_Error in global.asax.cs file. Can you let me know how to handle ajax call here with for "JavaScriptResult" result.

I am using "RedirectToRoute" to handle it, but in some of code it is appending the html with existing header. My error controller has no layout (_Layout=null), but still it is showing header and footer.

I am just working to a fresh RedirectToRoute call.

 Response.RedirectToRoute("Default", new {controller = "Error", action = "Error"});



protected void Application_Error(object sender, EventArgs e)
        {
            RouteValueDictionary routeDataCollection = HttpContext.Current.Request.RequestContext.RouteData.Values;
            if (null != routeDataCollection && routeDataCollection.Count()>1)
            {
                Server.ClearError();
                 Response.RedirectToRoute("Default", new { controller = "Error", action = "Error"});
             }
        }

Thanks

Sagar

Retha answered 29/4, 2015 at 6:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.