Я пытаюсь добавить немного журнала безопасности / проверки в приложение ASP.NET MVC 3, над которым я работаю. Я хотел бы украсить некоторые из моих методов действия фильтром действия, подобным следующему:
public class RegexValidateAttribute : ActionFilterAttribute
{
private static readonly ILog logger =
LogManager.GetLogger( typeof( RegexValidateAttribute ).FullName );
public string ParameterName { get; set; }
public string Expression { get; set; }
public override void OnActionExecuting( ActionExecutingContext filterContext )
{
string parameterValue = Convert.ToString(
filterContext.ActionParameters[ ParameterName ] );
if ( parameterValue != null )
{
if ( !Regex.IsMatch( parameterValue, Expression ) )
{
logger.Error( "INPUT_VALIDATION_EXCEPTION [ Parameter "
+ ParameterName + " did not match the regex: '"
+ parameterValue + "' :: '" + Expression + "']" );
}
}
}
}
Мой контроллер определен примерно так:
public class MyController : Controller
{
[RegexValidate( ParameterName = "id", Expression = @"^\d+$" )]
public PartialViewResult MyMethod( int id = 0 )
{
<Action Proccessing>
}
}
Проблема, с которой я столкнулся, заключается в том, что, поскольку входной параметр метода действия определен как int
, если кто-то передает нечисловое значение, значение параметра изменяется на 0 в процессе определения какой метод действий выбрать. Конечно, это происходит ДО того, как мой ActionFilter сможет выполнить, и поэтому у меня нет возможности записать исходное недопустимое значение.
Я знаю, что это можно решить, изменив параметр, который должен быть определен как string
, но это потребует от меня переделки большого количества кода, а затем добавления логики преобразования в метод действия для преобразования из строки в инт.
Итак, есть ли способ получить исходное значение в ActionFilter вместо измененного значения или запустить ActionFilter до изменения значения?
Обновление:
Основываясь на предложении @ Дарина ниже об использовании AuthorizationFilter, я смог достичь своей цели с помощью кода, подобного следующему:
public class RegexValidateAttribute : AuthorizeAttribute
{
private static readonly ILog logger =
LogManager.GetLogger( typeof( RegexValidateAttribute ).FullName );
public string ParameterName { get; set; }
public string Expression { get; set; }
public string ReplacementValue { get; set; }
public override void OnAuthorization( AuthorizationContext filterContext )
{
string parameterValue = Convert.ToString(
filterContext.RouteData.Values[ ParameterName ] );
if ( parameterValue != null )
{
if ( !Regex.IsMatch( parameterValue, Expression ) )
{
logger.Error( "INPUT_VALIDATION_EXCEPTION [ Parameter "
+ ParameterName + " did not match the regex: '"
+ parameterValue + "' :: '" + Expression + "']" );
filterContext.RouteData.Values[ ParameterName ] = ReplacementValue;
}
}
}
}