我正在尝试将一些安全性/验证日志记录添加到我正在处理的ASP.NET MVC 3应用程序中.我想做的是使用类似于此的Action过滤器来装饰我的一些Action方法:
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 + "']" );
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的控制器的定义与此类似:
public class MyController : Controller
{
[RegexValidate( ParameterName = "id", Expression = @"^\d+$" )]
public PartialViewResult MyMethod( int id = 0 )
{
<Action Proccessing>
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的"问题"是因为action方法的输入参数定义为a int,如果有人传入非数字值,则在确定选择哪种操作方法的过程中,参数值会更改为0.当然,这发生在我的ActionFilter有机会执行之前,因此我没有机会记录原始的无效值.
我知道这可以通过更改要定义为a的参数来解决string,但这需要我重写大量代码,然后将转换逻辑添加到action方法以将字符串转换为int.
那么,有没有办法在ActionFilter中获取原始值而不是修改后的值,或者在修改值之前执行ActionFilter?
更新:根据@ Darin在下面使用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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
从ActionFilterAttribute派生时,模型绑定器将在您的OnActionExecuting方法之前运行.当模型绑定器运行时,它会崩溃.如果希望方法在模型绑定器之前运行,则应实现IAuthorizationFilter
接口或从AuthorizeAttribute已实现该接口的接口派生.
另一种可能性是为路由添加约束,以便在id不是数字时不调用控制器操作:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { id = @"^\d+$" }
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
751 次 |
| 最近记录: |