Можно ли отправить объект как значение маршрута в RedirectToRouteResult? - PullRequest
1 голос
/ 01 марта 2010

Прежде всего, необходимо создать несколько кодов, которые обрабатывают любую ошибку в моем приложении, например, следующий код.

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. Это всегда ноль.

Я знаю, что это поведение предназначено для обработки любых значений в коллекции форм, отправляемой веб-браузером, когда пользователь отправляет форму. Таким образом, он всегда читает только строковое значение и анализирует его для объекта.

Итак, возможно ли это сделать?

Спасибо

Ответы [ 2 ]

3 голосов
/ 04 марта 2010

После поиска соответствующего вопроса в Stackoverflow я просто понимаю, что любое действие перенаправления в ASP.NET отправляет код HTTP 302 в браузер. После этого браузер создаст новый запрос на получение нового URL (который можно найти в HTTP 302 заголовок ).

Следовательно, невозможно напрямую отправлять какие-либо сложные объекты (без их сериализации) в браузер и приказывать браузеру отправлять их обратно на сервер. Хотя, это возможно, но я думаю, что это так глупо. Поскольку вы можете использовать следующий код для вызова другого действия без отправки 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 голос
/ 03 марта 2010

Неа. Редирект возвращает строку в ваш браузер, информируя его о странице (и параметрах запроса), которую он должен получить. Вы можете (и должны!) Смотреть это в Fiddler. Поэтому все, что вы помещаете в редирект, должно быть сериализуемо в / из строки.

...