Некоторые фон в мой вопрос:заплат Asp.net MVC2 AntiForgeryToken исключение
Оказывается, что есть изменение/ошибка в MVC2 относительно ValidateAntiForgeryTokenAttribute
.
При обновлении с Mvc1 до MVC2, пользователи с активной сессии будет получить следующее сообщение об ошибке при запросе страницы с помощью ValidateAntiForgeryTokenAttribute
:
Невозможно привести объект типа «» System.Web.UI.Triplet для ввода «System.Object []».
Проблема документирована here.
После обновления до Mvc2 мы ожидаем, что эта проблема будет серьезно затронута. Я закодировал исправление, полученное из кода в комментариях (ниже описано ниже для потомков). В настоящий момент этот код вызывается путем создания подкласса Controller
и AsyncController
, переопределяя метод Initialize, чтобы исправить проблему. например
public class FixedController:Controller
{
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
this.FixAntiForgeryTokenMvc1ToMvc2(requestContext); //extension
}
}
internal static class ControllerEx
{
public static void FixAntiForgeryTokenMvc1ToMvc2(
this Controller controller,
RequestContext requestContext)
{
var cc = new ControllerContext(requestContext,
controller);
var antiForgeryAttribute = new ValidateAntiForgeryTokenAttribute();
try
{
antiForgeryAttribute.OnAuthorization(new AuthorizationContext(cc));
}
catch (HttpAntiForgeryException forgeryException)
{
var castException = forgeryException.InnerException;
if (castException != null
&& castException is InvalidCastException
&& castException.Message.StartsWith(
"Unable to cast object of type"
+ " 'System.Web.UI.Triplet' to type"
+ " 'System.Object[]'"))
{
var responseTokenCookieNames =
controller
.Response
.Cookies
.Cast<Cookie>()
.Select(c => c.Name)
.Where(n => n.Contains("RequestVerificationToken"));
foreach (var s in responseTokenCookieNames)
{
var cookie = controller.Response.Cookies[s];
if (cookie != null)
{
cookie.Value = "";
}
}
var requestTokenCookieNames =
controller
.Request
.Cookies
.Cast<String>()
.Where(n => n.Contains("RequestVerificationToken"))
.ToList();
foreach (var c in requestTokenCookieNames)
{
controller.Request.Cookies.Remove(c);
}
}
}
}
}
Стук эффект этого является то, что я должен изменить все мои классы контроллеров, чтобы извлечь из моих новых, скорректированных подклассов контроллера. Это кажется довольно навязчивым для кода, который намерен осуждать примерно через месяц.
Итак, подойдя к моему вопросу, я хотел бы знать, существует ли менее навязчивое средство для исправления существующих классов, так что нисходящие пользователи этого класса не должны быть изменены, возможно, используя отражение?
Можете ли вы отключить всех до обновления? –
Мы предпочли бы, если это возможно. – spender
Я знаю, что это не поможет вам в ваших поисках. нам повезло, что мы смогли сообщить всем нашим пользователям очистить их кеш/файлы cookie, прежде чем мы сделали аналогичное обновление около 3 месяцев назад. я обошел круги, пытаясь найти жизнеспособное решение потенциальных проблем. в конце (это была линейка бизнес-приложений с 50 пользователями), мы просто наняли их инструкциями о том, как очистить «мусор». конечно, если ваш сайт является общедоступным, то, возможно, это единственный способ действий. я буду внимательно следить за этим, поскольку исправление в одном месте для какой-то работы и предстоящей работы представляет интерес для меня. –