2013-02-27 52 views
0

努力弄清楚为什么我在这里从BindModel返回null。我有一个扩展ActionFilterAttribute属性...在ActionFilterAttribute中绑定

public class MyCachedAttribute : ActionFilterAttribute 
{ 
    private IModelBinder binder = new DefaultModelBinder(); 
    private Type model; 

    public MyCachedAttribute(Type model) 
    { 
    this.model = model; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
    ModelBindingContext bindingContext = new ModelBindingContext() 
    { 
     ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, model), 
     ModelName = model.Name, 
     ModelState = filterContext.Controller.ViewData.ModelState, 
     ValueProvider = filterContext.Controller.ValueProvider 
    }; 

    object data = binder.BindModel(filterContext.Controller.ControllerContext, bindingContext); 

data在这一点上是null

编辑:我已经回到这个,并认识到ModelState是空的(因此导致null),因为该方法没有正常传入的模型(因此,为什么我在这种情况下绑定,捡起它)。

[MyCached(typeof(FooViewModel))] 
    public ActionResult Foo() 
    { 
    return PartialView(new FooViewModel()); 
    } 

我该如何为我有的类型生成ModelState,并将它传递给活页夹?我试图避免添加模型作为输入参数,因为它会导致问题,但它看起来像我可能不得不排序这些问题,而如果这仍然是一个问题。

谢谢。

EDIT2:我使用的是ActionFilterAttribute这里修改发送,在某些情况下,响应模型,而在其他情况下,它接受一个模型,在高速缓存中进行更新。在这种情况下,我需要绑定它。

+0

什么你想达到多少?它看起来像你想创建一个自定义模型绑定器,应该从'DefaultModelBinder'派生而不是创建'ActionFilterAttribute'。 – 2013-02-27 17:18:04

+0

当使用此属性并发送POST命令时,我稍后使用模型将其存储在缓存中。我已经删除了代码,只是绑定过程。 – Tim 2013-02-27 17:50:18

+0

如果你想做缓存,为什么不使用'OutputCacheAttribute'? – 2013-02-27 17:57:53

回答

2

您应该在modelbinder中进行模型绑定。不是ActionFilter。 ActionFilters用于拦截和修改请求和响应。所以,像这样清理你的ActionResult。

​​

然后创建一个自定义模型联编程序。

public class CachedModelBinder : DefaultModelBinder { 

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
    object data = base.BindModel(controllerContext, bindingContext); 
    // data is not null anymore. You can do your custom stuff now, then return the model 
    return data; 
} 

,并在Application_Start()注册在你global.asax.cs

ModelBinders.Binders.Add(typeof(FooViewModel), new CachedModelBinder()); 
+0

我想修改请求和响应,所以这是一个合适的属性。该属性应该修改“GET”上的模型响应,并接受“POST”上的更新模型。 – Tim 2013-02-28 09:43:49

+0

当你尝试使用object data = binder.BindModel(filterContext.Controller.ControllerContext,bindingContext)时,你做了很多工作并得到null。在MyCachedAttribute中。虽然你可以只是对象data = base.BindModel(controllerContext,bindingContext);在我给你的例子中。现在,再次告诉我你是在正确的地方做的。我已经更新我的示例,只是绑定你想绑定的'对象数据'。 – 2013-02-28 16:02:12