首先,它需要创建一些代码来处理我的应用程序中的任何错误,如下面的代码。
public class HandleSomeErrorAttribute : HandleErrorAttribute
{
public string ControllerName { get; set; }
public string ActionName { get; set; }
public override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
if(filterContext.Result != null)
{
var viewResult = filterContext.Result as ViewResult;
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(
new
{
controller = ControllerName,
action = ActionName,
errorInfo = "test"
}
));
}
}
}
如果我将test发送为errorInfo值,一切正常。另一方面,如果我发送一些errorInfo对象作为errorInfo值,动作控制器将不会收到任何errorInfo值。它总是为空。
我知道此行为旨在处理用户提交表单时由Web浏览器发送的表单集合中的任何值。因此,它始终只读取字符串值并将其解析为对象。
那么,是否可以这样做?
谢谢,
答案 0 :(得分:3)
在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);
}
}
答案 1 :(得分:1)
不。重定向将字符串返回给您的浏览器,通知它应该获取的页面(和查询参数)。你可以(而且应该!)在Fiddler看这个。因此,无论你在重定向中放入什么,都必须可以串行化为字符串。