Asp.net mvc ASP.NET MVC将对象从自定义操作筛选器传递到操作
如果我在ASP.NET MVC中的自定义操作筛选器中创建对象Asp.net mvc ASP.NET MVC将对象从自定义操作筛选器传递到操作,asp.net-mvc,filter,custom-action,Asp.net Mvc,Filter,Custom Action,如果我在ASP.NET MVC中的自定义操作筛选器中创建对象 public override void OnActionExecuting(ActionExecutingContext filterContext) { DetachedCriteria criteria = DetachedCriteria.For<Person>(); criteria.Add("stuff"); // Now I need to access 'criteria' fro
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
DetachedCriteria criteria = DetachedCriteria.For<Person>();
criteria.Add("stuff");
// Now I need to access 'criteria' from the Action.....
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
DetachedCriteria=DetachedCriteria.For();
标准。添加(“材料”);
//现在我需要从操作中访问“标准”。。。。。
}
是否有任何方法可以从当前正在执行的操作访问对象。您可以使用
HttpContext
:
filterContext.HttpContext.Items["criteria"] = criteria;
你可以在行动中读到:
[YourActionFilter]
public ActionResult SomeAction()
{
var criteria = HttpContext.Items["criteria"] as DetachedCriteria;
}
在ViewData或viewmodel中设置项(如果将其作为参数传递到操作中)。 这里我设置了ViewModel的属性
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
ViewModelBase viewModel = null;
foreach (object parameter in filterContext.ActionParameters.Values)
{
if (parameter is ViewModelBase)
{
viewModel = (ViewModelBase)parameter;
break;
}
}
if(viewModel !=null)
{
viewModel.SomeProperty = "SomeValue";
}
}
public ActionResult About(ViewModelBase model)
{
string someProperty= model.SomeProperty;
}
以下是我认为您更喜欢的非类型版本:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.ViewData.Add("TestValue", "test");
}
[FilterWhichSetsValue]
public ActionResult About()
{
string test = (string)ViewData["TestValue"];
return View();
}
我建议将其放在路线数据中
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RouteData.Values.Add("test", "TESTING");
base.OnActionExecuting(filterContext);
}
public ActionResult Index()
{
ViewData["Message"] = RouteData.Values["test"];
return View();
}
这是由菲尔·哈克描述的
基本上你就是这么做的:
public class AddActionParameterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
// Create integer parameter.
filterContext.ActionParameters["number"] = 123;
// Create object parameter.
filterContext.ActionParameters["person"] = new Person("John", "Smith");
}
}
唯一的问题是,如果您正在创建对象参数,那么您的类(在本例中为Person)必须有一个默认构造函数,否则您将得到一个异常
以下是如何使用上述过滤器:
[AddActionParameter]
public ActionResult Index(int number, Person person)
{
// Now you can use number and person variables.
return View();
}
一件物品在RouteData中可以保存多久?我只需要在当前执行的操作期间保留对象,或者最多在当前请求期间保留对象,如果路由数据是这样工作的,那么这就是答案,否则HttpContext。Items可能更好。RouteData是与当前执行的路由(操作)相关的数据。将其视为一个容器,表示根据您的路由规则解析和映射的请求url。
RouteData
当然非常适合这样做,正如我今天学到的,感谢您的回答。我面前的这本漂亮的黑白MVC书(第四版)在关于过滤器的整个章节中都没有提到它或做任何类似的事情(或者至少我还没有找到它?)。不管怎样,+1,谢谢你<代码>filterContext.ControllerContext.RoutedData.Values.Add(“键”,值)代码>正在为我工作!:)我正在考虑使用HttpContext.Items[],这是一个可以接受的解决方案,因为它将在请求结束时被清除。我不确定是否有一个地方可以储存只在活动期间存在的东西。谢谢你的建议。不过,我的操作并没有将ViewModelBase作为参数,我不希望引入它只是为了解决我的问题。有关非类型化版本,请参阅编辑的文章。我仍然会使用第一个版本。也许参数名听起来很糟糕。它可以是任何类,而不必是类型化视图的类。这样做非常好,我肯定认为这比公认的答案要好得多。这应该是公认的答案!谢谢为什么这比公认的答案更好?似乎没有理由会出现这种情况,而且额外的[AddActionParameter]显然是其他方法不需要的额外工作。@ChrisBertrand它更干净,通过使用强类型,即-Person
class,避免了控制器中的编译时错误。这种方法的唯一问题是,当你试图做这件事的时候,同时又在写一篇文章。通过将其添加到操作参数中,它将参与模型验证,最终可能出现发布的数据有效,但ModelState.IsValid
仍然为false的奇怪情况,这不是一个很好的解决方案,因为现在你的api可以接受这些参数作为QueryString,这是一个意外的副作用。更糟糕的是,如果您有像swagger这样的文档库,它会显示这些参数是URL的查询参数,而这些参数完全是供内部使用的。