【问题标题】:Is it possible to send object as route value in RedirectToRouteResult?是否可以在 RedirectToRouteResult 中将对象作为路由值发送?
【发布时间】:2010-03-01 05:06:46
【问题描述】:

首先,它需要创建一些代码来处理我的应用程序中的任何错误,如以下代码。

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"
                 }
            ));
        }
    }
}

如果我将测试作为 errorInfo 值发送,一切正常。另一方面,如果我发送一些 errorInfo 对象作为 errorInfo 值,动作控制器将不会收到任何 errorInfo 值。它始终为空。

我知道此行为旨在处理用户提交表单时 Web 浏览器发送的表单集合中的任何值。因此,它总是只读取字符串值并将其解析为对象。

那么,有可能吗?

谢谢,

【问题讨论】:

    标签: asp.net-mvc-2 asp.net-mvc-routing


    【解决方案1】:

    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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      不。重定向返回一个 string 到您的浏览器,通知它应该获取的页面(和查询参数)。您可以(并且应该!)在 Fiddler 中观看此内容。因此,无论您放入重定向中的任何内容都必须可序列化到字符串或从字符串序列化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-06
        • 2022-11-29
        • 2016-11-13
        • 2020-12-07
        • 1970-01-01
        • 2010-11-22
        • 2016-06-19
        相关资源
        最近更新 更多