After I search some related question in Stackoverflow, I just realize that any redirect action in ASP.NET sends HTTP 302 code to browser. After that, browser will create new request to fetch new URL (that can be found in HTTP 302 header).
Therefore, it is impossible to directly send any complex objects (without serialize it) to browser and order browser to send it back to server. Although, it is possible, but I think it is so silly to do that. Because you can use the following code to call another action without send HTTP 302 to browser.
public class TransferResult : ActionResult
{
public TransferResult(string controllerName, string actionName, RouteValueDictionary routeValues = null)
{
RouteValues = routeValues ?? new RouteValueDictionary();
if (!string.IsNullOrEmpty(controllerName))
{
RouteValues[MvcApplication.ControllerRouteKey] = controllerName;
}
if (!string.IsNullOrEmpty(actionName))
{
RouteValues[MvcApplication.ActionRouteKey] = actionName;
}
if(RouteValues[MvcApplication.ControllerRouteKey] == null)
{
throw new ArgumentException(Resources.ControllerNameIsNotFoundInRouteValueDictionary, "controllerName");
}
if (RouteValues[MvcApplication.ActionRouteKey] == null)
{
throw new ArgumentException(Resources.ActionNameIsNotFoundInRouteValueDictionary, "actionName");
}
}
public TransferResult(RouteValueDictionary routeValues)
: this(null, null, routeValues)
{
}
public RouteValueDictionary RouteValues { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var routeData = new RouteData();
foreach (var item in RouteValues)
{
routeData.Values.Add(item.Key, item.Value);
}
var contextWrapper = new HttpContextWrapper(HttpContext.Current);
var request = new RequestContext(contextWrapper, routeData);
var controller = ControllerBuilder.Current.GetControllerFactory().CreateController(context.RequestContext, RouteValues[MvcApplication.ControllerRouteKey].ToString());
controller.Execute(request);
}
}
Next, I create some handle error for handling some error type and transfering it to another action controller.
public class SomeHandleErrorAttribute : HandleErrorAttribute
{
public SomeHandleErrorAttribute (string controllerName, string actionName)
{
ExceptionType = typeof (EntityException);
ControllerName = controllerName;
ActionName = actionName;
}
public string ControllerName { get; set; }
public string ActionName { get; set; }
public override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
if(filterContext.Result != null)
{
var routeValue = new RouteValueDictionary
{
{"errorInfo", filterContext}
};
filterContext.Result = new TransferResult(ControllerName, ActionName, routeValue);
}
}
}
Finally, I create the action for handling this error.
public class ErrorController : Controller
{
public string EntityError(ExceptionContext errorInfo)
{
return string.Format("Handle error for {0} ", errorInfo.Exception.Message);
}
}