在Stackoverflow 中搜索了一些相关问题后,我才意识到 ASP.NET 中的任何重定向操作都会将HTTP 302 code 发送到浏览器。之后,浏览器会创建新的请求来获取新的 URL(可以在HTTP 302 header 中找到)。
因此,不可能直接将任何复杂对象(不对其进行序列化)发送到浏览器并命令浏览器将其发送回服务器。虽然,这是可能的,但我认为这样做太愚蠢了。因为您可以使用以下代码调用另一个操作,而无需将HTTP 302 发送到浏览器。
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);
}
}
接下来,我创建一些句柄错误来处理一些错误类型并将其转移到另一个动作控制器。
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);
}
}
}
最后,我创建了处理此错误的操作。
public class ErrorController : Controller
{
public string EntityError(ExceptionContext errorInfo)
{
return string.Format("Handle error for {0} ", errorInfo.Exception.Message);
}
}