本文将介绍asp.net-mvc–使用ActionFilter检查URL中的参数的MVC.停止执行的详细情况,。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于
本文将介绍asp.net-mvc – 使用Action Filter检查URL中的参数的MVC.停止执行的详细情况,。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于ASP.NET MVC 5中的Actionfilter注入、ASP.NET MVC 5使用Filter过滤Action参数防止sql注入、ASP.NET MVC- ActionFilter的使用、ASP.NET MVC中的ActionFilter是如何执行的?的知识。
本文目录一览:- asp.net-mvc – 使用Action Filter检查URL中的参数的MVC.停止执行
- ASP.NET MVC 5中的Actionfilter注入
- ASP.NET MVC 5使用Filter过滤Action参数防止sql注入
- ASP.NET MVC- ActionFilter的使用
- ASP.NET MVC中的ActionFilter是如何执行的?
asp.net-mvc – 使用Action Filter检查URL中的参数的MVC.停止执行
当url没有instID时,我想重定向到“Instelling”动作
在这个控制器中,每个方法都需要instID.
[requiredParameter(parameterName="instID",controllerToSend="Instelling")] public ActionResult Index(int? instID) { //if (!instID.HasValue) { // return RedirectToAction("Index","Instelling"); //} var facts = _db.Instellingens.First(q => q.Inst_ID == instID).FacturatieGegevens; return View(facts); }
所以这是在控制器中.
actionfilter:
namespace MVC2_NASTEST.Controllers { public class requiredParameterattribute : ActionFilterattribute { public string parameterName { get; set; } public string actionToSend { get; set; } public string controllerToSend { get; set; } public override void OnActionExecuting(ActionExecutingContext filterContext) { if (parameterName != string.Empty) { if (filterContext.ActionParameters.ContainsKey(parameterName) && filterContext.ActionParameters[parameterName] != null) { string s = "test"; //all is good } else { //de parameter ontbreekt. kijk of de controller en de action geset zijn. if (actionToSend == string.Empty) actionToSend = "Index"; if (controllerToSend == string.Empty) { controllerToSend = filterContext.Controller.ToString(); controllerToSend = controllerToSend.Substring(controllerToSend.LastIndexOf(".") + 1); controllerToSend = controllerToSend.Substring(0,controllerToSend.LastIndexOf("Controller")); } UrlHelper helper = new UrlHelper(filterContext.RequestContext); string url = helper.Action(actionToSend,controllerToSend); HttpContext.Current.Response.Redirect(url); //filterContext.HttpContext.Response.Redirect(url,true); } } base.OnActionExecuting(filterContext); } public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); } } }
事情是:它确实有效,然而,动作本身首先被执行,然后重定向发生.这不是我想要的.
也许我不应该使用actionfilters但只是添加路线?
在这种情况下,如果缺少instID,我将如何将路由重定向到另一个控制器?
解决方法
像这样的东西(伪代码):
public class requiredParameterattribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { // read instID from QueryString // if instId is null,return false,otherwise true } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { filterContext.result = new RedirectToRouteResult( new { controller = "MyController",action = "MyAction" } ) }
}
ASP.NET MVC 5中的Actionfilter注入
public class IsAdmin : ActionFilterattribute,IAuthenticationFilter { private string _roleName; IBusinessIdentity _identity; public IsAdmin(string roleName,IBusinessIdentity identity) { this._roleName = roleName; this._identity = identity; } public void OnAuthentication(AuthenticationContext filterContext) { } public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) { if (!_identity.Roles.Contains(_roleName)) filterContext.Result = new HttpUnauthorizedResult(); } }
我正在使用Ninject.这是我的控制器.我正在尝试将注入的服务放入我的ActionFilter中,以便不依赖于HttpContext而是依赖于我的IBusinessIdentity.
IBusinessIdentity注入了HttpContext.User.Identity`.它会执行一些数据库调用并获取userRoles.
public class HomeController : Controller { readonly IBusinessIdentity _identity; public HomeController(IBusinessIdentity identity) { this._identity= identity; } [IsAdmin("Admin",_identity)] public ActionResult Index() { return View(); } }
这不起作用,当我尝试在编译时将“identity”放在actionfilter构造函数中时,我遇到编译器错误.
An object reference is required for the non-static field,method,or property
我需要这个,因为我打算用身份测试各种权限.
我想在控制器实例化之后要做一些反思.我对如何做到这一点有一个非常模糊的想法.
我正在使用ASP.NET MVC 5,我没有kernel.bindfilter.我不能使用旧版本.
我很清楚这个黑客.
Action filter constructor being called repeatedly for single controller
https://github.com/ninject/Ninject.Web.Mvc/wiki/Conditional-bindings-for-filters
如何使用Ninject for MVC 5实现相同的效果.
编辑:大规模失败
我忘了包括:
using Ninject.Web.Mvc.FilterBindingSyntax;
现在一切都按照上面的链接解释了.
现在我需要弄清楚如何在过滤器构造函数中注入“roleName”字符串.虽然我认为只是为每个角色构建一个过滤器.我稍后会发布完整的代码.
解决方法
DI友好属性永远不应该定义任何行为.您需要将行为分离到一个单独的过滤器中,该过滤器可以在应用程序启动时注入其依赖项.这可以通过将动作过滤器属性分为两部分来完成.
>一个不包含用于标记控制器和操作方法的行为的属性.
> DI友好类,它实现IActionFilter和/或IAuthenticationFilter,其中包含扫描实现所需的行为,以检查属性.
不要让微软的ActionFilterattribute营销欺骗你.这种方法完全不符合DI.
ASP.NET MVC 5使用Filter过滤Action参数防止sql注入
在开发程序的过程中,稍微不注意就会隐含有sql注入的危险。今天我就来说下,ASP.NET mvc 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁。不用每下地方对参数的值都进行检查,看是用户输入的内容是否有危险的sql。如果每个地方都要加有几个缺点:
1、工作量大
2、容易遗漏
3、不容易维护
下面我通过写一个过滤防止sql的特性类,对Action执行前对Action的参数进行处理,如果有其值有sql语句,就会这些非法字符替换为空字符串。
一、sql注入的例子:
上面的输入有两个输入框,用户可以输入任何的值,包括有sql注入的值。
后台代码:
AdminController.cs

public class AdminController : Controller
{
public ActionResult Index(string name = "", string loginName = "", int page = 1)
{
ViewBag.Name = name;
ViewBag.LoginName = loginName;
var r = DAdmin.GetList(name, loginName, page, 2);
return View(r);
}
}
}

DAdmin.cs:

public class DAdmin
{
public static PageDataView<MSys_Admin> GetList(string name, string loginName, int page,int pageSize=10)
{
PageCriteria criteria = new PageCriteria();
criteria.Condition = "1=1";
if (!string.IsNullOrEmpty(name))
criteria.Condition += string.Format(" and Name like ''%{0}%''", name);
if (!string.IsNullOrEmpty(loginName))
criteria.Condition += string.Format(" and LoginName like ''%{0}%''", loginName);
criteria.CurrentPage = page;
criteria.Fields = "*";
criteria.PageSize = pageSize;
criteria.TableName = "Sys_Admin a";
criteria.PrimaryKey = "UID";
var r = Common.GetPageData<MSys_Admin>(criteria);
return r;
}
}

上面对用户输入的name和loginName两个参数没有判断是否有sql注入的非法字符,就直接拼接到sql语句,到数据库中执行,这样是非常危险的。
1、比如用户在name输入这样的内容:
%''--%
这样拼接出来的sql语句就成了
SELECT * FROM Sys_Admin WHERE Name like ''%''--%''
这样“--”是sql的注释标记后面再拼接的sql语句都当成注释了,这样有效的就成了这样的sql语句:
SELECT * FROM Sys_Admin WHERE Name like ''%''
这表示显示全部的记录。如果是登录的sql就会跳过用户名、密码的验证。
2、如果用户name输入内容带有insert或delete或者drop,比如:
namer人值为:%'';DELETE FROM Sys_Admin--%
拼接成的sql成了:
SELECT * FROM Sys_Admin WHERE Name like ''%'';DELETE FROM Sys_Admin--%''
这样一执行就把Sys_Admin表的记录全部删除了。
总结:上面可以看到这种sql注入是多么的危险。
二、解决MVC sql注入方案
1、定义一个防止sql注入的字符串辅助类

{
public static string FilterSql(string s)
{
if (string.IsNullOrEmpty(s)) return string.Empty;
s = s.Trim().ToLower();
s = ClearScript(s);
s = s.Replace("=", "");
s = s.Replace("''", "");
s = s.Replace(";", "");
s = s.Replace(" or ", "");
s = s.Replace("select", "");
s = s.Replace("update", "");
s = s.Replace("insert", "");
s = s.Replace("delete", "");
s = s.Replace("declare", "");
s = s.Replace("exec", "");
s = s.Replace("drop", "");
s = s.Replace("create", "");
s = s.Replace("%", "");
s = s.Replace("--", "");
return s;
}
}

这个类对上面sql相关的字符串都替换掉。
2、定义一个用来检查并处理Action参数的特性类

public class AntiSqlInjectAttribute:FilterAttribute,IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var actionParameters = filterContext.ActionDescriptor.GetParameters();
foreach (var p in actionParameters)
{
if (p.ParameterType == typeof(string))
{
if (filterContext.ActionParameters[p.ParameterName] != null)
{
filterContext.ActionParameters[p.ParameterName] = StringHelper.FilterSql(filterContext.ActionParameters[p.ParameterName].ToString());
}
}
}
}
}

说明:这个特性类是继承了类FilterAttribute和实现了接口IActionFilter,这里在方法OnActionExecuting处理Action的参数,OnActionExecuting是在Action执行之前运行的方法,而OnActionExecuted是在Action执行之后运行的方法。
p.ParameterType == typeof(string)
因为sql注入只有参数类型为字符串的时候才有可能所以这里只对Action参数为字符串的参数进行处理。
filterContext.ActionParameters[p.ParameterName] =
StringHelper.FilterSql(filterContext.ActionParameters[p.ParameterName].ToString());
是用过滤之后的安全的Action参数值替换原来的原始值。
3、防止sql注入特性类的在MVC的Controller中的使用

public class AdminController : Controller
{
[AntiSqlInject]
public ActionResult Index(string name = "", string loginName = "", int page = 1)
{
ViewBag.Name = name;
ViewBag.LoginName = loginName;
var r = DAdmin.GetList(name, loginName, page, 2);
return View(r);
}
}

需要对Action的参数进行sql检查,只用在前面加上,上面定义的特性类AntiSqlInject。这个特性类可以用在任何的需要防止sql注入的Action上,根本不用对手动的去过滤程序中获取到的所有参数,安全、方便简洁
ASP.NET MVC- ActionFilter的使用
先理解一下什么是:ActionFilter
1:ActionFilter是穿插在Action执行过程,在Action执行前后提供扩展的功能。ActionFilter用途非常的广,用在页面压缩、缓存、错误处理,登陆验证。
2:ActionFilter的实现需要继承自ActionFilterAttribute抽象类,并且覆盖需要使用的方法。
3:ActionFilterAttribute类中有四个可重的方法,分别是OnActionExecuting,OnActionExecuted,OnResultExecuting,OnResultExecuted。
4:这四个方法的执行顺序是 OnActionExecuting->OnActionExecuted->OnResultExecuting->OnResultExecuted
实现步骤:一般都是建一个文件夹,专门放一个filter类,这里我就建一个Filter的文件夹,里边放一个TestFilter类
类中代码如下:
namespace FirstMvcDemo.Filter
{
public class TestFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//如果要使用ViewBag或者ViewData等控制器中的内容,则使用方法中的参数filterContext.Controller
filterContext.Controller.ViewBag.TestData = "内容1";
filterContext.Controller.ViewData["TestData"] = "内容2";
HttpContext.Current.Response.Write("正要准备执行Action的时候但还未执行时执行");
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
HttpContext.Current.Response.Write("Action执行时但还未返回结果时执行");
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
HttpContext.Current.Response.Write("OnResultExecuting也和OnActionExecuted一样,但前者是在后者执行完后才执行");
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
HttpContext.Current.Response.Write("Action执行完后将要返回ActionResult的时候执行");
}
}
}
然后在Controller里,加上[TestFilter]标记,则在执行这个Action的时候会先进入FilterDemo类里,执行里面的方法
[TestFilter]
public ActionResult Home()
{
return View();
}
当然,filter类放的位置如果需要引用别忘了引用就行!
ASP.NET MVC中的ActionFilter是如何执行的?
在ASP.NET MVC中的四大筛选器(Filter),ActionFilter直接应用在某个Action方法上,它在目标Action方法执行前后对调用进行拦截以执行一些额外的操作。这是一种典型的AOP式的设计,如果我们需要在执行某个Action方法的前后执行一些操作,可以通过定义ActionFilter来实现。本篇文章主要讲述多一个应用到相同Action方法上的ActionFilter的执行机制。[本文已经同步到《How ASP.NET MVC Works?》中]
目录
一、ActionFilter
二、ActionFilter的执行机制
三、ActionFilter对ActionResult的设置
四、ActionFilter中的异常处理
一、ActionFilter
ActionFilter允许我们在目标Action方法执行前后对调用进行拦截以执行一些额外的操作,所有的ActionFilter实现了具有如下定义的接口IActionFilter。
1: public interface IActionFilter
2: {
3: void OnActionExecuting(ActionExecutingContext filterContext);
4: void OnActionExecuted(ActionExecutedContext filterContext);
5: }
6:
7: public class ActionExecutingContext : ControllerContext
8: {
9: public ActionExecutingContext();
10: public ActionExecutingContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> actionParameters);
11:
12: public virtual ActionDescriptor ActionDescriptor { get; set; }
13: public virtual IDictionary<string, object> ActionParameters { get; set; }
14: public ActionResult Result { get; set; }
15: }
16:
17: public class ActionExecutedContext : ControllerContext
18: {
19: public ActionExecutedContext();
20: public ActionExecutedContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, bool canceled, Exception exception);
21:
22: public virtual ActionDescriptor ActionDescriptor { get; set; }
23: public virtual bool Canceled { get; set; }
24: public virtual Exception Exception { get; set; }
25: public bool ExceptionHandled { get; set; }
26: public ActionResult Result { get; set; }
27: }
如上面的代码片断所示,IActionFilter接口中定义了两个方法OnActionExecuting和OnActionExecuted,这两个方法分别在目标Action方法执行前后被调用,它们的参数类型分别为ActionExecutingContext和ActionExecutedContext。这两个上下文了类型均是ControllerContext的子类。
我们可以从ActionExecutingContext对象中获取到用于描述当前Action的ActionDescriptor,以及参数列表。ActionFilter可以在OnActionExecuting方法中对ActionExecutingContext对象的Result属性进行赋值来直接响应当前的请求。一旦ActionExecutingContext的Result属性被成功赋值,将会终止后续ActionFilter和最终目标方法的执行。
ActionExecutedContext具有额外的三个属性,Exception表示执行Action方法过程中抛出的异常,而ExceptionHandled是一个表示是否对异常已经做出处理的标记。Canceled属性表示没有完成整个ActionFilter链和目标Action方法的执行而中途被终止。
二、ActionFilter的执行机制
在这之后真正的目标Action方法被执行,ActionInvoker随后执行后续的筛选操作。具体来说,它根据当前ControllerContext、ActionDescriptro以及Action方法执行过程中抛出的异常创建一个ActionExecutedContext对象。该ActionExecutedContext的Cancel属性为False,如果Action方法返回一个ActionResult对象,该对象将会作为该ActionExecutedContext的Result属性。
接下来按照相反的次序依次调用ActionFilter对象的OnActionExecuted方法,执行过程中的ActionFilter可以修改ActionExecutedContext的Result属性。当整个ActionFilter链执行结束之后,ActionExecutedContext的Result属性返回的ActionResult将会作为对当前请求的响应。右图基本上反映了连同目标Action在内的整个ActionFilter链的执行过程。
三、ActionFilter对ActionResult的设置
上面我们已经提到过,在ActionFilter链进行OnActionExecuting方法调用的过程中,一旦某个ActionFilter为ActionExecutingContext的Result属性设置了一个ActionResult对象,后续ActionFilter和目标Action将不会被执行。实际上此时ActionInvoker此时会创建一个ActionExecutedContext对象,设置的ActionResult直接作为其Result属性,而Cancel属性被设置为True。我们现在考虑的问题是:之前的ActionFilter的OnActionExecuted是否还被执行呢?
为了弄清楚这个问题,我们来创建一个测试程序。在通过Visual Studio的ASP.NET MVC项目模板创建的空Web应用中我们定义了如下三个ActionFilter(FooAttribute、BarAttribute和BazAttribute),它们都继承自我们自定义的FilterBaseAttribute。在FilterBaseAttribute中实现的OnActionExecuting和OnActionExecuted方法中,我们将ActionFilter自身的类型和执行方法名写入当前HttpResponse并最终呈现在浏览器中。BarAttribute重写了OnActionExecuting方法,在调用基类同名方法之后为ActionExecutingContext的Result设置了一个EmptyResult对象。
1: public abstract class FilterBaseAttribute : FilterAttribute, IActionFilter
2: {
3: public virtual void OnActionExecuted(ActionExecutedContext filterContext)
4: {
5: filterContext.HttpContext.Response.Write(string.Format("{0}.OnActionExecuted()<br/>", this.GetType().Name));
6: }
7:
8: public virtual void OnActionExecuting(ActionExecutingContext filterContext)
9: {
10: filterContext.HttpContext.Response.Write(string.Format("{0}.OnActionExecuting()<br/>", this.GetType().Name));
11: }
12: }
13:
14: public class FooAttribute : FilterBaseAttribute
15: {}
16: public class BarAttribute : FilterBaseAttribute
17: {
18: public override void OnActionExecuting(ActionExecutingContext filterContext)
19: {
20: base.OnActionExecuting(filterContext);
21: filterContext.Result = new EmptyResult();
22: }
23: }
24: public class BazAttribute : FilterBaseAttribute
25: {}