Некоторые предыстории моей проблемы:
Похоже, что в Mvc2 есть изменение / ошибка, касающаяся ValidateAntiForgeryTokenAttribute
.
При обновлении с Mvc1 до Mvc2 пользователи с активным сеансом получат следующую ошибку при запросе страницы, используя ValidateAntiForgeryTokenAttribute
:
Невозможно привести объект типа 'Система.Web.UI.Triplet 'для ввода' System.Object [] '.
Проблема задокументирована здесь .
После обновления до 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);
}
}
}
}
}
Стук, который возникает из-за этого, заключается в том, что я должен изменить все свои классы контроллеров для получения из моих новых исправленных подклассов контроллеров.Это кажется довольно навязчивым для кода, который намеревается объявить устаревшим примерно через месяц.
Итак, возвращаясь к моему вопросу, я хотел бы знать, есть ли менее навязчивые средства для исправления существующих классов, чтобы нижестоящие пользователикласса не должны быть изменены, возможно, с помощью отражения?